| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.documentsui; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import android.app.Activity; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.om.OverlayInfo; |
| import android.content.om.OverlayManager; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.PackageManager; |
| import android.os.UserHandle; |
| |
| import androidx.core.util.Consumer; |
| import androidx.test.filters.SmallTest; |
| import androidx.test.platform.app.InstrumentationRegistry; |
| import androidx.test.runner.AndroidJUnit4; |
| |
| import com.android.documentsui.theme.ThemeOverlayManager; |
| |
| import com.google.common.collect.Lists; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| @SmallTest |
| @RunWith(AndroidJUnit4.class) |
| public class ThemeOverlayManagerTest { |
| private static final String TEST_DISABLED_PREFIX = "com.example."; |
| private static final String TEST_ENABLED_PREFIX = "com.example.enabled."; |
| private static final String TEST_OVERLAY_PACKAGE = "test.overlay"; |
| private static final String TEST_TARGET_PACKAGE = "test.target"; |
| |
| @Mock |
| OverlayManager mOverlayManager; |
| |
| @Mock |
| PackageManager mPackageManager; |
| |
| Consumer<Boolean> mCallback; |
| Context mContext; |
| CountDownLatch mLatch; |
| ThemeOverlayManager mThemeOverlayManager; |
| UserHandle mUserHandle; |
| |
| @Before |
| public void setUp() throws Exception { |
| InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( |
| "android.permission.CHANGE_OVERLAY_PACKAGES"); |
| |
| MockitoAnnotations.initMocks(this); |
| mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); |
| mLatch = new CountDownLatch(1); |
| mUserHandle = UserHandle.of(UserHandle.myUserId()); |
| mCallback = result -> mLatch.countDown(); |
| |
| when(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), |
| mUserHandle)).thenReturn(Lists.newArrayList( |
| createOverlayInfo(getOverlayPackageId(), getEnabledTargetPackageId(), true))); |
| |
| when(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(), |
| mUserHandle)).thenReturn(Lists.newArrayList( |
| createOverlayInfo(getOverlayPackageId(), getDisabledTargetPackageId(), false))); |
| } |
| |
| @Test |
| public void testApplyOverlays_shouldSetEnabled() throws Exception { |
| final boolean enabled = true; |
| |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getDisabledTargetPackageId()); |
| |
| mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); |
| mLatch.await(5, TimeUnit.SECONDS); |
| |
| verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, |
| mUserHandle); |
| } |
| |
| @Test |
| public void testApplyOverlays_shouldGetOverlayInfo() throws Exception { |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getEnabledTargetPackageId()); |
| |
| mThemeOverlayManager.applyOverlays(mContext, true /* enabled */, mCallback); |
| mLatch.await(5, TimeUnit.SECONDS); |
| |
| verify(mOverlayManager, times(1)).getOverlayInfosForTarget(getEnabledTargetPackageId(), |
| mUserHandle); |
| } |
| |
| @Test |
| public void testApplyOverlays_shouldCheckEnabled_beforeSetEnabled() { |
| final boolean enabled = true; |
| |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getEnabledTargetPackageId()); |
| |
| mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); |
| |
| verify(mOverlayManager, never()).setEnabled(getOverlayPackageId(), enabled, |
| mUserHandle); |
| } |
| |
| @Test |
| public void testDefaultDisabled_applyOverlays_shouldEnabled() throws Exception { |
| final boolean enabled = true; |
| |
| assertThat(mOverlayManager.getOverlayInfosForTarget(getDisabledTargetPackageId(), |
| mUserHandle).get(0).isEnabled()).isEqualTo(!enabled); |
| |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getDisabledTargetPackageId()); |
| |
| mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); |
| mLatch.await(5, TimeUnit.SECONDS); |
| |
| verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, |
| mUserHandle); |
| } |
| |
| @Test |
| public void testDefaultEnabled_applyOverlays_shouldDisabled() throws Exception { |
| final boolean enabled = false; |
| |
| assertThat(mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), |
| mUserHandle).get(0).isEnabled()).isEqualTo(!enabled); |
| |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getEnabledTargetPackageId()); |
| |
| mThemeOverlayManager.applyOverlays(mContext, enabled, mCallback); |
| mLatch.await(5, TimeUnit.SECONDS); |
| |
| verify(mOverlayManager, times(1)).setEnabled(getOverlayPackageId(), enabled, |
| mUserHandle); |
| } |
| |
| @Test |
| public void testDefaultEnabled_launchDocumentsUI_shouldSuccess() throws Exception { |
| final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); |
| intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| |
| final Activity activity = |
| InstrumentationRegistry.getInstrumentation().startActivitySync(intent); |
| |
| assertThat(activity).isNotNull(); |
| |
| if (activity != null) { |
| activity.finish(); |
| } |
| } |
| |
| @Test |
| public void testGetValidOverlay_system_valid() throws Exception { |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getEnabledTargetPackageId()); |
| |
| ApplicationInfo ai = mock(ApplicationInfo.class); |
| ai.flags |= ApplicationInfo.FLAG_SYSTEM; |
| when(mPackageManager.getApplicationInfo(getOverlayPackageId(), 0)).thenReturn(ai); |
| |
| assertThat(mThemeOverlayManager.getValidOverlay(mPackageManager)).isEqualTo( |
| mOverlayManager.getOverlayInfosForTarget(getEnabledTargetPackageId(), |
| mUserHandle).iterator().next()); |
| } |
| |
| @Test |
| public void testGetValidOverlay_data_invalid() throws Exception { |
| mThemeOverlayManager = new ThemeOverlayManager(mOverlayManager, |
| getEnabledTargetPackageId()); |
| |
| ApplicationInfo ai = mock(ApplicationInfo.class); |
| String path = "/data/app/DocumentUIOverlay/DocumentUIOverlay.apk"; |
| ai.sourceDir = path; |
| when(mPackageManager.getApplicationInfo(getOverlayPackageId(), 0)).thenReturn(ai); |
| |
| assertThat(mThemeOverlayManager.getValidOverlay(mPackageManager)).isEqualTo(null); |
| } |
| |
| private static OverlayInfo createOverlayInfo(String packageName, String targetPackageName, |
| boolean enabled) { |
| return new OverlayInfo(packageName, targetPackageName, null, null, "", |
| enabled ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED, 0, 0, false); |
| } |
| |
| private static String getDisabledTargetPackageId() { |
| return TEST_DISABLED_PREFIX + TEST_TARGET_PACKAGE; |
| } |
| |
| private static String getEnabledTargetPackageId() { |
| return TEST_ENABLED_PREFIX + TEST_TARGET_PACKAGE; |
| } |
| |
| private static String getOverlayPackageId() { |
| return TEST_DISABLED_PREFIX + TEST_OVERLAY_PACKAGE; |
| } |
| |
| } |