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 17 package com.android.systemui.keyguard; 18 19 import static org.mockito.Mockito.doReturn; 20 import static org.mockito.Mockito.eq; 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.verify; 23 import static org.mockito.Mockito.when; 24 import static org.mockito.Matchers.any; 25 import static org.mockito.Matchers.anyInt; 26 import static org.mockito.Matchers.argThat; 27 28 import android.app.Activity; 29 import android.app.ActivityManager; 30 import android.app.ActivityOptions; 31 import android.app.IActivityManager; 32 import android.app.IApplicationThread; 33 import android.app.ProfilerInfo; 34 import android.content.ComponentName; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.os.Bundle; 38 import android.os.IBinder; 39 import android.os.UserHandle; 40 import android.support.test.filters.SmallTest; 41 import android.support.test.runner.AndroidJUnit4; 42 43 import com.android.systemui.SysuiTestCase; 44 import com.android.systemui.keyguard.WorkLockActivity; 45 import com.android.systemui.keyguard.WorkLockActivityController; 46 import com.android.systemui.recents.misc.SystemServicesProxy; 47 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener; 48 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 import org.mockito.ArgumentCaptor; 53 import org.mockito.ArgumentMatcher; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 57 /** 58 * runtest systemui -c com.android.systemui.keyguard.WorkLockActivityControllerTest 59 */ 60 @SmallTest 61 @RunWith(AndroidJUnit4.class) 62 public class WorkLockActivityControllerTest extends SysuiTestCase { 63 private static final int USER_ID = 333; 64 private static final int TASK_ID = 444; 65 66 private @Mock Context mContext; 67 private @Mock SystemServicesProxy mSystemServicesProxy; 68 private @Mock IActivityManager mIActivityManager; 69 70 private WorkLockActivityController mController; 71 private TaskStackListener mTaskStackListener; 72 73 @Before 74 public void setUp() throws Exception { 75 MockitoAnnotations.initMocks(this); 76 77 // Set a package name to use for checking ComponentName well-formedness in tests. 78 doReturn("com.example.test").when(mContext).getPackageName(); 79 80 // Construct controller. Save the TaskStackListener for injecting events. 81 final ArgumentCaptor<TaskStackListener> listenerCaptor = 82 ArgumentCaptor.forClass(TaskStackListener.class); 83 mController = 84 new WorkLockActivityController(mContext, mSystemServicesProxy, mIActivityManager); 85 86 verify(mSystemServicesProxy).registerTaskStackListener(listenerCaptor.capture()); 87 mTaskStackListener = listenerCaptor.getValue(); 88 } 89 90 @Test 91 public void testOverlayStartedWhenLocked() throws Exception { 92 // When starting an activity succeeds, 93 setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_SUCCESS); 94 95 // And the controller receives a message saying the profile is locked, 96 mTaskStackListener.onTaskProfileLocked(TASK_ID, USER_ID); 97 98 // The overlay should start and the task the activity started in should not be removed. 99 verifyStartActivity(TASK_ID, true /*taskOverlay*/); 100 verify(mSystemServicesProxy, never()).removeTask(anyInt() /*taskId*/); 101 } 102 103 @Test 104 public void testRemoveTaskOnFailureToStartOverlay() throws Exception { 105 // When starting an activity fails, 106 setActivityStartCode(TASK_ID, true /*taskOverlay*/, ActivityManager.START_CLASS_NOT_FOUND); 107 108 // And the controller receives a message saying the profile is locked, 109 mTaskStackListener.onTaskProfileLocked(TASK_ID, USER_ID); 110 111 // The task the activity started in should be removed to prevent the locked task from 112 // being shown. 113 verifyStartActivity(TASK_ID, true /*taskOverlay*/); 114 verify(mSystemServicesProxy).removeTask(TASK_ID); 115 } 116 117 // End of tests, start of helpers 118 // ------------------------------ 119 120 private void setActivityStartCode(int taskId, boolean taskOverlay, int code) throws Exception { 121 doReturn(code).when(mIActivityManager).startActivityAsUser( 122 eq((IApplicationThread) null), 123 eq((String) null), 124 any(Intent.class), 125 eq((String) null), 126 eq((IBinder) null), 127 eq((String) null), 128 anyInt(), 129 anyInt(), 130 eq((ProfilerInfo) null), 131 argThat(hasOptions(taskId, taskOverlay)), 132 eq(UserHandle.USER_CURRENT)); 133 } 134 135 private void verifyStartActivity(int taskId, boolean taskOverlay) throws Exception { 136 verify(mIActivityManager).startActivityAsUser( 137 eq((IApplicationThread) null), 138 eq((String) null), 139 any(Intent.class), 140 eq((String) null), 141 eq((IBinder) null), 142 eq((String) null), 143 anyInt(), 144 anyInt(), 145 eq((ProfilerInfo) null), 146 argThat(hasOptions(taskId, taskOverlay)), 147 eq(UserHandle.USER_CURRENT)); 148 } 149 150 private static ArgumentMatcher<Intent> hasComponent(final Context context, 151 final Class<? extends Activity> activityClass) { 152 return new ArgumentMatcher<Intent>() { 153 @Override 154 public boolean matches(Intent intent) { 155 return new ComponentName(context, activityClass).equals(intent.getComponent()); 156 } 157 }; 158 } 159 160 private static ArgumentMatcher<Bundle> hasOptions(final int taskId, final boolean overlay) { 161 return new ArgumentMatcher<Bundle>() { 162 @Override 163 public boolean matches(Bundle item) { 164 final ActivityOptions options = ActivityOptions.fromBundle(item); 165 return (options.getLaunchTaskId() == taskId) 166 && (options.getTaskOverlay() == overlay); 167 } 168 }; 169 } 170 } 171