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