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 android.app.admin.DeviceAdminReceiver; 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageManager; 25 import android.net.Uri; 26 import android.os.Process; 27 import android.os.UserHandle; 28 import android.os.UserManager; 29 import android.test.InstrumentationTestCase; 30 import android.text.TextUtils; 31 import android.util.Log; 32 33 import com.android.compatibility.common.util.SystemUtil; 34 import java.util.concurrent.CountDownLatch; 35 36 /** 37 * Base class for profile and device based tests. 38 * 39 * This class handles making sure that the test is the profile or device owner and that it has an 40 * active admin registered, so that all tests may assume these are done. 41 */ 42 public class BaseDeviceAdminTest extends InstrumentationTestCase { 43 44 public static class BasicAdminReceiver extends DeviceAdminReceiver { 45 46 @Override onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri, String suggestedAlias)47 public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri, 48 String suggestedAlias) { 49 super.onChoosePrivateKeyAlias(context, intent, uid, uri, suggestedAlias); 50 if (uid != Process.myUid() || uri == null) { 51 return null; 52 } 53 return uri.getQueryParameter("alias"); 54 } 55 56 @Override onPasswordExpiring(Context context, Intent intent, UserHandle user)57 public void onPasswordExpiring(Context context, Intent intent, UserHandle user) { 58 super.onPasswordExpiring(context, intent, user); 59 if (mOnPasswordExpiryTimeoutCalled != null) { 60 mOnPasswordExpiryTimeoutCalled.countDown(); 61 } 62 } 63 } 64 65 public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName(); 66 public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName( 67 PACKAGE_NAME, BasicAdminReceiver.class.getName()); 68 69 protected DevicePolicyManager mDevicePolicyManager; 70 protected UserManager mUserManager; 71 protected Context mContext; 72 static CountDownLatch mOnPasswordExpiryTimeoutCalled; 73 74 private final String mTag = getClass().getSimpleName(); 75 76 @Override setUp()77 protected void setUp() throws Exception { 78 super.setUp(); 79 mContext = getInstrumentation().getContext(); 80 81 mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class); 82 assertNotNull(mDevicePolicyManager); 83 84 mUserManager = mContext.getSystemService(UserManager.class); 85 assertNotNull(mUserManager); 86 87 assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT)); 88 assertTrue("App is neither device nor profile owner", 89 mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) || 90 mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME)); 91 } 92 getTargetApiLevel()93 protected int getTargetApiLevel() throws Exception { 94 final PackageManager pm = mContext.getPackageManager(); 95 final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), /* flags =*/ 0); 96 return pi.applicationInfo.targetSdkVersion; 97 } 98 99 /** 100 * Runs a Shell command, returning a trimmed response. 101 */ runShellCommand(String template, Object...args)102 protected String runShellCommand(String template, Object...args) { 103 final String command = String.format(template, args); 104 Log.d(mTag, "runShellCommand(): " + command); 105 try { 106 final String result = SystemUtil.runShellCommand(getInstrumentation(), command); 107 return TextUtils.isEmpty(result) ? "" : result.trim(); 108 } catch (Exception e) { 109 throw new RuntimeException("Command '" + command + "' failed: ", e); 110 } 111 } 112 waitUntilUserUnlocked()113 protected void waitUntilUserUnlocked() { 114 boolean isUserUnlocked = mUserManager.isUserUnlocked(); 115 int retries = 30; 116 while (retries >= 0 && !isUserUnlocked) { 117 retries--; 118 try { 119 Thread.sleep(500); 120 } catch (InterruptedException e) { 121 break; 122 } 123 } 124 assertTrue("User should have been unlocked", mUserManager.isUserUnlocked()); 125 } 126 assertPasswordSufficiency(boolean expectPasswordSufficient)127 protected void assertPasswordSufficiency(boolean expectPasswordSufficient) { 128 waitUntilUserUnlocked(); 129 int retries = 100; 130 // isActivePasswordSufficient() gets the result asynchronously so let's retry a few times 131 while (retries >= 0 132 && mDevicePolicyManager.isActivePasswordSufficient() != expectPasswordSufficient) { 133 retries--; 134 try { 135 Thread.sleep(200); 136 } catch (InterruptedException e) { 137 break; 138 } 139 } 140 assertEquals(expectPasswordSufficient, mDevicePolicyManager.isActivePasswordSufficient()); 141 } 142 isDeviceOwner()143 protected boolean isDeviceOwner() { 144 return mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME); 145 } 146 } 147