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