• 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 package com.android.cts.deviceandprofileowner;
17 
18 import static com.google.common.truth.Truth.assertWithMessage;
19 
20 import android.annotation.NonNull;
21 import android.app.admin.DeviceAdminReceiver;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.SharedPreferences;
27 import android.content.pm.PackageInfo;
28 import android.content.pm.PackageManager;
29 import android.net.Uri;
30 import android.os.Process;
31 import android.os.SystemClock;
32 import android.os.UserHandle;
33 import android.os.UserManager;
34 import android.test.InstrumentationTestCase;
35 import android.text.TextUtils;
36 import android.util.Log;
37 
38 import androidx.test.platform.app.InstrumentationRegistry;
39 
40 import com.android.bedstead.dpmwrapper.DeviceOwnerHelper;
41 import com.android.bedstead.dpmwrapper.TestAppSystemServiceFactory;
42 import com.android.compatibility.common.util.SystemUtil;
43 import com.android.cts.deviceandprofileowner.BaseDeviceAdminTest.BasicAdminReceiver;
44 
45 import java.util.List;
46 import java.util.concurrent.CountDownLatch;
47 
48 /**
49  * Base class for profile and device based tests.
50  *
51  * <p>This class handles making sure that the test is the profile or device owner and that it has an
52  * active admin registered, so that all tests may assume these are done.
53  */
54 public abstract class BaseDeviceAdminTest extends InstrumentationTestCase {
55 
56     public static final class BasicAdminReceiver extends DeviceAdminReceiver {
57 
58         static final String ACTION_NETWORK_LOGS_AVAILABLE =
59                 "com.android.cts.deviceandprofileowner.action.ACTION_NETWORK_LOGS_AVAILABLE";
60 
61         static final String EXTRA_NETWORK_LOGS_BATCH_TOKEN =
62                 "com.android.cts.deviceandprofileowner.extra.NETWORK_LOGS_BATCH_TOKEN";
63 
64         // Shared preference used to coordinate compliance acknowledgement test.
65         static final String COMPLIANCE_ACK_PREF_NAME = "compliance-pref";
66         // Shared preference key controlling whether to use default callback implementation.
67         static final String COMPLIANCE_ACK_PREF_KEY_OVERRIDE = "compliance-pref-override";
68         // Shared preference key to save broadcast receipt.
69         static final String COMPLIANCE_ACK_PREF_KEY_BCAST_RECEIVED = "compliance-pref-bcast";
70 
71         @Override
onReceive(Context context, Intent intent)72         public void onReceive(Context context, Intent intent) {
73             if (DeviceOwnerHelper.runManagerMethod(this, context, intent)) return;
74 
75             super.onReceive(context, intent);
76         }
77 
78         @Override
onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri, String suggestedAlias)79         public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
80                 String suggestedAlias) {
81             super.onChoosePrivateKeyAlias(context, intent, uid, uri, suggestedAlias);
82             if (uid != Process.myUid() || uri == null) {
83                 return null;
84             }
85             return uri.getQueryParameter("alias");
86         }
87 
88         @Override
onPasswordExpiring(Context context, Intent intent, UserHandle user)89         public void onPasswordExpiring(Context context, Intent intent, UserHandle user) {
90             super.onPasswordExpiring(context, intent, user);
91             if (mOnPasswordExpiryTimeoutCalled != null) {
92                 mOnPasswordExpiryTimeoutCalled.countDown();
93             }
94         }
95 
96         @Override
onNetworkLogsAvailable(Context context, Intent intent, long batchToken, int networkLogsCount)97         public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken,
98                 int networkLogsCount) {
99             super.onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
100             // send the broadcast, the rest of the test happens in NetworkLoggingTest
101             Intent batchIntent = new Intent(ACTION_NETWORK_LOGS_AVAILABLE);
102             batchIntent.putExtra(EXTRA_NETWORK_LOGS_BATCH_TOKEN, batchToken);
103             context.sendBroadcast(batchIntent);
104         }
105 
106         @Override
onComplianceAcknowledgementRequired( @onNull Context context, @NonNull Intent intent)107         public void onComplianceAcknowledgementRequired(
108                 @NonNull Context context, @NonNull Intent intent) {
109             final SharedPreferences pref =
110                     context.getSharedPreferences(COMPLIANCE_ACK_PREF_NAME, Context.MODE_PRIVATE);
111             // Record the broadcast receipt.
112             pref.edit().putBoolean(COMPLIANCE_ACK_PREF_KEY_BCAST_RECEIVED, true).commit();
113             // Call the default implementation unless instructed otherwise.
114             if (!pref.getBoolean(COMPLIANCE_ACK_PREF_KEY_OVERRIDE, false)) {
115                 super.onComplianceAcknowledgementRequired(context, intent);
116             }
117         }
118 
119         @Override
onPasswordChanged(@onNull Context context, @NonNull Intent intent, @NonNull UserHandle user)120         public void onPasswordChanged(@NonNull Context context, @NonNull Intent intent,
121                 @NonNull UserHandle user) {
122             super.onPasswordChanged(context, intent, user);
123             if (mOnPasswordChangedCalled != null) {
124                 mOnPasswordChangedCalled.countDown();
125             }
126         }
127     }
128 
129     private static final String TAG = BaseDeviceAdminTest.class.getSimpleName();
130 
131     public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName();
132     public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
133             PACKAGE_NAME, BasicAdminReceiver.class.getName());
134 
135     protected DevicePolicyManager mDevicePolicyManager;
136     protected UserManager mUserManager;
137     protected Context mContext;
138     protected boolean mHasSecureLockScreen;
139     protected boolean mIsAutomotive;
140     protected boolean mIsDeviceOwnerTest;
141     static CountDownLatch mOnPasswordExpiryTimeoutCalled;
142     static CountDownLatch mOnPasswordChangedCalled;
143     protected final String mTag = getClass().getSimpleName();
144 
145     @Override
setUp()146     protected void setUp() throws Exception {
147         super.setUp();
148         mContext = getInstrumentation().getContext();
149 
150         mUserManager = mContext.getSystemService(UserManager.class);
151         assertWithMessage("userManager").that(mUserManager).isNotNull();
152 
153         mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
154                 PackageManager.FEATURE_SECURE_LOCK_SCREEN);
155         mIsAutomotive = mContext.getPackageManager().hasSystemFeature(
156                 PackageManager.FEATURE_AUTOMOTIVE);
157 
158         mIsDeviceOwnerTest = "DeviceOwner"
159                 .equals(InstrumentationRegistry.getArguments().getString("admin_type"));
160 
161         mDevicePolicyManager = TestAppSystemServiceFactory.getDevicePolicyManager(mContext,
162                 BasicAdminReceiver.class, mIsDeviceOwnerTest);
163 
164         Log.v(TAG, "setup(): dpm for " + getClass() + " and user " + mContext.getUserId() + ": "
165                 + mDevicePolicyManager);
166         assertWithMessage("dpm").that(mDevicePolicyManager).isNotNull();
167 
168         boolean isActiveAdmin = mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT);
169         boolean isProfileOwner = mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME);
170         boolean isDeviceOwner = mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME);
171 
172         Log.d(mTag, "setup() on user " + mContext.getUserId() + ": package=" + PACKAGE_NAME
173                 + ", adminReceiverComponent=" + ADMIN_RECEIVER_COMPONENT
174                 + ", isActiveAdmin=" + isActiveAdmin + ", isProfileOwner=" + isProfileOwner
175                 + ", isDeviceOwner=" + isDeviceOwner + ", isDeviceOwnerTest=" + mIsDeviceOwnerTest);
176 
177         assertWithMessage("active admin for %s", ADMIN_RECEIVER_COMPONENT).that(isActiveAdmin)
178                 .isTrue();
179 
180         assertWithMessage("profile owner or device owner for %s", PACKAGE_NAME)
181                 .that(isProfileOwner || isDeviceOwner).isTrue();
182     }
183 
getTargetApiLevel()184     protected int getTargetApiLevel() throws Exception {
185         final PackageManager pm = mContext.getPackageManager();
186         final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), /* flags= */ 0);
187         return pi.applicationInfo.targetSdkVersion;
188     }
189 
190     /**
191      * Runs a Shell command, returning a trimmed response.
192      */
runShellCommand(String template, Object...args)193     protected String runShellCommand(String template, Object...args) {
194         final String command = String.format(template, args);
195         Log.d(mTag, "runShellCommand(): " + command);
196         try {
197             final String result = SystemUtil.runShellCommand(getInstrumentation(), command);
198             return TextUtils.isEmpty(result) ? "" : result.trim();
199         } catch (Exception e) {
200             throw new RuntimeException("Command '" + command + "' failed: ", e);
201         }
202     }
203 
waitUntilUserUnlocked()204     protected void waitUntilUserUnlocked() {
205         boolean isUserUnlocked = mUserManager.isUserUnlocked();
206         int retries = 30;
207         while (retries >= 0 && !isUserUnlocked) {
208             retries--;
209             try {
210                 Thread.sleep(500);
211             } catch (InterruptedException e) {
212                 break;
213             }
214         }
215         assertWithMessage("user unlocked").that(mUserManager.isUserUnlocked()).isTrue();
216     }
217 
assertPasswordSufficiency(boolean expectPasswordSufficient)218     protected void assertPasswordSufficiency(boolean expectPasswordSufficient) {
219         waitUntilUserUnlocked();
220         assertWithMessage("isActivePasswordSufficient()")
221                 .that(mDevicePolicyManager.isActivePasswordSufficient())
222                 .isEqualTo(expectPasswordSufficient);
223     }
224 
isDeviceOwner()225     protected boolean isDeviceOwner() {
226         return mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME);
227     }
228 
setDelegatedScopes(String delegatePackage, List<String> scopes)229     protected void setDelegatedScopes(String delegatePackage, List<String> scopes) {
230         Log.v(TAG, "Calling setDelegatedScopes(" + ADMIN_RECEIVER_COMPONENT.flattenToShortString()
231                 + ", " + delegatePackage + ", " + scopes + ") using " + mDevicePolicyManager);
232         mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT, delegatePackage, scopes);
233     }
234 
sleep(int timeMs)235     void sleep(int timeMs) {
236         Log.d(TAG, "Sleeping " + timeMs + " ms");
237         SystemClock.sleep(timeMs);
238     }
239 }
240