1 /* 2 * Copyright (C) 2023 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.launcher3.allapps; 18 19 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 20 21 import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED; 22 import static com.android.launcher3.allapps.UserProfileManager.STATE_ENABLED; 23 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED; 24 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.anyInt; 29 import static org.mockito.Mockito.doNothing; 30 import static org.mockito.Mockito.doReturn; 31 import static org.mockito.Mockito.spy; 32 import static org.mockito.Mockito.when; 33 34 import android.app.PendingIntent; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.content.pm.LauncherApps; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ResolveInfo; 40 import android.content.res.Resources; 41 import android.os.Process; 42 import android.os.UserHandle; 43 import android.os.UserManager; 44 45 import androidx.test.ext.junit.runners.AndroidJUnit4; 46 47 import com.android.launcher3.logging.StatsLogManager; 48 import com.android.launcher3.pm.UserCache; 49 import com.android.launcher3.util.ActivityContextWrapper; 50 import com.android.launcher3.util.ApiWrapper; 51 import com.android.launcher3.util.UserIconInfo; 52 import com.android.launcher3.util.rule.TestStabilityRule; 53 54 import org.junit.Before; 55 import org.junit.Rule; 56 import org.junit.Test; 57 import org.junit.rules.TestRule; 58 import org.junit.runner.RunWith; 59 import org.mockito.ArgumentCaptor; 60 import org.mockito.Mock; 61 import org.mockito.Mockito; 62 import org.mockito.MockitoAnnotations; 63 64 import java.util.ArrayList; 65 import java.util.Arrays; 66 67 @RunWith(AndroidJUnit4.class) 68 public class PrivateProfileManagerTest { 69 70 @Rule(order = 0) 71 public TestRule testStabilityRule = new TestStabilityRule(); 72 73 private static final UserHandle MAIN_HANDLE = Process.myUserHandle(); 74 private static final UserHandle PRIVATE_HANDLE = new UserHandle(11); 75 private static final UserIconInfo MAIN_ICON_INFO = 76 new UserIconInfo(MAIN_HANDLE, UserIconInfo.TYPE_MAIN); 77 private static final UserIconInfo PRIVATE_ICON_INFO = 78 new UserIconInfo(PRIVATE_HANDLE, UserIconInfo.TYPE_PRIVATE); 79 80 private PrivateProfileManager mPrivateProfileManager; 81 @Mock 82 private ActivityAllAppsContainerView mAllApps; 83 @Mock 84 private StatsLogManager mStatsLogManager; 85 @Mock 86 private UserCache mUserCache; 87 @Mock 88 private UserManager mUserManager; 89 @Mock 90 private Context mContext; 91 @Mock 92 private AllAppsStore<?> mAllAppsStore; 93 @Mock 94 private PackageManager mPackageManager; 95 @Mock 96 private LauncherApps mLauncherApps; 97 @Mock 98 private AllAppsRecyclerView mAllAppsRecyclerView; 99 @Mock 100 private Resources mResources; 101 102 @Before setUp()103 public void setUp() { 104 MockitoAnnotations.initMocks(this); 105 when(mUserCache.getUserProfiles()) 106 .thenReturn(Arrays.asList(MAIN_HANDLE, PRIVATE_HANDLE)); 107 when(mUserCache.getUserInfo(Process.myUserHandle())).thenReturn(MAIN_ICON_INFO); 108 when(mUserCache.getUserInfo(PRIVATE_HANDLE)).thenReturn(PRIVATE_ICON_INFO); 109 when(mAllApps.getContext()).thenReturn(mContext); 110 when(mContext.getResources()).thenReturn(mResources); 111 when(mContext.getApplicationContext()).thenReturn(getApplicationContext()); 112 when(mAllApps.getAppsStore()).thenReturn(mAllAppsStore); 113 when(mAllApps.getActiveRecyclerView()).thenReturn(mAllAppsRecyclerView); 114 when(mContext.getPackageManager()).thenReturn(mPackageManager); 115 when(mPackageManager.resolveActivity(any(), any())).thenReturn(new ResolveInfo()); 116 when(mContext.getSystemService(LauncherApps.class)).thenReturn(mLauncherApps); 117 when(mLauncherApps.getAppMarketActivityIntent(any(), any())).thenReturn(PendingIntent 118 .getActivity(new ActivityContextWrapper(getApplicationContext()), 0, 119 new Intent(), PendingIntent.FLAG_IMMUTABLE).getIntentSender()); 120 when(mContext.getPackageName()) 121 .thenReturn("com.android.launcher3.tests.privateProfileManager"); 122 when(mLauncherApps.getPreInstalledSystemPackages(any())).thenReturn(new ArrayList<>()); 123 mPrivateProfileManager = new PrivateProfileManager(mUserManager, 124 mAllApps, mStatsLogManager, mUserCache); 125 } 126 127 @Test lockPrivateProfile_requestsQuietModeAsTrue()128 public void lockPrivateProfile_requestsQuietModeAsTrue() throws Exception { 129 when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED)).thenReturn(false); 130 131 mPrivateProfileManager.setQuietMode(true /* lock */); 132 133 awaitTasksCompleted(); 134 Mockito.verify(mUserManager).requestQuietModeEnabled(true, PRIVATE_HANDLE); 135 } 136 137 @Test unlockPrivateProfile_requestsQuietModeAsFalse()138 public void unlockPrivateProfile_requestsQuietModeAsFalse() throws Exception { 139 when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED)).thenReturn(true); 140 141 mPrivateProfileManager.setQuietMode(false /* unlock */); 142 143 awaitTasksCompleted(); 144 Mockito.verify(mUserManager).requestQuietModeEnabled(false, PRIVATE_HANDLE); 145 } 146 147 @Test quietModeFlagPresent_privateSpaceIsResetToDisabled()148 public void quietModeFlagPresent_privateSpaceIsResetToDisabled() { 149 PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager); 150 doNothing().when(privateProfileManager).addPrivateSpaceDecorator(anyInt()); 151 doNothing().when(privateProfileManager).executeLock(); 152 doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView(); 153 when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED)) 154 .thenReturn(false, true); 155 156 // In first call the state should be disabled. 157 privateProfileManager.reset(); 158 assertEquals("Profile State is not Disabled", STATE_ENABLED, 159 privateProfileManager.getCurrentState()); 160 161 // In the next call the state should be disabled. 162 privateProfileManager.reset(); 163 assertEquals("Profile State is not Disabled", STATE_DISABLED, 164 privateProfileManager.getCurrentState()); 165 } 166 167 @Test transitioningToUnlocked_resetCallsPostUnlock()168 public void transitioningToUnlocked_resetCallsPostUnlock() throws Exception { 169 PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager); 170 doNothing().when(privateProfileManager).addPrivateSpaceDecorator(anyInt()); 171 doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView(); 172 when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED)) 173 .thenReturn(false); 174 doNothing().when(privateProfileManager).expandPrivateSpace(); 175 when(privateProfileManager.getCurrentState()).thenReturn(STATE_DISABLED); 176 177 privateProfileManager.setQuietMode(false /* unlock */); 178 privateProfileManager.reset(); 179 180 awaitTasksCompleted(); 181 Mockito.verify(privateProfileManager).postUnlock(); 182 } 183 184 @Test transitioningToLocked_resetCallsExecuteLock()185 public void transitioningToLocked_resetCallsExecuteLock() throws Exception { 186 PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager); 187 doNothing().when(privateProfileManager).addPrivateSpaceDecorator(anyInt()); 188 doNothing().when(privateProfileManager).executeLock(); 189 doReturn(mAllAppsRecyclerView).when(privateProfileManager).getMainRecyclerView(); 190 when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED)) 191 .thenReturn(true); 192 doNothing().when(privateProfileManager).expandPrivateSpace(); 193 when(privateProfileManager.getCurrentState()).thenReturn(STATE_ENABLED); 194 195 privateProfileManager.setQuietMode(true /* lock */); 196 privateProfileManager.reset(); 197 198 awaitTasksCompleted(); 199 Mockito.verify(privateProfileManager).executeLock(); 200 } 201 202 @Test openPrivateSpaceSettings_triggersCorrectIntent()203 public void openPrivateSpaceSettings_triggersCorrectIntent() { 204 Intent expectedIntent = ApiWrapper.INSTANCE.get(mContext).getPrivateSpaceSettingsIntent(); 205 ArgumentCaptor<Intent> acIntent = ArgumentCaptor.forClass(Intent.class); 206 mPrivateProfileManager.setPrivateSpaceSettingsAvailable(true); 207 208 mContext.startActivity(expectedIntent); 209 210 Mockito.verify(mContext).startActivity(acIntent.capture()); 211 assertEquals("Intent Action is different", 212 expectedIntent == null ? null : expectedIntent.toUri(0), 213 acIntent.getValue() == null ? null : acIntent.getValue().toUri(0)); 214 } 215 awaitTasksCompleted()216 private static void awaitTasksCompleted() throws Exception { 217 UI_HELPER_EXECUTOR.submit(() -> null).get(); 218 } 219 } 220