1 /* 2 * Copyright (C) 2012 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.cts.verifier.managedprovisioning; 18 19 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 20 21 import android.app.Service; 22 import android.app.admin.DeviceAdminReceiver; 23 import android.app.admin.DevicePolicyManager; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.ServiceConnection; 29 import android.content.pm.PackageManager; 30 import android.os.IBinder; 31 import android.os.PersistableBundle; 32 import android.os.Process; 33 import android.os.RemoteException; 34 import android.os.UserHandle; 35 import android.os.UserManager; 36 import android.util.Log; 37 38 import androidx.localbroadcastmanager.content.LocalBroadcastManager; 39 40 import com.android.bedstead.dpmwrapper.DeviceOwnerHelper; 41 import com.android.compatibility.common.util.enterprise.DeviceAdminReceiverUtils; 42 import com.android.cts.verifier.R; 43 44 import java.util.Collections; 45 import java.util.HashSet; 46 import java.util.List; 47 import java.util.Set; 48 import java.util.function.Consumer; 49 50 /** 51 * Profile owner receiver for BYOD flow test. 52 * Setup cross-profile intent filter after successful provisioning. 53 */ 54 public class DeviceAdminTestReceiver extends DeviceAdminReceiver { 55 public static final String KEY_BUNDLE_WIPE_IMMEDIATELY = "wipe_immediately"; 56 private static final String TAG = "DeviceAdminTestReceiver"; 57 private static final String DEVICE_OWNER_PKG = 58 "com.android.cts.verifier"; 59 private static final String ADMIN_RECEIVER_TEST_CLASS = 60 DEVICE_OWNER_PKG + ".managedprovisioning.DeviceAdminTestReceiver"; 61 private static final ComponentName RECEIVER_COMPONENT_NAME = new ComponentName( 62 DEVICE_OWNER_PKG, ADMIN_RECEIVER_TEST_CLASS); 63 public static final String EXTRA_MANAGED_USER_TEST = 64 "com.android.cts.verifier.managedprovisioning.extra.MANAGED_USER_TEST"; 65 public static final String EXTRA_LOGOUT_ON_START = 66 "com.android.cts.verifier.managedprovisioning.extra.LOGOUT_ON_START"; 67 public static final String AFFILIATION_ID = "affiliationId"; 68 getReceiverComponentName()69 public static ComponentName getReceiverComponentName() { 70 return RECEIVER_COMPONENT_NAME; 71 } 72 73 @Override onReceive(Context context, Intent intent)74 public void onReceive(Context context, Intent intent) { 75 if (DeviceAdminReceiverUtils.disableSelf(context, intent)) return; 76 if (DeviceOwnerHelper.runManagerMethod(this, context, intent)) return; 77 78 DevicePolicyManager dpm = getManager(context); 79 String action = intent.getAction(); 80 Log.d(TAG, "onReceive(): user=" + UserHandle.myUserId() + ", action=" + action 81 + ", EXTRA_USER=" + intent.getExtra(Intent.EXTRA_USER) 82 + ", dpm=" + dpm); 83 84 // Must set affiliation on headless system user, otherwise some operations in the current 85 // user (which is PO) won't be allowed (like uininstalling a package) 86 if (ACTION_DEVICE_ADMIN_ENABLED.equals(action) && UserManager.isHeadlessSystemUserMode()) { 87 Set<String> ids = new HashSet<>(1); 88 ids.add(DeviceAdminTestReceiver.AFFILIATION_ID); 89 Log.i(TAG, "Setting affiliation ids to " + ids); 90 dpm.setAffiliationIds(getWho(context), ids); 91 Log.i(TAG, "Is affiliated: " + dpm.isAffiliatedUser()); 92 } 93 94 super.onReceive(context, intent); 95 } 96 97 @Override onProfileProvisioningComplete(Context context, Intent intent)98 public void onProfileProvisioningComplete(Context context, Intent intent) { 99 Log.d(TAG, "Provisioning complete intent received"); 100 setupProfile(context); 101 wipeIfNecessary(context, intent); 102 } 103 104 @Override onBugreportSharingDeclined(Context context, Intent intent)105 public void onBugreportSharingDeclined(Context context, Intent intent) { 106 Log.i(TAG, "Bugreport sharing declined"); 107 Utils.showBugreportNotification(context, context.getString( 108 R.string.bugreport_sharing_declined), Utils.BUGREPORT_NOTIFICATION_ID); 109 } 110 111 @Override onBugreportShared(Context context, Intent intent, String bugreportFileHash)112 public void onBugreportShared(Context context, Intent intent, String bugreportFileHash) { 113 Log.i(TAG, "Bugreport shared"); 114 Utils.showBugreportNotification(context, context.getString( 115 R.string.bugreport_shared_successfully), Utils.BUGREPORT_NOTIFICATION_ID); 116 } 117 118 @Override onBugreportFailed(Context context, Intent intent, int failureCode)119 public void onBugreportFailed(Context context, Intent intent, int failureCode) { 120 Log.i(TAG, "Bugreport collection operation failed, code: " + failureCode); 121 Utils.showBugreportNotification(context, context.getString( 122 R.string.bugreport_failed_completing), Utils.BUGREPORT_NOTIFICATION_ID); 123 } 124 125 @Override onLockTaskModeEntering(Context context, Intent intent, String pkg)126 public void onLockTaskModeEntering(Context context, Intent intent, String pkg) { 127 Log.i(TAG, "Entering LockTask mode: " + pkg); 128 LocalBroadcastManager.getInstance(context) 129 .sendBroadcast(new Intent(LockTaskUiTestActivity.ACTION_LOCK_TASK_STARTED)); 130 } 131 132 @Override onLockTaskModeExiting(Context context, Intent intent)133 public void onLockTaskModeExiting(Context context, Intent intent) { 134 Log.i(TAG, "Exiting LockTask mode"); 135 LocalBroadcastManager.getInstance(context) 136 .sendBroadcast(new Intent(LockTaskUiTestActivity.ACTION_LOCK_TASK_STOPPED)); 137 } 138 139 @Override onEnabled(Context context, Intent intent)140 public void onEnabled(Context context, Intent intent) { 141 int myUserId = UserHandle.myUserId(); 142 Log.i(TAG, "Device admin enabled on user " + myUserId); 143 if (intent.getBooleanExtra(EXTRA_MANAGED_USER_TEST, false)) { 144 DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); 145 ComponentName admin = getReceiverComponentName(); 146 dpm.setAffiliationIds(admin, 147 Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID)); 148 context.startActivity( 149 new Intent(context, ManagedUserPositiveTestActivity.class).setFlags( 150 Intent.FLAG_ACTIVITY_NEW_TASK)); 151 152 bindPrimaryUserService(context, iCrossUserService -> { 153 try { 154 UserHandle userHandle = Process.myUserHandle(); 155 Log.d(TAG, "calling switchUser(" + userHandle + ") from " + myUserId); 156 iCrossUserService.switchUser(userHandle); 157 } catch (RemoteException re) { 158 Log.e(TAG, "Error when calling primary user", re); 159 } 160 }); 161 } else if (intent.getBooleanExtra(EXTRA_LOGOUT_ON_START, false)) { 162 DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); 163 ComponentName admin = getReceiverComponentName(); 164 dpm.setAffiliationIds(admin, 165 Collections.singleton(DeviceAdminTestReceiver.AFFILIATION_ID)); 166 dpm.logoutUser(admin); 167 } 168 } 169 setupProfile(Context context)170 private void setupProfile(Context context) { 171 DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); 172 dpm.setProfileEnabled(new ComponentName(context.getApplicationContext(), getClass())); 173 174 // Setup cross-profile intent filter to allow communications between the two versions of CtsVerifier 175 // Primary -> work direction 176 IntentFilter filter = new IntentFilter(); 177 filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER); 178 filter.addAction(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE); 179 filter.addAction(ByodHelperActivity.ACTION_CHECK_DISK_ENCRYPTION); 180 filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK); 181 filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK_WORK_PROFILE_GLOBAL_RESTRICTION); 182 filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK_PRIMARY_PROFILE_GLOBAL_RESTRICTION); 183 filter.addAction(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS); 184 filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE); 185 filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO_WITH_EXTRA_OUTPUT); 186 filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO_WITHOUT_EXTRA_OUTPUT); 187 filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO); 188 filter.addAction(ByodHelperActivity.ACTION_KEYGUARD_DISABLED_FEATURES); 189 filter.addAction(ByodHelperActivity.ACTION_LOCKNOW); 190 filter.addAction(ByodHelperActivity.ACTION_TEST_NFC_BEAM); 191 filter.addAction(ByodHelperActivity.ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG); 192 filter.addAction(ByodHelperActivity.ACTION_TEST_APP_LINKING_DIALOG); 193 filter.addAction(ByodHelperActivity.ACTION_NOTIFICATION); 194 filter.addAction(ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN); 195 filter.addAction(ByodHelperActivity.ACTION_CLEAR_NOTIFICATION); 196 filter.addAction(ByodHelperActivity.ACTION_SET_USER_RESTRICTION); 197 filter.addAction(ByodHelperActivity.ACTION_CLEAR_USER_RESTRICTION); 198 filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_WORK); 199 filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST); 200 filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON); 201 filter.addAction( 202 PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN); 203 filter.addAction(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST); 204 filter.addAction(VpnTestActivity.ACTION_VPN); 205 filter.addAction(AlwaysOnVpnSettingsTestActivity.ACTION_ALWAYS_ON_VPN_SETTINGS_TEST); 206 filter.addAction(RecentsRedactionActivity.ACTION_RECENTS); 207 filter.addAction(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE); 208 filter.addAction(ByodHelperActivity.ACTION_TEST_PATTERN_WORK_CHALLENGE); 209 filter.addAction(ByodHelperActivity.ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS); 210 filter.addAction(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO); 211 filter.addAction(ByodHelperActivity.ACTION_TEST_PARENT_PROFILE_PASSWORD); 212 filter.addAction(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG); 213 filter.addAction(KeyChainTestActivity.ACTION_KEYCHAIN); 214 filter.addAction(CommandReceiverActivity.ACTION_EXECUTE_COMMAND); 215 filter.addAction(WorkProfileWidgetActivity.ACTION_TEST_WORK_PROFILE_WIDGET); 216 filter.addAction( 217 CrossProfilePermissionControlActivity.ACTION_CROSS_PROFILE_PERMISSION_CONTROL); 218 filter.addAction(LocationCheckerActivity.ACTION_CHECK_LOCATION_WORK); 219 dpm.addCrossProfileIntentFilter(getWho(context), filter, 220 DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT); 221 222 // Work -> primary direction 223 filter = new IntentFilter(); 224 filter.addAction(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS); 225 filter.addAction(ByodHelperActivity.ACTION_DISK_ENCRYPTION_STATUS); 226 filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK_IN_PRIMARY); 227 filter.addAction(ByodFlowTestActivity.ACTION_TEST_RESULT); 228 filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL); 229 230 dpm.addCrossProfileIntentFilter(getWho(context), filter, 231 DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED); 232 233 // Disable the work profile instance of this activity, because it is a helper activity for 234 // the work -> primary direction. 235 context.getPackageManager().setComponentEnabledSetting( 236 new ComponentName(context, ByodPrimaryHelperActivity.class.getName()), 237 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 238 239 // Disable the work profile instance of ByodFlowTestActivity 240 context.getPackageManager().setComponentEnabledSetting( 241 new ComponentName(context, ByodFlowTestActivity.class), 242 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 243 } 244 wipeIfNecessary(Context context, Intent intent)245 private void wipeIfNecessary(Context context, Intent intent) { 246 PersistableBundle bundle = intent.getParcelableExtra( 247 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE); 248 if (bundle != null && bundle.getBoolean(KEY_BUNDLE_WIPE_IMMEDIATELY, false)) { 249 getManager(context).wipeData(0); 250 } 251 } 252 bindPrimaryUserService(Context context, Consumer<ICrossUserService> consumer)253 private void bindPrimaryUserService(Context context, Consumer<ICrossUserService> consumer) { 254 DevicePolicyManager devicePolicyManager = context.getSystemService( 255 DevicePolicyManager.class); 256 List<UserHandle> adminUsers = devicePolicyManager.getBindDeviceAdminTargetUsers( 257 getReceiverComponentName()); 258 Log.d(TAG, "bindPrimaryUserService(): admins=" + adminUsers); 259 UserHandle primaryUser = adminUsers.get(0); 260 261 Log.d(TAG, "Calling primary user: " + primaryUser); 262 final ServiceConnection serviceConnection = new ServiceConnection() { 263 @Override 264 public void onServiceConnected(ComponentName name, IBinder service) { 265 Log.d(TAG, "onServiceConnected is called"); 266 consumer.accept(ICrossUserService.Stub.asInterface(service)); 267 } 268 269 @Override 270 public void onServiceDisconnected(ComponentName name) { 271 Log.d(TAG, "onServiceDisconnected is called"); 272 } 273 }; 274 final Intent serviceIntent = new Intent(context, PrimaryUserService.class); 275 devicePolicyManager.bindDeviceAdminServiceAsUser(getReceiverComponentName(), serviceIntent, 276 serviceConnection, Context.BIND_AUTO_CREATE, primaryUser); 277 } 278 279 public static final class PrimaryUserService extends Service { 280 private final ICrossUserService.Stub mBinder = new ICrossUserService.Stub() { 281 public void switchUser(UserHandle userHandle) { 282 Log.d(TAG, "switchUser: " + userHandle); 283 getSystemService(DevicePolicyManager.class).switchUser(getReceiverComponentName(), 284 userHandle); 285 } 286 }; 287 288 @Override onBind(Intent intent)289 public IBinder onBind(Intent intent) { 290 return mBinder; 291 } 292 } 293 } 294