1 /* 2 * Copyright (C) 2019 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 package com.google.android.cts.deviceowner; 17 18 import static android.server.wm.WindowManagerState.STATE_RESUMED; 19 20 import static com.google.common.truth.Truth.assertWithMessage; 21 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.pm.PackageManager; 28 import android.os.RemoteException; 29 import android.provider.Settings; 30 import android.server.wm.WindowManagerStateHelper; 31 import android.support.test.uiautomator.By; 32 import android.support.test.uiautomator.UiDevice; 33 import android.support.test.uiautomator.Until; 34 import android.test.InstrumentationTestCase; 35 import android.util.Log; 36 37 import androidx.test.InstrumentationRegistry; 38 39 import com.android.bedstead.dpmwrapper.DeviceOwnerHelper; 40 import com.android.bedstead.dpmwrapper.TestAppSystemServiceFactory; 41 import com.android.compatibility.common.util.enterprise.DeviceAdminReceiverUtils; 42 43 /** 44 * Class for device-owner based tests. 45 * 46 * <p>This class handles making sure that the test is the device owner and that it has an active 47 * admin registered if necessary. The admin component can be accessed through {@link #getWho()}. 48 */ 49 public final class DeviceOwnerTest extends InstrumentationTestCase { 50 51 private static final String TAG = DeviceOwnerTest.class.getSimpleName(); 52 53 private static final String WORK_POLICY_INFO_TEXT = "Your work policy info"; 54 55 public static final int TIMEOUT_MS = 2_000; 56 57 protected Context mContext; 58 protected UiDevice mDevice; 59 60 /** Device Admin receiver for DO. */ 61 public static final class BasicAdminReceiver extends DeviceAdminReceiver { 62 63 @Override onReceive(Context context, Intent intent)64 public void onReceive(Context context, Intent intent) { 65 // Ignore intents used by DpmWrapper IPC between current and system users 66 if (DeviceOwnerHelper.runManagerMethod(this, context, intent)) return; 67 68 // Hack used to manually disable the admin during development 69 if (DeviceAdminReceiverUtils.disableSelf(context, intent)) return; 70 71 super.onReceive(context, intent); 72 } 73 } 74 75 static final String PACKAGE_NAME = DeviceOwnerTest.class.getPackage().getName(); 76 static final ComponentName RECEIVER_COMPONENT = 77 new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName()); 78 79 protected DevicePolicyManager mDevicePolicyManager; 80 protected PackageManager mPackageManager; 81 protected boolean mIsDeviceOwner; 82 83 @Override setUp()84 protected void setUp() throws Exception { 85 super.setUp(); 86 mContext = getInstrumentation().getContext(); 87 mDevice = UiDevice.getInstance(getInstrumentation()); 88 mPackageManager = mContext.getPackageManager(); 89 mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext, 90 BasicAdminReceiver.class); 91 92 mIsDeviceOwner = mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME); 93 Log.d(TAG, "setup(): dpm=" + mDevicePolicyManager + ", isDO: " + mIsDeviceOwner); 94 95 if (mIsDeviceOwner) { 96 assertWithMessage("isAdminActive(%s)", RECEIVER_COMPONENT) 97 .that(mDevicePolicyManager.isAdminActive(RECEIVER_COMPONENT)).isTrue(); 98 99 // Note DPM.getDeviceOwner() now always returns null on non-DO users as of NYC. 100 assertWithMessage("%s.getDeviceOwner()", mDevicePolicyManager) 101 .that(mDevicePolicyManager.getDeviceOwner()).isEqualTo(PACKAGE_NAME); 102 } 103 104 try { 105 mDevice.setOrientationNatural(); 106 } catch (RemoteException e) { 107 throw new RuntimeException("failed to freeze device orientation", e); 108 } 109 wakeupDeviceAndPressHome(); 110 } 111 wakeupDeviceAndPressHome()112 private void wakeupDeviceAndPressHome() throws Exception { 113 mDevice.wakeUp(); 114 mDevice.pressMenu(); 115 mDevice.pressHome(); 116 } 117 118 @Override tearDown()119 protected void tearDown() throws Exception { 120 mDevice.pressBack(); 121 mDevice.pressHome(); 122 mDevice.waitForIdle(TIMEOUT_MS); // give UI time to finish animating 123 } 124 launchPrivacyAndCheckWorkPolicyInfo()125 private boolean launchPrivacyAndCheckWorkPolicyInfo() throws Exception { 126 // Launch Settings 127 launchSettingsPage(InstrumentationRegistry.getContext(), Settings.ACTION_PRIVACY_SETTINGS); 128 129 // Wait for loading permission usage data. 130 mDevice.waitForIdle(TIMEOUT_MS); 131 132 Log.d(TAG, "Waiting " + TIMEOUT_MS + "ms for the '" + WORK_POLICY_INFO_TEXT + "' message"); 133 134 return (null != mDevice.wait(Until.findObject(By.text(WORK_POLICY_INFO_TEXT)), TIMEOUT_MS)); 135 } 136 launchSettingsPage(Context ctx, String pageName)137 private void launchSettingsPage(Context ctx, String pageName) throws Exception { 138 Intent intent = new Intent(pageName); 139 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 140 141 ComponentName componentName = 142 ctx.getPackageManager() 143 .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) 144 .getComponentInfo() 145 .getComponentName(); 146 ctx.startActivity(intent); 147 148 new WindowManagerStateHelper().waitForActivityState(componentName, STATE_RESUMED); 149 } 150 disableWorkPolicyInfoActivity()151 private void disableWorkPolicyInfoActivity() { 152 mContext.getPackageManager() 153 .setComponentEnabledSetting( 154 new ComponentName(mContext, WorkPolicyInfoActivity.class), 155 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 156 PackageManager.DONT_KILL_APP); 157 } 158 launchPrivacySettingsAndAssertWorkPolicyInfoIsShowing()159 private void launchPrivacySettingsAndAssertWorkPolicyInfoIsShowing() throws Exception { 160 assertWithMessage("Work policy info (%s) on settings entry", WORK_POLICY_INFO_TEXT) 161 .that(launchPrivacyAndCheckWorkPolicyInfo()).isTrue(); 162 } 163 launchPrivacySettingsAndAssertWorkPolicyInfoIsNotShowing()164 private void launchPrivacySettingsAndAssertWorkPolicyInfoIsNotShowing() throws Exception { 165 assertWithMessage("Work policy info (%s) on settings entry", WORK_POLICY_INFO_TEXT) 166 .that(launchPrivacyAndCheckWorkPolicyInfo()).isFalse(); 167 } 168 169 /** 170 * If the app is the active device owner and has work policy info, then we should have a Privacy 171 * entry for it. 172 */ testDeviceOwnerWithInfo()173 public void testDeviceOwnerWithInfo() throws Exception { 174 assertWithMessage("is device owner").that(mIsDeviceOwner).isTrue(); 175 176 launchPrivacySettingsAndAssertWorkPolicyInfoIsShowing(); 177 } 178 179 /** 180 * If the app is the active device owner, but doesn't have work policy info, then we shouldn't 181 * have a Privacy entry for it. 182 */ testDeviceOwnerWithoutInfo()183 public void testDeviceOwnerWithoutInfo() throws Exception { 184 assertWithMessage("is device owner").that(mIsDeviceOwner).isTrue(); 185 186 disableWorkPolicyInfoActivity(); 187 188 launchPrivacySettingsAndAssertWorkPolicyInfoIsNotShowing(); 189 } 190 191 /** 192 * If the app is NOT the active device owner, then we should not have a Privacy entry for work 193 * policy info. 194 */ testNonDeviceOwnerWithInfo()195 public void testNonDeviceOwnerWithInfo() throws Exception { 196 assertWithMessage("is device owner").that(mIsDeviceOwner).isFalse(); 197 198 launchPrivacySettingsAndAssertWorkPolicyInfoIsNotShowing(); 199 } 200 201 /** 202 * If the app is NOT the active device owner, and doesn't have work policy info, then we should 203 * not have a Privacy entry for work policy info. 204 */ testNonDeviceOwnerWithoutInfo()205 public void testNonDeviceOwnerWithoutInfo() throws Exception { 206 assertWithMessage("is device owner").that(mIsDeviceOwner).isFalse(); 207 208 disableWorkPolicyInfoActivity(); 209 210 launchPrivacySettingsAndAssertWorkPolicyInfoIsNotShowing(); 211 } 212 } 213