Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 834305e2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove OverlayManagerWrapper class out from Settings"

parents ff62b289 feae5d79
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -19,20 +19,23 @@ package com.android.settings.development;
import static android.os.UserHandle.USER_SYSTEM;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
import android.view.DisplayCutout;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.DisplayCutout;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;

import java.util.ArrayList;
import java.util.List;

public class EmulateDisplayCutoutPreferenceController extends
@@ -41,7 +44,7 @@ public class EmulateDisplayCutoutPreferenceController extends

    private static final String KEY = "display_cutout_emulation";

    private final OverlayManagerWrapper mOverlayManager;
    private final IOverlayManager mOverlayManager;
    private final boolean mAvailable;

    private ListPreference mPreference;
@@ -49,7 +52,7 @@ public class EmulateDisplayCutoutPreferenceController extends

    @VisibleForTesting
    EmulateDisplayCutoutPreferenceController(Context context, PackageManager packageManager,
            OverlayManagerWrapper overlayManager) {
            IOverlayManager overlayManager) {
        super(context);
        mOverlayManager = overlayManager;
        mPackageManager = packageManager;
@@ -57,7 +60,8 @@ public class EmulateDisplayCutoutPreferenceController extends
    }

    public EmulateDisplayCutoutPreferenceController(Context context) {
        this(context, context.getPackageManager(), new OverlayManagerWrapper());
        this(context, context.getPackageManager(), IOverlayManager.Stub
                .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    @Override
@@ -102,11 +106,15 @@ public class EmulateDisplayCutoutPreferenceController extends
        }

        final boolean result;
        try {
            if (TextUtils.isEmpty(packageName)) {
                result = mOverlayManager.setEnabled(currentPackageName, false, USER_SYSTEM);
            } else {
                result = mOverlayManager.setEnabledExclusiveInCategory(packageName, USER_SYSTEM);
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        updateState(mPreference);
        return result;
    }
@@ -145,14 +153,18 @@ public class EmulateDisplayCutoutPreferenceController extends
    }

    private OverlayInfo[] getOverlayInfos() {
        @SuppressWarnings("unchecked") List<OverlayInfo> overlayInfos =
                mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
        List<OverlayInfo> overlayInfos;
        try {
            overlayInfos = mOverlayManager.getOverlayInfosForTarget("android", USER_SYSTEM);
            for (int i = overlayInfos.size() - 1; i >= 0; i--) {
                if (!DisplayCutout.EMULATION_OVERLAY_CATEGORY.equals(
                        overlayInfos.get(i).category)) {
                    overlayInfos.remove(i);
                }
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return overlayInfos.toArray(new OverlayInfo[overlayInfos.size()]);
    }

+42 −33
Original line number Diff line number Diff line
@@ -13,23 +13,22 @@
 */
package com.android.settings.display;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import android.text.TextUtils;

import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;

@@ -37,7 +36,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_THEME;
import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;

public class ThemePreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -45,16 +46,16 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
    private static final String KEY_THEME = "theme";

    private final MetricsFeatureProvider mMetricsFeatureProvider;
    private final OverlayManagerWrapper mOverlayService;
    private final IOverlayManager mOverlayService;
    private final PackageManager mPackageManager;

    public ThemePreferenceController(Context context) {
        this(context, ServiceManager.getService(Context.OVERLAY_SERVICE) != null
                ? new OverlayManagerWrapper() : null);
        this(context, IOverlayManager.Stub
                .asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    @VisibleForTesting
    ThemePreferenceController(Context context, OverlayManagerWrapper overlayManager) {
    ThemePreferenceController(Context context, IOverlayManager overlayManager) {
        super(context);
        mOverlayService = overlayManager;
        mPackageManager = context.getPackageManager();
@@ -77,7 +78,7 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
    @Override
    public void updateState(Preference preference) {
        ListPreference pref = (ListPreference) preference;
        String[] pkgs = getAvailableThemes();
        String[] pkgs = getAvailableThemes(false /* currentThemeOnly */);
        CharSequence[] labels = new CharSequence[pkgs.length];
        for (int i = 0; i < pkgs.length; i++) {
            try {
@@ -109,11 +110,15 @@ public class ThemePreferenceController extends AbstractPreferenceController impl

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        String current = getTheme();
        String current = getCurrentTheme();
        if (Objects.equals(newValue, current)) {
            return true;
        }
        try {
            mOverlayService.setEnabledExclusiveInCategory((String) newValue, UserHandle.myUserId());
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return true;
    }

@@ -129,40 +134,44 @@ public class ThemePreferenceController extends AbstractPreferenceController impl
        }
    }

    private String getTheme() {
        List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
                UserHandle.myUserId());
        for (int i = 0, size = infos.size(); i < size; i++) {
            if (infos.get(i).isEnabled() && isTheme(infos.get(i))) {
                return infos.get(i).packageName;
            }
        }
        return null;
    }

    @Override
    public boolean isAvailable() {
        if (mOverlayService == null) return false;
        String[] themes = getAvailableThemes();
        String[] themes = getAvailableThemes(false /* currentThemeOnly */);
        return themes != null && themes.length > 1;
    }


    @VisibleForTesting
    String getCurrentTheme() {
        return getTheme();
        String[] themePackages = getAvailableThemes(true /* currentThemeOnly */);
        return themePackages.length < 1 ? null : themePackages[0];
    }

    @VisibleForTesting
    String[] getAvailableThemes() {
        List<OverlayInfo> infos = mOverlayService.getOverlayInfosForTarget("android",
                UserHandle.myUserId());
        List<String> pkgs = new ArrayList<>(infos.size());
    String[] getAvailableThemes(boolean currentThemeOnly) {
        List<OverlayInfo> infos;
        List<String> pkgs;
        try {
            infos = mOverlayService.getOverlayInfosForTarget("android", UserHandle.myUserId());
            pkgs = new ArrayList<>(infos.size());
            for (int i = 0, size = infos.size(); i < size; i++) {
                if (isTheme(infos.get(i))) {
                    if (infos.get(i).isEnabled() && currentThemeOnly) {
                        return new String[] {infos.get(i).packageName};
                    } else {
                        pkgs.add(infos.get(i).packageName);
                    }
                }
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }

        // Current enabled theme is not found.
        if (currentThemeOnly) {
            return new String[0];
        }
        return pkgs.toArray(new String[pkgs.size()]);
    }
}
+0 −102
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.settings.wrapper;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.os.RemoteException;
import android.os.ServiceManager;

import java.util.ArrayList;
import java.util.List;

public class OverlayManagerWrapper {

    private final IOverlayManager mOverlayManager;

    public OverlayManagerWrapper(IOverlayManager overlayManager) {
        mOverlayManager = overlayManager;
    }

    public OverlayManagerWrapper() {
        this(IOverlayManager.Stub.asInterface(ServiceManager.getService(Context.OVERLAY_SERVICE)));
    }

    public List<OverlayInfo> getOverlayInfosForTarget(String overlay, int userId) {
        if (mOverlayManager == null) {
            return new ArrayList<>();
        }
        try {
            List<android.content.om.OverlayInfo> infos
                    = mOverlayManager.getOverlayInfosForTarget(overlay, userId);
            ArrayList<OverlayInfo> result = new ArrayList<>(infos.size());
            for (int i = 0; i < infos.size(); i++) {
                result.add(new OverlayInfo(infos.get(i)));
            }
            return result;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public boolean setEnabled(String overlay, boolean enabled, int userId) {
        if (mOverlayManager == null) {
            return false;
        }
        try {
            return mOverlayManager.setEnabled(overlay, enabled, userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public boolean setEnabledExclusiveInCategory(String overlay, int userId) {
        if (mOverlayManager == null) {
            return false;
        }
        try {
            return mOverlayManager.setEnabledExclusiveInCategory(overlay, userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    public static class OverlayInfo {

        public static final String CATEGORY_THEME = android.content.om.OverlayInfo.CATEGORY_THEME;
        public final String packageName;
        public final String category;
        private final boolean mEnabled;

        public OverlayInfo(String packageName, String category, boolean enabled) {
            this.packageName = packageName;
            this.category = category;
            mEnabled = enabled;
        }

        public OverlayInfo(android.content.om.OverlayInfo info) {
            mEnabled = info.isEnabled();
            category = info.category;
            packageName = info.packageName;
        }

        public boolean isEnabled() {
            return mEnabled;
        }
    }
}
+22 −6
Original line number Diff line number Diff line
@@ -26,14 +26,15 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceScreen;
import android.view.DisplayCutout;

import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.OverlayManagerWrapper;
import com.android.settings.wrapper.OverlayManagerWrapper.OverlayInfo;

import org.junit.Before;
import org.junit.Test;
@@ -41,6 +42,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Arrays;

@RunWith(SettingsRobolectricTestRunner.class)
@@ -54,7 +56,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    @Mock
    private Context mContext;
    @Mock
    private OverlayManagerWrapper mOverlayManager;
    private IOverlayManager mOverlayManager;
    @Mock
    private PackageManager mPackageManager;
    @Mock
@@ -64,6 +66,7 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
        mockCurrentOverlays();
        when(mPackageManager.getApplicationInfo(any(), anyInt()))
            .thenThrow(PackageManager.NameNotFoundException.class);
@@ -72,8 +75,12 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    }

    Object mockCurrentOverlays(OverlayInfo... overlays) {
        try {
            return when(mOverlayManager.getOverlayInfosForTarget(eq("android"), anyInt()))
                .thenReturn(Arrays.asList(overlays));
        } catch (RemoteException re) {
            return new ArrayList<OverlayInfo>();
        }
    }

    @Test
@@ -146,6 +153,15 @@ public class EmulateDisplayCutoutPreferenceControllerTest {
    }

    private static OverlayInfo createFakeOverlay(String pkg, boolean enabled) {
        return new OverlayInfo(pkg, DisplayCutout.EMULATION_OVERLAY_CATEGORY, enabled);
        final int state = (enabled) ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED;

        return new OverlayInfo(pkg /* packageName */,
                pkg + ".target" /* targetPackageName */,
                DisplayCutout.EMULATION_OVERLAY_CATEGORY /* category */,
                pkg + ".baseCodePath" /* baseCodePath */,
                state /* state */,
                0 /* userId */,
                0 /* priority */,
                true /* isStatic */);
    }
}
 No newline at end of file
+62 −7
Original line number Diff line number Diff line
@@ -16,25 +16,26 @@

package com.android.settings.display;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import androidx.preference.ListPreference;

import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.OverlayManagerWrapper;

import org.junit.Before;
import org.junit.Test;
@@ -44,6 +45,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;

import java.util.Arrays;

import androidx.preference.ListPreference;

@RunWith(SettingsRobolectricTestRunner.class)
public class ThemePreferenceControllerTest {

@@ -55,6 +60,8 @@ public class ThemePreferenceControllerTest {
    private ApplicationInfo mApplicationInfo;
    @Mock
    private ListPreference mPreference;
    @Mock
    private IOverlayManager mOverlayManager;

    private ThemePreferenceController mController;

@@ -67,8 +74,28 @@ public class ThemePreferenceControllerTest {
        when(mContext.getString(R.string.default_theme))
                .thenReturn(RuntimeEnvironment.application.getString(R.string.default_theme));

        mController =
            spy(new ThemePreferenceController(mContext, mock(OverlayManagerWrapper.class)));
        when(mContext.getSystemService(Context.OVERLAY_SERVICE)).thenReturn(mOverlayManager);
        mController = spy(new ThemePreferenceController(mContext, mOverlayManager));
    }

    @Test
    public void testAvailable_false() throws Exception {
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
                .thenReturn(Arrays.asList(new OverlayInfo("", "", "", "", 0, 0, 0, false)));
        assertThat(mController.isAvailable()).isFalse();
    }

    @Test
    public void testAvailable_true() throws Exception {
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
                .thenReturn(Arrays.asList(
                        new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true),
                        new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true)));
        assertThat(mController.isAvailable()).isTrue();
    }

    @Test
@@ -79,7 +106,7 @@ public class ThemePreferenceControllerTest {
        final String themeLabel2 = "Theme2";
        final String[] themes = {pkg1, pkg2};
        doReturn("pkg1.theme1").when(mController).getCurrentTheme();
        doReturn(themes).when(mController).getAvailableThemes();
        doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
        when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
                .thenReturn(themeLabel1)
                .thenReturn(themeLabel2);
@@ -98,7 +125,7 @@ public class ThemePreferenceControllerTest {
        final String themeLabel2 = "Theme2";
        final String[] themes = {pkg1, pkg2};
        doReturn(null).when(mController).getCurrentTheme();
        doReturn(themes).when(mController).getAvailableThemes();
        doReturn(themes).when(mController).getAvailableThemes(false /* currentThemeOnly */);
        when(mPackageManager.getApplicationInfo(anyString(), anyInt()).loadLabel(mPackageManager))
                .thenReturn(themeLabel1)
                .thenReturn(themeLabel2);
@@ -109,4 +136,32 @@ public class ThemePreferenceControllerTest {
                .setSummary(RuntimeEnvironment.application.getString(R.string.default_theme));
        verify(mPreference).setValue(null);
    }

    @Test
    public void getCurrentTheme_withEnabledState() throws Exception {
        OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
                OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
        OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
                OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
                Arrays.asList(info1, info2));
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());

        assertThat(mController.getCurrentTheme()).isEqualTo(info1.packageName);
    }

    @Test
    public void testGetCurrentTheme_withoutEnabledState() throws Exception {
        OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
                OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_DISABLED, 0, 0, true);
        OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
                OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
        when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
                Arrays.asList(info1, info2));
        when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
                new PackageInfo());

        assertThat(mController.getCurrentTheme()).isNull();
    }
}
Loading