Add update FCM token grpc
Add update FCM API to the check in grpc definition and to
DeviceCheckInClient. The API will be used in future CLs
Bug: 367447984
Flag: EXEMPT low-risk refactor
Test: atest DeviceCheckInClientImplTest
Change-Id: If35daf24e929e5e06f252a4fa2b8475e2bf10547
diff --git a/DeviceLockController/proto/checkin_service.proto b/DeviceLockController/proto/checkin_service.proto
index 377e29c..f1f1a3a 100644
--- a/DeviceLockController/proto/checkin_service.proto
+++ b/DeviceLockController/proto/checkin_service.proto
@@ -46,6 +46,10 @@
// provisioning.
rpc ReportDeviceProvisionState(ReportDeviceProvisionStateRequest)
returns (ReportDeviceProvisionStateResponse) {}
+
+ // Updates FCM token for a device.
+ rpc UpdateFcmToken(UpdateFcmTokenRequest)
+ returns (UpdateFcmTokenResponse) {}
}
// Request to retrieve the check-in status of the device.
@@ -252,3 +256,33 @@
// CLIENT_PROVISION_STATE_DISMISSIBLE_UI
optional uint32 days_left_until_reset = 2;
}
+
+// Request to update FCM token for a device.
+message UpdateFcmTokenRequest {
+ // The device identifiers associated with the device provided by the Device
+ // Lock Android client.
+ repeated ClientDeviceIdentifier client_device_identifiers = 1;
+
+ // The Firebase Cloud Messaging (FCM) registration token associated with the
+ // device provided by the Device Lock Android client. The token is only used
+ // for GMS devices.
+ optional string fcm_registration_token = 2;
+}
+
+// Response to a request to update FCM token for a device.
+message UpdateFcmTokenResponse {
+ // The result of the update.
+ optional UpdateFcmTokenResult result = 1;
+}
+
+// The results of FCM token update.
+enum UpdateFcmTokenResult {
+ // Unspecified result.
+ UPDATE_FCM_TOKEN_RESULT_UNSPECIFIED = 0;
+
+ // Update to FCM token was successful.
+ UPDATE_FCM_TOKEN_RESULT_SUCCESS = 1;
+
+ // Update to FCM token was unsuccessful.
+ UPDATE_FCM_TOKEN_RESULT_FAILURE = 2;
+}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceCheckInClientDebug.java b/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceCheckInClientDebug.java
index 2c2bc6b..1c67471 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceCheckInClientDebug.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceCheckInClientDebug.java
@@ -25,6 +25,7 @@
import android.util.ArraySet;
import androidx.annotation.Keep;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.devicelockcontroller.common.DeviceId;
@@ -38,6 +39,7 @@
import com.android.devicelockcontroller.provision.grpc.PauseDeviceProvisioningGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.ProvisioningConfiguration;
import com.android.devicelockcontroller.provision.grpc.ReportDeviceProvisionStateGrpcResponse;
+import com.android.devicelockcontroller.provision.grpc.UpdateFcmTokenGrpcResponse;
import com.android.devicelockcontroller.util.LogUtil;
import com.android.devicelockcontroller.util.ThreadAsserts;
@@ -247,4 +249,16 @@
}
};
}
+
+ @Override
+ public UpdateFcmTokenGrpcResponse updateFcmToken(ArraySet<DeviceId> deviceIds,
+ @NonNull String fcmRegistrationToken) {
+ ThreadAsserts.assertWorkerThread("updateFcmToken");
+ return new UpdateFcmTokenGrpcResponse() {
+ @Override
+ public int getFcmTokenResult() {
+ return FcmTokenResult.RESULT_SUCCESS;
+ }
+ };
+ }
}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/DeviceCheckInClient.java b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/DeviceCheckInClient.java
index ab8ff20..e58f4e0 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/DeviceCheckInClient.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/DeviceCheckInClient.java
@@ -23,6 +23,7 @@
import android.os.UserHandle;
import android.util.ArraySet;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@@ -188,6 +189,19 @@
boolean isSuccessful, @ProvisionFailureReason int failureReason);
/**
+ * Update FCM registration token on device lock backend server for the given device identifiers.
+ *
+ * @param deviceIds A set of all device unique identifiers, this could include IMEIs,
+ * MEIDs, etc.
+ * @param fcmRegistrationToken The fcm registration token
+ * @return A class that encapsulate the response from the backend server.
+ */
+ @WorkerThread
+ public abstract UpdateFcmTokenGrpcResponse updateFcmToken(
+ ArraySet<DeviceId> deviceIds,
+ @NonNull String fcmRegistrationToken);
+
+ /**
* Called when this device check in client is no longer in use and should clean up its
* resources.
*/
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/UpdateFcmTokenGrpcResponse.java b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/UpdateFcmTokenGrpcResponse.java
new file mode 100644
index 0000000..a713fc8
--- /dev/null
+++ b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/UpdateFcmTokenGrpcResponse.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.devicelockcontroller.provision.grpc;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+
+import io.grpc.Status;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An abstract class that is used to encapsulate the response for updating the FCM registration
+ * token.
+ */
+public abstract class UpdateFcmTokenGrpcResponse extends GrpcResponse {
+ /** Definitions for FCM token results. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ value = {
+ FcmTokenResult.RESULT_UNSPECIFIED,
+ FcmTokenResult.RESULT_SUCCESS,
+ FcmTokenResult.RESULT_FAILURE
+ }
+ )
+ public @interface FcmTokenResult {
+ /** Result unspecified */
+ int RESULT_UNSPECIFIED = 0;
+ /** FCM registration token successfully updated */
+ int RESULT_SUCCESS = 1;
+ /** FCM registration token falied to update */
+ int RESULT_FAILURE = 2;
+ }
+
+ public UpdateFcmTokenGrpcResponse() {
+ mStatus = null;
+ }
+
+ public UpdateFcmTokenGrpcResponse(@NonNull Status status) {
+ super(status);
+ }
+
+ /**
+ * Get result of updating FCM registration token.
+ *
+ * @return one of {@link FcmTokenResult}
+ */
+ @FcmTokenResult
+ public abstract int getFcmTokenResult();
+}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckInClientImpl.java b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckInClientImpl.java
index eedf8b3..767c0f9 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckInClientImpl.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckInClientImpl.java
@@ -54,11 +54,13 @@
import com.android.devicelockcontroller.proto.PauseDeviceProvisioningReason;
import com.android.devicelockcontroller.proto.PauseDeviceProvisioningRequest;
import com.android.devicelockcontroller.proto.ReportDeviceProvisionStateRequest;
+import com.android.devicelockcontroller.proto.UpdateFcmTokenRequest;
import com.android.devicelockcontroller.provision.grpc.DeviceCheckInClient;
import com.android.devicelockcontroller.provision.grpc.GetDeviceCheckInStatusGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.IsDeviceInApprovedCountryGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.PauseDeviceProvisioningGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.ReportDeviceProvisionStateGrpcResponse;
+import com.android.devicelockcontroller.provision.grpc.UpdateFcmTokenGrpcResponse;
import com.android.devicelockcontroller.util.LogUtil;
import com.android.devicelockcontroller.util.ThreadAsserts;
@@ -201,7 +203,6 @@
@Nullable String fcmRegistrationToken,
@NonNull DeviceLockCheckinServiceBlockingStub stub) {
try {
- // TODO(339313833): Make a separate grpc call for passing in the token
return new GetDeviceCheckInStatusGrpcResponseWrapper(
stub.withDeadlineAfter(GRPC_DEADLINE_MS, TimeUnit.MILLISECONDS)
.getDeviceCheckinStatus(createGetDeviceCheckinStatusRequest(
@@ -316,6 +317,40 @@
}
@Override
+ public UpdateFcmTokenGrpcResponse updateFcmToken(ArraySet<DeviceId> deviceIds,
+ @NonNull String fcmRegistrationToken) {
+ ThreadAsserts.assertWorkerThread("getDeviceCheckInStatus");
+ UpdateFcmTokenGrpcResponse response =
+ updateFcmToken(deviceIds, fcmRegistrationToken, mDefaultBlockingStub);
+ if (response.hasRecoverableError()) {
+ DeviceLockCheckinServiceBlockingStub stub;
+ synchronized (this) {
+ if (mNonVpnBlockingStub == null) {
+ return response;
+ }
+ stub = mNonVpnBlockingStub;
+ }
+ LogUtil.d(TAG, "Non-VPN network fallback detected. Re-attempt fcm token update.");
+ return updateFcmToken(deviceIds, fcmRegistrationToken, stub);
+ }
+ return response;
+ }
+
+ private UpdateFcmTokenGrpcResponse updateFcmToken(
+ ArraySet<DeviceId> deviceIds,
+ @NonNull String fcmRegistrationToken,
+ @NonNull DeviceLockCheckinServiceBlockingStub stub) {
+ try {
+ return new UpdateFcmTokenGrpcResponseWrapper(
+ stub.withDeadlineAfter(GRPC_DEADLINE_MS, TimeUnit.MILLISECONDS)
+ .updateFcmToken(createUpdateFcmTokenRequest(
+ deviceIds, fcmRegistrationToken)));
+ } catch (StatusRuntimeException e) {
+ return new UpdateFcmTokenGrpcResponseWrapper(e.getStatus());
+ }
+ }
+
+ @Override
public void cleanUp() {
super.cleanUp();
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
@@ -356,24 +391,10 @@
@Nullable String fcmRegistrationToken) {
GetDeviceCheckinStatusRequest.Builder builder = GetDeviceCheckinStatusRequest.newBuilder();
for (DeviceId deviceId : deviceIds) {
- DeviceIdentifierType type;
- switch (deviceId.getType()) {
- case DeviceIdType.DEVICE_ID_TYPE_UNSPECIFIED:
- type = DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_UNSPECIFIED;
- break;
- case DeviceIdType.DEVICE_ID_TYPE_IMEI:
- type = DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_IMEI;
- break;
- case DeviceIdType.DEVICE_ID_TYPE_MEID:
- type = DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_MEID;
- break;
- default:
- throw new IllegalStateException(
- "Unexpected DeviceId type: " + deviceId.getType());
- }
builder.addClientDeviceIdentifiers(
ClientDeviceIdentifier.newBuilder()
- .setDeviceIdentifierType(type)
+ .setDeviceIdentifierType(
+ convertToProtoDeviceIdType(deviceId.getType()))
.setDeviceIdentifier(deviceId.getId()));
}
builder.setCarrierMccmnc(carrierInfo);
@@ -386,6 +407,19 @@
return builder.build();
}
+ private static DeviceIdentifierType convertToProtoDeviceIdType(@DeviceIdType int deviceIdType) {
+ return switch (deviceIdType) {
+ case DeviceIdType.DEVICE_ID_TYPE_UNSPECIFIED ->
+ DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_UNSPECIFIED;
+ case DeviceIdType.DEVICE_ID_TYPE_IMEI ->
+ DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_IMEI;
+ case DeviceIdType.DEVICE_ID_TYPE_MEID ->
+ DeviceIdentifierType.DEVICE_IDENTIFIER_TYPE_MEID;
+ default -> throw new IllegalStateException(
+ "Unexpected DeviceId type: " + deviceIdType);
+ };
+ }
+
private static IsDeviceInApprovedCountryRequest createIsDeviceInApprovedCountryRequest(
String carrierInfo, String registeredId) {
return IsDeviceInApprovedCountryRequest.newBuilder()
@@ -469,4 +503,18 @@
}
return builder.build();
}
+
+ private static UpdateFcmTokenRequest createUpdateFcmTokenRequest(ArraySet<DeviceId> deviceIds,
+ @NonNull String fcmRegistrationToken) {
+ UpdateFcmTokenRequest.Builder builder = UpdateFcmTokenRequest.newBuilder();
+ for (DeviceId deviceId : deviceIds) {
+ builder.addClientDeviceIdentifiers(
+ ClientDeviceIdentifier.newBuilder()
+ .setDeviceIdentifierType(
+ convertToProtoDeviceIdType(deviceId.getType()))
+ .setDeviceIdentifier(deviceId.getId()));
+ }
+ builder.setFcmRegistrationToken(fcmRegistrationToken);
+ return builder.build();
+ }
}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/UpdateFcmTokenGrpcResponseWrapper.java b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/UpdateFcmTokenGrpcResponseWrapper.java
new file mode 100644
index 0000000..6f8e90e
--- /dev/null
+++ b/DeviceLockController/src/com/android/devicelockcontroller/provision/grpc/impl/UpdateFcmTokenGrpcResponseWrapper.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.devicelockcontroller.provision.grpc.impl;
+
+import com.android.devicelockcontroller.proto.UpdateFcmTokenResponse;
+import com.android.devicelockcontroller.provision.grpc.UpdateFcmTokenGrpcResponse;
+
+import io.grpc.Status;
+
+/**
+ * A wrapper class for {@link UpdateFcmTokenGrpcResponse}.
+ */
+public final class UpdateFcmTokenGrpcResponseWrapper extends UpdateFcmTokenGrpcResponse {
+ private UpdateFcmTokenResponse mResponse;
+
+ public UpdateFcmTokenGrpcResponseWrapper(Status status) {
+ super(status);
+ }
+
+ public UpdateFcmTokenGrpcResponseWrapper(UpdateFcmTokenResponse response) {
+ super();
+ mResponse = response;
+ }
+
+ @Override
+ @FcmTokenResult
+ public int getFcmTokenResult() {
+ if (mResponse == null) {
+ return FcmTokenResult.RESULT_UNSPECIFIED;
+ }
+ return switch (mResponse.getResult()) {
+ case UPDATE_FCM_TOKEN_RESULT_UNSPECIFIED -> FcmTokenResult.RESULT_UNSPECIFIED;
+ case UPDATE_FCM_TOKEN_RESULT_SUCCESS -> FcmTokenResult.RESULT_SUCCESS;
+ case UPDATE_FCM_TOKEN_RESULT_FAILURE -> FcmTokenResult.RESULT_FAILURE;
+ default -> throw new IllegalStateException(
+ "Unexpected update FCM result: " + mResponse.getResult());
+ };
+ }
+}
diff --git a/DeviceLockController/tests/robolectric/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckinClientImplTest.java b/DeviceLockController/tests/robolectric/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckinClientImplTest.java
index 6ed66db..d3d3c01 100644
--- a/DeviceLockController/tests/robolectric/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckinClientImplTest.java
+++ b/DeviceLockController/tests/robolectric/src/com/android/devicelockcontroller/provision/grpc/impl/DeviceCheckinClientImplTest.java
@@ -41,11 +41,14 @@
import com.android.devicelockcontroller.proto.PauseDeviceProvisioningResponse;
import com.android.devicelockcontroller.proto.ReportDeviceProvisionStateRequest;
import com.android.devicelockcontroller.proto.ReportDeviceProvisionStateResponse;
+import com.android.devicelockcontroller.proto.UpdateFcmTokenRequest;
+import com.android.devicelockcontroller.proto.UpdateFcmTokenResponse;
import com.android.devicelockcontroller.provision.grpc.DeviceCheckInClient;
import com.android.devicelockcontroller.provision.grpc.GetDeviceCheckInStatusGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.IsDeviceInApprovedCountryGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.PauseDeviceProvisioningGrpcResponse;
import com.android.devicelockcontroller.provision.grpc.ReportDeviceProvisionStateGrpcResponse;
+import com.android.devicelockcontroller.provision.grpc.UpdateFcmTokenGrpcResponse;
import io.grpc.CallOptions;
import io.grpc.Channel;
@@ -710,6 +713,127 @@
}
@Test
+ public void updateFcmToken_succeeds() throws Exception {
+ // GIVEN the service succeeds through the default network
+ mGrpcCleanup.register(InProcessServerBuilder
+ .forName(mDefaultNetworkServerName)
+ .directExecutor()
+ .addService(makeSucceedingService())
+ .build()
+ .start());
+
+ // WHEN we update FCM token
+ AtomicReference<UpdateFcmTokenGrpcResponse> response = new AtomicReference<>();
+ mBgExecutor.submit(() -> response.set(
+ mDeviceCheckInClientImpl.updateFcmToken(
+ new ArraySet<>(), TEST_FCM_TOKEN))).get();
+
+ // THEN the response is successful
+ assertThat(response.get().isSuccessful()).isTrue();
+ assertThat(mReceivedFcmToken).isEqualTo(TEST_FCM_TOKEN);
+ }
+
+ @Test
+ public void updateFcmToken_noDefaultConnectivity_fallsBackToNonVpn()
+ throws Exception {
+ // GIVEN a non-VPN network is connected with connectivity
+ Set<ConnectivityManager.NetworkCallback> networkCallbacks =
+ mShadowConnectivityManager.getNetworkCallbacks();
+ for (ConnectivityManager.NetworkCallback callback : networkCallbacks) {
+ NetworkCapabilities capabilities =
+ Shadows.shadowOf(new NetworkCapabilities()).addCapability(
+ NET_CAPABILITY_VALIDATED);
+ callback.onCapabilitiesChanged(mNonVpnNetwork, capabilities);
+ }
+
+ // GIVEN the service fails through the default network and succeeds through the non-VPN
+ // network
+ mGrpcCleanup.register(InProcessServerBuilder
+ .forName(mDefaultNetworkServerName)
+ .directExecutor()
+ .addService(makeFailingService())
+ .build()
+ .start());
+ mGrpcCleanup.register(InProcessServerBuilder
+ .forName(mNonVpnServerName)
+ .directExecutor()
+ .addService(makeSucceedingService())
+ .build()
+ .start());
+
+ // WHEN we update FCM token
+ AtomicReference<UpdateFcmTokenGrpcResponse> response = new AtomicReference<>();
+ mBgExecutor.submit(() -> response.set(
+ mDeviceCheckInClientImpl.updateFcmToken(
+ new ArraySet<>(), TEST_FCM_TOKEN))).get();
+
+ // THEN the response is successful
+ assertThat(response.get().isSuccessful()).isTrue();
+ assertThat(mReceivedFcmToken).isEqualTo(TEST_FCM_TOKEN);
+ }
+
+ @Test
+ public void updateFcmToken_noConnectivityOrNonVpnNetwork_isNotSuccessful()
+ throws Exception {
+ // GIVEN non-VPN network connects and then loses connectivity
+ Set<ConnectivityManager.NetworkCallback> networkCallbacks =
+ mShadowConnectivityManager.getNetworkCallbacks();
+ for (ConnectivityManager.NetworkCallback callback : networkCallbacks) {
+ callback.onUnavailable();
+ }
+
+ // GIVEN the service fails through the default network
+ mGrpcCleanup.register(InProcessServerBuilder
+ .forName(mDefaultNetworkServerName)
+ .directExecutor()
+ .addService(makeFailingService())
+ .build()
+ .start());
+
+ // WHEN we update FCM token
+ AtomicReference<UpdateFcmTokenGrpcResponse> response = new AtomicReference<>();
+ mBgExecutor.submit(() -> response.set(
+ mDeviceCheckInClientImpl.updateFcmToken(
+ new ArraySet<>(), TEST_FCM_TOKEN))).get();
+
+ // THEN the response is unsuccessful
+ assertThat(response.get().isSuccessful()).isFalse();
+ }
+
+ @Test
+ public void updateFcmToken_lostNonVpnConnection_isNotSuccessful()
+ throws Exception {
+ // GIVEN no connectable non-VPN networks
+ Set<ConnectivityManager.NetworkCallback> networkCallbacks =
+ mShadowConnectivityManager.getNetworkCallbacks();
+ for (ConnectivityManager.NetworkCallback callback : networkCallbacks) {
+ NetworkCapabilities capabilities =
+ Shadows.shadowOf(new NetworkCapabilities()).addCapability(
+ NET_CAPABILITY_VALIDATED);
+ callback.onCapabilitiesChanged(mNonVpnNetwork, capabilities);
+ callback.onLost(mNonVpnNetwork);
+ }
+
+ // GIVEN the service fails through the default network
+ mGrpcCleanup.register(InProcessServerBuilder
+ .forName(mDefaultNetworkServerName)
+ .directExecutor()
+ .addService(makeFailingService())
+ .build()
+ .start());
+
+ // WHEN we update FCM token
+ AtomicReference<UpdateFcmTokenGrpcResponse> response = new AtomicReference<>();
+ mBgExecutor.submit(() -> response.set(
+ mDeviceCheckInClientImpl.updateFcmToken(
+ new ArraySet<>(), TEST_FCM_TOKEN))).get();
+
+ // THEN the response is unsuccessful
+ assertThat(response.get().isSuccessful()).isFalse();
+ assertThat(response.get().hasRecoverableError()).isTrue();
+ }
+
+ @Test
public void cleanUp_unregistersNetworkCallback() {
// WHEN we call clean up
mDeviceCheckInClientImpl.cleanUp();
@@ -784,6 +908,17 @@
responseObserver.onNext(response);
responseObserver.onCompleted();
}
+
+ @Override
+ public void updateFcmToken(UpdateFcmTokenRequest req,
+ StreamObserver<UpdateFcmTokenResponse> responseObserver) {
+ mReceivedFcmToken = req.getFcmRegistrationToken();
+ UpdateFcmTokenResponse response = UpdateFcmTokenResponse
+ .newBuilder()
+ .build();
+ responseObserver.onNext(response);
+ responseObserver.onCompleted();
+ }
};
}
@@ -816,6 +951,13 @@
responseObserver.onError(new StatusRuntimeException(Status.DEADLINE_EXCEEDED));
responseObserver.onCompleted();
}
+
+ @Override
+ public void updateFcmToken(UpdateFcmTokenRequest req,
+ StreamObserver<UpdateFcmTokenResponse> responseObserver) {
+ responseObserver.onError(new StatusRuntimeException(Status.DEADLINE_EXCEEDED));
+ responseObserver.onCompleted();
+ }
};
}
}