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