1 /* 2 * Copyright (C) 2017 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.compatibility.common.util.devicepolicy.provisioning; 17 18 import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED; 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 20 import static android.content.Intent.ACTION_MANAGED_PROFILE_ADDED; 21 22 import android.content.BroadcastReceiver; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.os.Bundle; 27 import android.os.RemoteException; 28 import android.support.test.InstrumentationRegistry; 29 import android.support.test.uiautomator.UiDevice; 30 import android.util.Log; 31 32 import com.android.compatibility.common.util.BlockingBroadcastReceiver; 33 34 import java.util.concurrent.CountDownLatch; 35 import java.util.concurrent.LinkedBlockingQueue; 36 import java.util.concurrent.TimeUnit; 37 38 public class SilentProvisioningTestManager { 39 private static final long TIMEOUT_SECONDS = 120L; 40 private static final String TAG = "SilentProvisioningTest"; 41 42 private final LinkedBlockingQueue<Boolean> mProvisioningResults = new LinkedBlockingQueue(1); 43 44 private final IBooleanCallback mProvisioningResultCallback = new IBooleanCallback.Stub() { 45 @Override 46 public void onResult(boolean result) { 47 try { 48 mProvisioningResults.put(result); 49 } catch (InterruptedException e) { 50 Log.e(TAG, "IBooleanCallback.callback", e); 51 } 52 } 53 }; 54 55 private final Context mContext; 56 private Intent mReceivedProfileProvisionedIntent; 57 SilentProvisioningTestManager(Context context)58 public SilentProvisioningTestManager(Context context) { 59 mContext = context.getApplicationContext(); 60 } 61 getReceviedProfileProvisionedIntent()62 public Intent getReceviedProfileProvisionedIntent() { 63 return mReceivedProfileProvisionedIntent; 64 } 65 startProvisioningAndWait(Intent provisioningIntent)66 public boolean startProvisioningAndWait(Intent provisioningIntent) throws InterruptedException { 67 wakeUpAndDismissInsecureKeyguard(); 68 mContext.startActivity(getStartIntent(provisioningIntent)); 69 Log.i(TAG, "startActivity with intent: " + provisioningIntent); 70 71 if (ACTION_PROVISION_MANAGED_PROFILE.equals(provisioningIntent.getAction())) { 72 return waitManagedProfileProvisioning(); 73 } else { 74 return waitDeviceOwnerProvisioning(); 75 } 76 } 77 waitDeviceOwnerProvisioning()78 private boolean waitDeviceOwnerProvisioning() throws InterruptedException { 79 return pollProvisioningResult(); 80 } 81 waitManagedProfileProvisioning()82 private boolean waitManagedProfileProvisioning() throws InterruptedException { 83 BlockingBroadcastReceiver managedProfileProvisionedReceiver = 84 new BlockingBroadcastReceiver(mContext, ACTION_MANAGED_PROFILE_PROVISIONED); 85 BlockingBroadcastReceiver managedProfileAddedReceiver = 86 new BlockingBroadcastReceiver(mContext, ACTION_MANAGED_PROFILE_ADDED); 87 try { 88 managedProfileProvisionedReceiver.register(); 89 managedProfileAddedReceiver.register(); 90 91 if (!pollProvisioningResult()) { 92 return false; 93 } 94 95 mReceivedProfileProvisionedIntent = 96 managedProfileProvisionedReceiver.awaitForBroadcast(); 97 if (mReceivedProfileProvisionedIntent == null) { 98 Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed"); 99 return false; 100 } 101 102 if (managedProfileAddedReceiver.awaitForBroadcast() == null) { 103 Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed"); 104 return false; 105 } 106 } finally { 107 managedProfileProvisionedReceiver.unregisterQuietly(); 108 managedProfileAddedReceiver.unregisterQuietly(); 109 } 110 return true; 111 } 112 pollProvisioningResult()113 private boolean pollProvisioningResult() throws InterruptedException { 114 Boolean result = mProvisioningResults.poll(TIMEOUT_SECONDS, TimeUnit.SECONDS); 115 if (result == null) { 116 Log.i(TAG, "ManagedProvisioning doesn't return result within " 117 + TIMEOUT_SECONDS + " seconds "); 118 return false; 119 } 120 121 if (!result) { 122 Log.i(TAG, "Failed to provision"); 123 return false; 124 } 125 return true; 126 } 127 getStartIntent(Intent intent)128 private Intent getStartIntent(Intent intent) { 129 final Bundle bundle = new Bundle(); 130 bundle.putParcelable(Intent.EXTRA_INTENT, intent); 131 bundle.putBinder(StartProvisioningActivity.EXTRA_BOOLEAN_CALLBACK, 132 mProvisioningResultCallback.asBinder()); 133 return new Intent(mContext, StartProvisioningActivity.class) 134 .putExtras(bundle) 135 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 136 } 137 wakeUpAndDismissInsecureKeyguard()138 private static void wakeUpAndDismissInsecureKeyguard() { 139 try { 140 UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 141 uiDevice.wakeUp(); 142 uiDevice.pressMenu(); 143 } catch (RemoteException e) { 144 Log.e(TAG, "wakeUpScreen", e); 145 } 146 } 147 148 private static class BlockingReceiver extends BroadcastReceiver { 149 150 private final CountDownLatch mLatch = new CountDownLatch(1); 151 private final Context mContext; 152 private final String mAction; 153 private Intent mReceivedIntent; 154 BlockingReceiver(Context context, String action)155 private BlockingReceiver(Context context, String action) { 156 mContext = context; 157 mAction = action; 158 mReceivedIntent = null; 159 } 160 register()161 public void register() { 162 mContext.registerReceiver(this, new IntentFilter(mAction)); 163 } 164 await()165 public boolean await() throws InterruptedException { 166 return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); 167 } 168 getReceivedIntent()169 public Intent getReceivedIntent() { 170 return mReceivedIntent; 171 } 172 173 @Override onReceive(Context context, Intent intent)174 public void onReceive(Context context, Intent intent) { 175 mReceivedIntent = intent; 176 mLatch.countDown(); 177 } 178 } 179 } 180