1 /*
2  * Copyright (C) 2015 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 android.app.Activity;
20 import android.app.ActivityManager;
21 import android.app.AlertDialog;
22 import android.app.Notification;
23 import android.app.NotificationChannel;
24 import android.app.NotificationManager;
25 import android.app.admin.DevicePolicyManager;
26 import android.content.ActivityNotFoundException;
27 import android.content.ComponentName;
28 import android.content.Context;
29 import android.content.DialogInterface;
30 import android.content.Intent;
31 import android.content.pm.PackageManager;
32 import android.os.UserHandle;
33 import android.os.UserManager;
34 import android.provider.Settings;
35 import android.util.Log;
36 import android.widget.Toast;
37 
38 import com.android.cts.verifier.IntentDrivenTestActivity;
39 import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
40 import com.android.cts.verifier.R;
41 import com.android.cts.verifier.TestListAdapter.TestListItem;
42 
43 public class Utils {
44 
45     private static final String TAG = "CtsVerifierByodUtils";
46     static final int BUGREPORT_NOTIFICATION_ID = 12345;
47     private static final String CHANNEL_ID = "BugReport";
48     static final String FILE_PROVIDER_AUTHORITY =
49             "com.android.cts.verifier.managedprovisioning.fileprovider";
50 
createInteractiveTestItem(Activity activity, String id, int titleRes, int infoRes, ButtonInfo[] buttonInfos)51     static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
52             int infoRes, ButtonInfo[] buttonInfos) {
53         return TestListItem.newTest(activity, titleRes,
54                 id, new Intent(activity, IntentDrivenTestActivity.class)
55                 .putExtra(IntentDrivenTestActivity.EXTRA_ID, id)
56                 .putExtra(IntentDrivenTestActivity.EXTRA_TITLE, titleRes)
57                 .putExtra(IntentDrivenTestActivity.EXTRA_INFO, infoRes)
58                 .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS, buttonInfos),
59                 null);
60     }
61 
createInteractiveTestItem(Activity activity, String id, int titleRes, int infoRes, ButtonInfo buttonInfo)62     static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
63             int infoRes, ButtonInfo buttonInfo) {
64         return createInteractiveTestItem(activity, id, titleRes, infoRes,
65                 new ButtonInfo[] { buttonInfo });
66     }
67 
requestDeleteManagedProfile(Context context)68     static void requestDeleteManagedProfile(Context context) {
69         try {
70             Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
71             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
72             context.startActivity(intent);
73         }
74         catch (ActivityNotFoundException e) {
75             Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
76         }
77     }
78 
provisionManagedProfile(Activity activity, ComponentName admin, int requestCode)79     static void provisionManagedProfile(Activity activity, ComponentName admin, int requestCode) {
80         Intent sending = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
81         sending.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, admin);
82         if (sending.resolveActivity(activity.getPackageManager()) != null) {
83             activity.startActivityForResult(sending, requestCode);
84         } else {
85             showToast(activity, R.string.provisioning_byod_disabled);
86         }
87     }
88 
showBugreportNotification(Context context, String msg, int notificationId)89     static void showBugreportNotification(Context context, String msg, int notificationId) {
90         NotificationManager notificationManager = getNotificationManager(context);
91         NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
92                 CHANNEL_ID, NotificationManager.IMPORTANCE_HIGH);
93         notificationManager.createNotificationChannel(channel);
94         CharSequence title = context.getString(R.string.device_owner_requesting_bugreport_tests);
95         Notification notification = new Notification.Builder(context)
96                 .setChannelId(CHANNEL_ID)
97                 .setSmallIcon(R.drawable.icon)
98                 .setContentTitle(title)
99                 .setContentText(msg)
100                 .setStyle(new Notification.BigTextStyle().bigText(msg))
101                 .extend(new Notification.TvExtender())
102                 .build();
103         Log.d(TAG, "Sending notification: id=" + notificationId + ", title='" + title
104                 + "' text='" + msg + "'");
105         notificationManager.notify(notificationId, notification);
106     }
107 
getNotificationManager(Context context)108     private static NotificationManager getNotificationManager(Context context) {
109         if (UserManager.isHeadlessSystemUserMode()) {
110             int currentUserId = ActivityManager.getCurrentUser();
111             int contextUserId = context.getUser().getIdentifier();
112             if (currentUserId != contextUserId) {
113                 Log.d(TAG, "getNotificationManager(): using context for current user ("
114                         + currentUserId + ") instead of user " + contextUserId
115                         + " on headless system user mode");
116                 context = context.createContextAsUser(UserHandle.of(currentUserId), /* flags= */ 0);
117             }
118         }
119         Log.d(TAG, "Returning NotificationManager for context of user " + context.getUserId());
120         return context.getSystemService(NotificationManager.class);
121     }
122 
showToast(Context context, int messageId)123     static void showToast(Context context, int messageId) {
124         CharSequence msg = context.getString(messageId);
125         Log.d(TAG, "showToast(): " + msg);
126         Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
127     }
128 
129     /**
130      * Prompts the tester to set a screen lock credential, or change it if one exists.
131      *
132      * An instruction dialog is shown before the tester is sent to the ChooseLockGeneric activity
133      * in Settings.
134      *
135      * @param activity The calling activity where the result is handled
136      * @param requestCode The callback request code when the lock is set
137      */
setScreenLock(Activity activity, int requestCode)138     static void setScreenLock(Activity activity, int requestCode) {
139         final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
140         new AlertDialog.Builder(activity)
141                 .setTitle(R.string.provisioning_byod)
142                 .setMessage(R.string.provisioning_byod_set_screen_lock_dialog_message)
143                 .setPositiveButton(R.string.go_button_text, (DialogInterface dialog, int which) ->
144                         activity.startActivityForResult(intent, requestCode))
145                 .show();
146     }
147 
148     /**
149      * Prompts the tester to remove the current screen lock credential.
150      *
151      * An instruction dialog is shown before the tester is sent to the ChooseLockGeneric activity
152      * in Settings.
153      *
154      * @param activity The calling activity
155      */
removeScreenLock(Activity activity)156     static void removeScreenLock(Activity activity) {
157         final Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
158         new AlertDialog.Builder(activity)
159                 .setTitle(R.string.provisioning_byod)
160                 .setMessage(R.string.provisioning_byod_remove_screen_lock_dialog_message)
161                 .setPositiveButton(R.string.go_button_text, (DialogInterface dialog, int which) ->
162                         activity.startActivity(intent))
163                 .show();
164     }
165 
166 
167     /**
168      * Depending on form factor, the location of enterprise info page is different.
169      * The helper function opening settings can cause confusion, hence differentiating location
170      * it opens based on type of device.
171      *
172      * @param context The calling context
173      */
getManagedSettingsIntent(Context context)174     static Intent getManagedSettingsIntent(Context context) {
175         if (isWatch(context)) {
176             return new Intent(Settings.ACTION_SETTINGS);
177         } else {
178             return new Intent(Settings.ACTION_SECURITY_SETTINGS);
179         }
180     }
181 
182     /**
183      * Depending on form factor, device may not have room to show more than an icon
184      * for the enterprise managed cases.
185      * Returning an indicator, so the tests can be adjusted.
186      *
187      * @param context The calling context
188      */
isLockScreenManagedOrgNameSupported(Context context)189     static boolean isLockScreenManagedOrgNameSupported(Context context) {
190         return !isWatch(context);
191     }
192 
193 
isLockscreenSupported(Context context)194     static boolean isLockscreenSupported(Context context) {
195         return context.getPackageManager().hasSystemFeature(
196                 PackageManager.FEATURE_SECURE_LOCK_SCREEN);
197     }
198 
isTV(Context context)199     static boolean isTV(Context context) {
200         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
201                 || context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION);
202     }
203 
isWatch(Context context)204     static boolean isWatch(Context context) {
205         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
206     }
207 }
208