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 58 public SilentProvisioningTestManager(Context context) { 59 mContext = context.getApplicationContext(); 60 } 61 62 public Intent getReceviedProfileProvisionedIntent() { 63 return mReceivedProfileProvisionedIntent; 64 } 65 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 78 private boolean waitDeviceOwnerProvisioning() throws InterruptedException { 79 return pollProvisioningResult(); 80 } 81 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 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 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).putExtras(bundle); 134 } 135 136 private static void wakeUpAndDismissInsecureKeyguard() { 137 try { 138 UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 139 uiDevice.wakeUp(); 140 uiDevice.pressMenu(); 141 } catch (RemoteException e) { 142 Log.e(TAG, "wakeUpScreen", e); 143 } 144 } 145 146 private static class BlockingReceiver extends BroadcastReceiver { 147 148 private final CountDownLatch mLatch = new CountDownLatch(1); 149 private final Context mContext; 150 private final String mAction; 151 private Intent mReceivedIntent; 152 153 private BlockingReceiver(Context context, String action) { 154 mContext = context; 155 mAction = action; 156 mReceivedIntent = null; 157 } 158 159 public void register() { 160 mContext.registerReceiver(this, new IntentFilter(mAction)); 161 } 162 163 public boolean await() throws InterruptedException { 164 return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS); 165 } 166 167 public Intent getReceivedIntent() { 168 return mReceivedIntent; 169 } 170 171 @Override 172 public void onReceive(Context context, Intent intent) { 173 mReceivedIntent = intent; 174 mLatch.countDown(); 175 } 176 } 177 } 178