1 /* 2 * Copyright (C) 2019 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.documentsui; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.never; 23 import static org.mockito.Mockito.times; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import android.app.Activity; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.om.OverlayInfo; 31 import android.content.om.OverlayManager; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.PackageManager; 34 import android.os.UserHandle; 35 36 import androidx.core.util.Consumer; 37 import androidx.test.filters.SmallTest; 38 import androidx.test.platform.app.InstrumentationRegistry; 39 import androidx.test.runner.AndroidJUnit4; 40 41 import com.android.documentsui.theme.ThemeOverlayManager; 42 43 import com.google.common.collect.Lists; 44 45 import org.junit.Before; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 import org.mockito.Mock; 49 import org.mockito.MockitoAnnotations; 50 51 import java.util.concurrent.CountDownLatch; 52 import java.util.concurrent.TimeUnit; 53 54 @SmallTest 55 @RunWith(AndroidJUnit4.class) 56 public class ThemeOverlayManagerTest { 57 private static final String TEST_DISABLED_PREFIX = "com.example."; 58 private static final String TEST_ENABLED_PREFIX = "com.example.enabled."; 59 private static final String TEST_OVERLAY_PACKAGE = "test.overlay"; 60 private static final String TEST_TARGET_PACKAGE = "test.target"; 61 62 @Mock 63 OverlayManager mOverlayManager; 64 65 @Mock 66 PackageManager mPackageManager; 67 68 Consumer<Boolean> mCallback; 69 Context mContext; 70 CountDownLatch mLatch; 71 ThemeOverlayManager mThemeOverlayManager; 72 UserHandle mUserHandle; 73 74 @Before setUp()75 public void setUp() throws Exception { 76 InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( 77 "android.permission.CHANGE_OVERLAY_PACKAGES"); 78 79 MockitoAnnotations.initMocks(this); 80 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 81 mLatch = new CountDownLatch(1); 82 mUserHandle = UserHandle.of(UserHandle.myUserId()); 83 mCallback = result -> mLatch.countDown(); 84 85 when(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), 86 mUserHandle)).thenReturn(Lists.newArrayList( 87 createOverlayInfo(getOverlayPackageId(), getEnabledTargetPackageId(), true))); 88 89 when(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(), 90 mUserHandle)).thenReturn(Lists.newArrayList( 91 createOverlayInfo(getOverlayPackageId(), getDisabledTargetPackageId(), false))); 92 } 93 94 @Test testApplyOverlays_shouldSetEnabled()95 public void testApplyOverlays_shouldSetEnabled() throws Exception { 96 final boolean enabled = true; 97 98 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 99 getDisabledTargetPackageId()); 100 101 mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); 102 mLatch.await(5, TimeUnit.SECONDS); 103 104 verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, 105 mUserHandle); 106 } 107 108 @Test testApplyOverlays_shouldGetOverlayInfo()109 public void testApplyOverlays_shouldGetOverlayInfo() throws Exception { 110 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 111 getEnabledTargetPackageId()); 112 113 mThemeOverlayManager.applyOverlays(mContext, true /* enabled */, mCallback); 114 mLatch.await(5, TimeUnit.SECONDS); 115 116 verify(mOverlayManager, times(1)).getOverlayInfosForTarget(getEnabledTargetPackageId(), 117 mUserHandle); 118 } 119 120 @Test testApplyOverlays_shouldCheckEnabled_beforeSetEnabled()121 public void testApplyOverlays_shouldCheckEnabled_beforeSetEnabled() { 122 final boolean enabled = true; 123 124 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 125 getEnabledTargetPackageId()); 126 127 mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); 128 129 verify(mOverlayManager, never()).setEnabled(getOverlayPackageId(), enabled, 130 mUserHandle); 131 } 132 133 @Test testDefaultDisabled_applyOverlays_shouldEnabled()134 public void testDefaultDisabled_applyOverlays_shouldEnabled() throws Exception { 135 final boolean enabled = true; 136 137 assertThat(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(), 138 mUserHandle).get(0).isEnabled()).isEqualTo(!enabled); 139 140 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 141 getDisabledTargetPackageId()); 142 143 mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); 144 mLatch.await(5, TimeUnit.SECONDS); 145 146 verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, 147 mUserHandle); 148 } 149 150 @Test testDefaultEnabled_applyOverlays_shouldDisabled()151 public void testDefaultEnabled_applyOverlays_shouldDisabled() throws Exception { 152 final boolean enabled = false; 153 154 assertThat(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), 155 mUserHandle).get(0).isEnabled()).isEqualTo(!enabled); 156 157 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 158 getEnabledTargetPackageId()); 159 160 mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); 161 mLatch.await(5, TimeUnit.SECONDS); 162 163 verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, 164 mUserHandle); 165 } 166 167 @Test testDefaultEnabled_launchDocumentsUI_shouldSuccess()168 public void testDefaultEnabled_launchDocumentsUI_shouldSuccess() throws Exception { 169 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 170 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 171 172 final Activity activity = 173 InstrumentationRegistry.getInstrumentation().startActivitySync(intent); 174 175 assertThat(activity).isNotNull(); 176 177 if (activity != null) { 178 activity.finish(); 179 } 180 } 181 182 @Test testGetValidOverlay_system_valid()183 public void testGetValidOverlay_system_valid() throws Exception { 184 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 185 getEnabledTargetPackageId()); 186 187 ApplicationInfo ai = mock(ApplicationInfo.class); 188 ai.flags |= ApplicationInfo.FLAG_SYSTEM; 189 when(mPackageManager.getApplicationInfo(getOverlayPackageId(), 0)).thenReturn(ai); 190 191 assertThat(mThemeOverlayManager.getValidOverlay(mPackageManager)).isEqualTo( 192 mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), 193 mUserHandle).iterator().next()); 194 } 195 196 @Test testGetValidOverlay_data_invalid()197 public void testGetValidOverlay_data_invalid() throws Exception { 198 mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, 199 getEnabledTargetPackageId()); 200 201 ApplicationInfo ai = mock(ApplicationInfo.class); 202 String path = "/data/app/DocumentUIOverlay/DocumentUIOverlay.apk"; 203 ai.sourceDir = path; 204 when(mPackageManager.getApplicationInfo(getOverlayPackageId(), 0)).thenReturn(ai); 205 206 assertThat(mThemeOverlayManager.getValidOverlay(mPackageManager)).isEqualTo(null); 207 } 208 createOverlayInfo(String packageName, String targetPackageName, boolean enabled)209 private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName, 210 boolean enabled) { 211 return new OverlayInfo(packageName, targetPackageName, null, null, "", 212 enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false); 213 } 214 getDisabledTargetPackageId()215 private static String getDisabledTargetPackageId() { 216 return TEST_DISABLED_PREFIX + TEST_TARGET_PACKAGE; 217 } 218 getEnabledTargetPackageId()219 private static String getEnabledTargetPackageId() { 220 return TEST_ENABLED_PREFIX + TEST_TARGET_PACKAGE; 221 } 222 getOverlayPackageId()223 private static String getOverlayPackageId() { 224 return TEST_DISABLED_PREFIX + TEST_OVERLAY_PACKAGE; 225 } 226 227 } 228