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