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