1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.devicelockcontroller.provision.grpc; 18 19 import android.os.Build; 20 import android.os.SystemProperties; 21 import android.util.ArraySet; 22 import android.util.Pair; 23 24 import androidx.annotation.Nullable; 25 import androidx.annotation.WorkerThread; 26 27 import com.android.devicelockcontroller.common.DeviceId; 28 import com.android.devicelockcontroller.common.DeviceLockConstants.DeviceProvisionState; 29 import com.android.devicelockcontroller.common.DeviceLockConstants.PauseDeviceProvisioningReason; 30 import com.android.devicelockcontroller.common.DeviceLockConstants.SetupFailureReason; 31 import com.android.devicelockcontroller.util.LogUtil; 32 33 /** 34 * An abstract class that's intended for implementation of class that manages communication with 35 * DeviceLock backend server. 36 */ 37 public abstract class DeviceCheckInClient { 38 private static final String TAG = "DeviceCheckInClient"; 39 public static final String DEVICE_CHECK_IN_CLIENT_DEBUG_CLASS_NAME = 40 "com.android.devicelockcontroller.debug.DeviceCheckInClientDebug"; 41 private static volatile DeviceCheckInClient sClient; 42 43 @Nullable 44 protected static String sRegisteredId; 45 protected static String sHostName = ""; 46 protected static int sPortNumber = 0; 47 protected static Pair<String, String> sApiKey = new Pair<>("", ""); 48 49 /** 50 * Get a instance of DeviceCheckInClient object. 51 */ getInstance( String className, String hostName, int portNumber, Pair<String, String> apiKey, @Nullable String registeredId)52 public static DeviceCheckInClient getInstance( 53 String className, 54 String hostName, 55 int portNumber, 56 Pair<String, String> apiKey, 57 @Nullable String registeredId) { 58 if (sClient == null) { 59 synchronized (DeviceCheckInClient.class) { 60 try { 61 // In case the initialization is already done by other thread use existing 62 // instance. 63 if (sClient != null) { 64 return sClient; 65 } 66 sHostName = hostName; 67 sPortNumber = portNumber; 68 sRegisteredId = registeredId; 69 sApiKey = apiKey; 70 if (Build.isDebuggable() && SystemProperties.getBoolean( 71 "debug.devicelock.checkin", true)) { 72 className = DEVICE_CHECK_IN_CLIENT_DEBUG_CLASS_NAME; 73 } 74 LogUtil.d(TAG, "Creating instance for " + className); 75 Class<?> clazz = Class.forName(className); 76 sClient = (DeviceCheckInClient) clazz.getDeclaredConstructor().newInstance(); 77 } catch (Exception e) { 78 throw new RuntimeException("Failed to get DeviceCheckInClient instance", e); 79 } 80 } 81 } 82 return sClient; 83 } 84 85 /** 86 * Check In with DeviceLock backend server and get the next step for the device 87 * 88 * @param deviceIds A set of all device unique identifiers, this could include IMEIs, 89 * MEIDs, etc. 90 * @param carrierInfo The information of the device's sim operator which is used to 91 * determine the device's geological location and eventually 92 * eligibility of the DeviceLock program. 93 * @param fcmRegistrationToken The fcm registration token 94 * @return A class that encapsulate the response from the backend server. 95 */ 96 @WorkerThread getDeviceCheckInStatus( ArraySet<DeviceId> deviceIds, String carrierInfo, @Nullable String fcmRegistrationToken)97 public abstract GetDeviceCheckInStatusGrpcResponse getDeviceCheckInStatus( 98 ArraySet<DeviceId> deviceIds, String carrierInfo, 99 @Nullable String fcmRegistrationToken); 100 101 /** 102 * Check if the device is in an approved country for the device lock program. 103 * 104 * @param carrierInfo The information of the device's sim operator which is used to determine 105 * the device's geological location and eventually eligibility of the 106 * DeviceLock program. Could be null if unavailable. 107 * @return A class that encapsulate the response from the backend server. 108 */ isDeviceInApprovedCountry( @ullable String carrierInfo)109 public abstract IsDeviceInApprovedCountryGrpcResponse isDeviceInApprovedCountry( 110 @Nullable String carrierInfo); 111 112 /** 113 * Inform the server that device provisioning has been paused for a certain amount of time. 114 * 115 * @param reason The reason that provisioning has been paused. 116 * @return A class that encapsulate the response from the backend sever. 117 */ 118 @WorkerThread pauseDeviceProvisioning( @auseDeviceProvisioningReason int reason)119 public abstract PauseDeviceProvisioningGrpcResponse pauseDeviceProvisioning( 120 @PauseDeviceProvisioningReason int reason); 121 122 /** 123 * Reports the current provision state of the device. 124 * 125 * @param reasonOfFailure one of {@link SetupFailureReason} 126 * @param lastReceivedProvisionState one of {@link DeviceProvisionState}. 127 * It must be the value from the response when this API 128 * was called last time. If this API is called for the first 129 * time, then 130 * {@link 131 * DeviceProvisionState#PROVISION_STATE_UNSPECIFIED } 132 * must be used. 133 * @param isSuccessful true if the device has been setup for DeviceLock program 134 * successful; false otherwise. 135 * @return A class that encapsulate the response from the backend server. 136 */ 137 @WorkerThread reportDeviceProvisionState( @etupFailureReason int reasonOfFailure, @DeviceProvisionState int lastReceivedProvisionState, boolean isSuccessful)138 public abstract ReportDeviceProvisionStateGrpcResponse reportDeviceProvisionState( 139 @SetupFailureReason int reasonOfFailure, 140 @DeviceProvisionState int lastReceivedProvisionState, 141 boolean isSuccessful); 142 } 143