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

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

Merge "Move theme setting out of tuner to display"

parents e736dc66 6324cffc
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -8161,4 +8161,11 @@
        Make <xliff:g id="app_name">%1$s</xliff:g> your autofill app? <xliff:g id="app_name">%1$s</xliff:g> will be able to read your screen and fill fields in other apps.
    </string>
    <!-- Name of setting for switching device theme [CHAR LIMIT=60] -->
    <string name="device_theme">Device theme</string>
    <!-- Name of default device theme [CHAR LIMIT=60] -->
    <string name="default_theme">Default</string>
    <!-- Temporary reboot string, will be removed -->
    <string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
</resources>
+5 −0
Original line number Diff line number Diff line
@@ -105,6 +105,11 @@
                android:title="@string/tap_to_wake"
                android:summary="@string/tap_to_wake_summary" />

        <ListPreference
                android:key="theme"
                android:title="@string/device_theme"
                android:summary="%s" />

        <Preference
                android:key="wifi_display"
                android:title="@string/wifi_display_settings_title"
+3 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.settings.display.NightDisplayPreferenceController;
import com.android.settings.display.NightModePreferenceController;
import com.android.settings.display.ScreenSaverPreferenceController;
import com.android.settings.display.TapToWakePreferenceController;
import com.android.settings.display.ThemePreferenceController;
import com.android.settings.display.TimeoutPreferenceController;
import com.android.settings.display.VrDisplayPreferenceController;
import com.android.settings.display.WallpaperPreferenceController;
@@ -92,6 +93,7 @@ public class DisplaySettings extends DashboardFragment {
        controllers.add(new TimeoutPreferenceController(context));
        controllers.add(new VrDisplayPreferenceController(context));
        controllers.add(new WallpaperPreferenceController(context));
        controllers.add(new ThemePreferenceController(context));
        return controllers;
    }

@@ -177,6 +179,7 @@ public class DisplaySettings extends DashboardFragment {
                    new TimeoutPreferenceController(context).updateNonIndexableKeys(result);
                    new VrDisplayPreferenceController(context).updateNonIndexableKeys(result);
                    new WallpaperPreferenceController(context).updateNonIndexableKeys(result);
                    new ThemePreferenceController(context).updateNonIndexableKeys(result);

                    return result;
                }
+112 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.display;

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

import android.app.AlertDialog;
import android.app.UiModeManager;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;

import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.overlay.FeatureFactory;

import libcore.util.Objects;

public class ThemePreferenceController extends PreferenceController implements
        Preference.OnPreferenceChangeListener {

    private static final String KEY_THEME = "theme";

    private final UiModeManager mUiModeManager;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

    public ThemePreferenceController(Context context) {
        super(context);
        mUiModeManager = context.getSystemService(UiModeManager.class);
        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
    }

    @Override
    public String getPreferenceKey() {
        return KEY_THEME;
    }

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (KEY_THEME.equals(preference.getKey())) {
            mMetricsFeatureProvider.action(mContext, ACTION_THEME);
        }
        return false;
    }

    @Override
    public void updateState(Preference preference) {
        ListPreference pref = (ListPreference) preference;
        String[] options = mUiModeManager.getAvailableThemes();
        for (int i = 0; i < options.length; i++) {
            options[i] = nullToDefault(options[i]);
        }
        pref.setEntries(options);
        pref.setEntryValues(options);
        String theme = mUiModeManager.getTheme();
        if (theme == null) {
            theme = mContext.getString(R.string.default_theme);
        }
        pref.setValue(nullToDefault(theme));
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (Objects.equal(newValue, mUiModeManager.getTheme())) {
            return true;
        }
        // TODO: STOPSHIP Don't require reboot and remove this prompt.
        OnClickListener onConfirm = (d, i) -> {
            mUiModeManager.setTheme(defaultToNull((String) newValue));
            ((ListPreference) preference).setValue((String) newValue);
        };
        new AlertDialog.Builder(mContext)
                .setTitle(R.string.change_theme_reboot)
                .setPositiveButton(com.android.internal.R.string.global_action_restart, onConfirm)
                .setNegativeButton(android.R.string.cancel, null)
                .show();
        return false;
    }

    @Override
    public boolean isAvailable() {
        String[] themes = mUiModeManager.getAvailableThemes();
        return themes != null && themes.length > 1;
    }

    private String nullToDefault(String input) {
        if (input == null) {
            return mContext.getString(R.string.default_theme);
        }
        return input;
    }

    private String defaultToNull(String input) {
        if (mContext.getString(R.string.default_theme).equals(input)) {
            return null;
        }
        return input;
    }
}
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.core;

import static junit.framework.TestCase.assertNotNull;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.UiModeManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.support.v7.preference.ListPreference;

import com.android.settings.R;
import com.android.settings.display.ThemePreferenceController;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class ThemePreferenceControllerTest {

    private UiModeManager mMockUiModeManager;
    private ContextWrapper mContext;
    private ThemePreferenceController mPreferenceController;

    @Before
    public void setup() {
        mMockUiModeManager = mock(UiModeManager.class);
        mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
            @Override
            public Object getSystemService(String name) {
                if (Context.UI_MODE_SERVICE.equals(name)) {
                    return mMockUiModeManager;
                }
                return super.getSystemService(name);
            }
        };
        mPreferenceController = new ThemePreferenceController(mContext);
    }

    @Test
    public void testUpdateState() {
        when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[] {
                null,
                "Theme1",
                "Theme2",
        });
        when(mMockUiModeManager.getTheme()).thenReturn("Theme1");
        ListPreference pref = mock(ListPreference.class);
        mPreferenceController.updateState(pref);
        ArgumentCaptor<String[]> arg = ArgumentCaptor.forClass(String[].class);
        verify(pref).setEntries(arg.capture());

        String[] entries = arg.getValue();
        assertEquals(3, entries.length);
        assertNotNull(entries[0]);
        assertEquals("Theme1", entries[1]);
        assertEquals("Theme2", entries[2]);

        verify(pref).setEntryValues(arg.capture());
        String[] entryValues = arg.getValue();
        assertEquals(3, entryValues.length);
        assertNotNull(entryValues[0]);
        assertEquals("Theme1", entryValues[1]);
        assertEquals("Theme2", entryValues[2]);

        verify(pref).setValue(eq("Theme1"));
    }

    @Test
    public void testAvailable_false() {
        when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[1]);
        assertFalse(mPreferenceController.isAvailable());
    }

    @Test
    public void testAvailable_true() {
        when(mMockUiModeManager.getAvailableThemes()).thenReturn(new String[2]);
        assertTrue(mPreferenceController.isAvailable());
    }
}