1 /* 2 * Copyright (C) 2022 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.storage; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.os.Build; 22 23 import androidx.annotation.Nullable; 24 25 import com.android.devicelockcontroller.common.DeviceLockConstants.DeviceProvisionState; 26 import com.android.devicelockcontroller.policy.DeviceStateController.DeviceState; 27 import com.android.devicelockcontroller.policy.FinalizationControllerImpl.FinalizationState; 28 import com.android.devicelockcontroller.util.LogUtil; 29 30 import java.util.Locale; 31 32 /** 33 * Stores global parameters. 34 * <p> 35 * Note that, these parameter values are common across all users which means any users can read or 36 * write them. Due to this reason, unlike {@link UserParameters}, they must be accessed all the time 37 * via the {@link GlobalParametersClient}. 38 */ 39 final class GlobalParameters { 40 private static final String FILENAME = "global-params"; 41 private static final String KEY_REGISTERED_DEVICE_ID = "registered_device_id"; 42 private static final String KEY_FORCED_PROVISION = "forced_provision"; 43 private static final String KEY_LAST_RECEIVED_PROVISION_STATE = "last-received-provision-state"; 44 private static final String TAG = "GlobalParameters"; 45 private static final String KEY_DEVICE_STATE = "device_state"; 46 private static final String KEY_FINALIZATION_STATE = "finalization_state"; 47 public static final String KEY_IS_PROVISION_READY = "key-is-provision-ready"; 48 49 GlobalParameters()50 private GlobalParameters() { 51 } 52 getSharedPreferences(Context context)53 private static SharedPreferences getSharedPreferences(Context context) { 54 final Context deviceContext = context.createDeviceProtectedStorageContext(); 55 56 return deviceContext.getSharedPreferences(FILENAME, Context.MODE_PRIVATE); 57 } 58 isProvisionReady(Context context)59 static boolean isProvisionReady(Context context) { 60 return getSharedPreferences(context).getBoolean(KEY_IS_PROVISION_READY, false); 61 } 62 setProvisionReady(Context context, boolean isProvisionReady)63 static void setProvisionReady(Context context, boolean isProvisionReady) { 64 getSharedPreferences(context).edit().putBoolean(KEY_IS_PROVISION_READY, 65 isProvisionReady).apply(); 66 } 67 68 /** 69 * Gets the unique identifier that is regisered to DeviceLock backend server. 70 * 71 * @param context Context used to get the shared preferences. 72 * @return The registered device unique identifier; null if device has never checked in with 73 * backed server. 74 */ 75 @Nullable getRegisteredDeviceId(Context context)76 static String getRegisteredDeviceId(Context context) { 77 SharedPreferences preferences = getSharedPreferences(context); 78 return preferences.getString(KEY_REGISTERED_DEVICE_ID, null); 79 } 80 81 /** 82 * Set the unique identifier that is registered to DeviceLock backend server. 83 * 84 * @param context Context used to get the shared preferences. 85 * @param registeredDeviceId The registered device unique identifier. 86 */ setRegisteredDeviceId(Context context, String registeredDeviceId)87 static void setRegisteredDeviceId(Context context, String registeredDeviceId) { 88 getSharedPreferences(context) 89 .edit() 90 .putString(KEY_REGISTERED_DEVICE_ID, registeredDeviceId) 91 .apply(); 92 } 93 94 /** 95 * Check if provision should be forced. 96 * 97 * @param context Context used to get the shared preferences. 98 * @return True if the provision should be forced without any delays. 99 */ isProvisionForced(Context context)100 static boolean isProvisionForced(Context context) { 101 return getSharedPreferences(context).getBoolean(KEY_FORCED_PROVISION, false); 102 } 103 104 /** 105 * Gets the current device state. 106 */ 107 @DeviceState getDeviceState(Context context)108 static int getDeviceState(Context context) { 109 return getSharedPreferences(context).getInt(KEY_DEVICE_STATE, DeviceState.UNDEFINED); 110 } 111 112 /** 113 * Sets the current device state. 114 */ setDeviceState(Context context, @DeviceState int state)115 static void setDeviceState(Context context, @DeviceState int state) { 116 getSharedPreferences(context).edit().putInt(KEY_DEVICE_STATE, state).apply(); 117 } 118 119 /** 120 * Gets the current {@link FinalizationState}. 121 */ 122 @FinalizationState getFinalizationState(Context context)123 static int getFinalizationState(Context context) { 124 return getSharedPreferences(context).getInt( 125 KEY_FINALIZATION_STATE, FinalizationState.UNFINALIZED); 126 } 127 128 /** 129 * Sets the current {@link FinalizationState}. 130 */ setFinalizationState(Context context, @FinalizationState int state)131 static void setFinalizationState(Context context, @FinalizationState int state) { 132 getSharedPreferences(context).edit().putInt(KEY_FINALIZATION_STATE, state).apply(); 133 } 134 135 /** 136 * Set provision is forced 137 * 138 * @param context Context used to get the shared preferences. 139 * @param isForced The new value of the forced provision flag. 140 */ setProvisionForced(Context context, boolean isForced)141 static void setProvisionForced(Context context, boolean isForced) { 142 getSharedPreferences(context) 143 .edit() 144 .putBoolean(KEY_FORCED_PROVISION, isForced) 145 .apply(); 146 } 147 148 @DeviceProvisionState getLastReceivedProvisionState(Context context)149 static int getLastReceivedProvisionState(Context context) { 150 return getSharedPreferences(context).getInt(KEY_LAST_RECEIVED_PROVISION_STATE, 151 DeviceProvisionState.PROVISION_STATE_UNSPECIFIED); 152 } 153 setLastReceivedProvisionState(Context context, @DeviceProvisionState int provisionState)154 static void setLastReceivedProvisionState(Context context, 155 @DeviceProvisionState int provisionState) { 156 getSharedPreferences(context) 157 .edit() 158 .putInt(KEY_LAST_RECEIVED_PROVISION_STATE, provisionState) 159 .apply(); 160 } 161 clear(Context context)162 static void clear(Context context) { 163 if (!Build.isDebuggable()) { 164 throw new SecurityException("Clear is not allowed in non-debuggable build!"); 165 } 166 getSharedPreferences(context).edit().clear().commit(); 167 } 168 dump(Context context)169 static void dump(Context context) { 170 LogUtil.d(TAG, String.format(Locale.US, 171 "Dumping GlobalParameters ...\n" 172 + "%s: %s\n" // registered_device_id: 173 + "%s: %s\n" // forced_provision: 174 + "%s: %s\n" // last-received-provision-state: 175 + "%s: %s\n" // device_state: 176 + "%s: %s\n", // is-provision-ready: 177 KEY_REGISTERED_DEVICE_ID, getRegisteredDeviceId(context), 178 KEY_FORCED_PROVISION, isProvisionForced(context), 179 KEY_LAST_RECEIVED_PROVISION_STATE, getLastReceivedProvisionState(context), 180 KEY_DEVICE_STATE, getDeviceState(context), 181 KEY_IS_PROVISION_READY, isProvisionReady(context) 182 )); 183 } 184 } 185