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