• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.packageinstaller;
18 
19 import android.app.UiAutomation;
20 import android.content.Intent;
21 import android.content.pm.PackageInstaller;
22 import android.content.pm.PackageManager;
23 import android.content.pm.ResolveInfo;
24 import android.os.UserHandle;
25 import android.provider.Settings;
26 import android.support.test.uiautomator.By;
27 import android.support.test.uiautomator.BySelector;
28 import android.support.test.uiautomator.UiObject2;
29 import android.support.test.uiautomator.Until;
30 import android.util.Log;
31 
32 import java.util.regex.Pattern;
33 
34 /**
35  * This class tests manual package install and uninstall by a device owner.
36  */
37 public final class ManualPackageInstallTest extends BasePackageInstallTest {
38 
39     private static final String TAG = ManualPackageInstallTest.class.getSimpleName();
40 
41     private static final int AUTOMATOR_WAIT_TIMEOUT = 5000;
42     private static final int INSTALL_WAIT_TIME = 5000;
43 
44     private static final BySelector INSTALL_BUTTON_SELECTOR = By.text(Pattern.compile("Install",
45             Pattern.CASE_INSENSITIVE));
46 
47     private UiAutomation mUiAutomation;
48     private boolean mIsAutomotive;
49 
50     @Override
setUp()51     protected void setUp() throws Exception {
52         super.setUp();
53         mUiAutomation = getInstrumentation().getUiAutomation();
54         mIsAutomotive = mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
55     }
56 
testManualInstallSucceeded()57     public void testManualInstallSucceeded() throws Exception {
58         assertInstallPackage();
59     }
60 
testManualInstallBlocked()61     public void testManualInstallBlocked() throws Exception {
62         synchronized (mPackageInstallerTimeoutLock) {
63             mCallbackReceived = false;
64             mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
65         }
66         // Calls the original installPackage which does not click through the install button.
67         Log.d(TAG, "Installing " + TEST_APP_LOCATION);
68         super.installPackage(TEST_APP_LOCATION);
69         synchronized (mPackageInstallerTimeoutLock) {
70             try {
71                 mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
72             } catch (InterruptedException e) {
73                 Thread.currentThread().interrupt();
74                 Log.e(TAG, "Interrupted", e);
75             }
76             assertTrue(mCallbackReceived);
77             assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
78         }
79 
80         mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
81         Log.d(TAG, "Starting " + mCallbackIntent + " on user " + UserHandle.myUserId());
82         mContext.startActivity(mCallbackIntent);
83 
84         automateDismissInstallBlockedDialog();
85 
86         // Assuming installation is not synchronous, we should wait a while before checking.
87         Thread.sleep(INSTALL_WAIT_TIME);
88         assertFalse(isPackageInstalled(TEST_APP_PKG));
89     }
90 
91     @Override
installPackage(String packageLocation)92     protected void installPackage(String packageLocation) throws Exception {
93         super.installPackage(packageLocation);
94 
95         synchronized (mPackageInstallerTimeoutLock) {
96             try {
97                 mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
98             } catch (InterruptedException e) {
99             }
100             assertTrue(mCallbackReceived);
101             assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
102         }
103 
104         // Use a receiver to listen for package install.
105         synchronized (mPackageInstallerTimeoutLock) {
106             mCallbackReceived = false;
107             mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
108         }
109 
110         mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
111         mContext.startActivity(mCallbackIntent);
112 
113         automateInstallClick();
114     }
115 
automateInstallClick()116     private void automateInstallClick() {
117         mDevice.wait(Until.hasObject(INSTALL_BUTTON_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
118         UiObject2 button = mDevice.findObject(INSTALL_BUTTON_SELECTOR);
119         assertNotNull("Install button not found", button);
120         button.click();
121     }
122 
automateDismissInstallBlockedDialog()123     private void automateDismissInstallBlockedDialog() {
124         BySelector selector = getPopUpImageSelector();
125         mDevice.wait(Until.hasObject(selector), AUTOMATOR_WAIT_TIMEOUT);
126         UiObject2 icon = mDevice.findObject(selector);
127         assertNotNull("Policy transparency dialog icon not found: " + selector, icon);
128         // "OK" button only present in the dialog if it is blocked by policy.
129         UiObject2 button = mDevice.findObject(getPopUpButtonSelector());
130         assertNotNull("OK button not found", button);
131         button.click();
132     }
133 
getSettingsPackageName()134     private String getSettingsPackageName() {
135         String settingsPackageName = mIsAutomotive
136                 ? "com.android.car.settings"
137                 : "com.android.settings";
138         mUiAutomation.adoptShellPermissionIdentity("android.permission.INTERACT_ACROSS_USERS");
139         try {
140             ResolveInfo resolveInfo = mPackageManager.resolveActivityAsUser(
141                     new Intent(Settings.ACTION_SETTINGS), PackageManager.MATCH_SYSTEM_ONLY,
142                     UserHandle.USER_SYSTEM);
143             if (resolveInfo != null && resolveInfo.activityInfo != null) {
144                 settingsPackageName = resolveInfo.activityInfo.packageName;
145             }
146         } finally {
147             mUiAutomation.dropShellPermissionIdentity();
148         }
149         Log.d(TAG, "getSettingsPackageName(): returning " + settingsPackageName);
150         return settingsPackageName;
151     }
152 
getPopUpButtonSelector()153     private BySelector getPopUpButtonSelector() {
154         return By.clazz(android.widget.Button.class.getName())
155                 .res("android:id/button1")
156                 .pkg(getSettingsPackageName());
157     }
158 
getPopUpImageSelector()159     private BySelector getPopUpImageSelector() {
160         final String settingsPackageName = getSettingsPackageName();
161         final String resId = mIsAutomotive ? "car_ui_alert_icon" : "admin_support_icon";
162         return By.clazz(android.widget.ImageView.class.getName())
163                 .res(settingsPackageName + ":id/" + resId)
164                 .pkg(settingsPackageName);
165     }
166 }
167