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