From 97a06a12ed29fb72eb40d49b83333a9a6327222c Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Wed, 9 Nov 2016 15:53:30 -0500 Subject: [PATCH] Add switchable theme to tuner Allows option in tuner to switch between system theme overlays if multiple exist. Requires a restart to take effect. Test: Settings -> Tuner -> Other -> Theme Change-Id: Iea43b9cbb67fd91c6008be594ad4cfd19c3f57ec --- core/java/android/app/IUiModeManager.aidl | 10 +++ core/java/android/app/UiModeManager.java | 29 +++++++ core/res/AndroidManifest.xml | 6 ++ packages/SystemUI/AndroidManifest.xml | 2 + packages/SystemUI/res/values/strings.xml | 7 ++ packages/SystemUI/res/xml/other_settings.xml | 7 +- .../android/systemui/SystemUIApplication.java | 2 +- .../systemui/tuner/ThemePreference.java | 77 +++++++++++++++++++ .../android/server/UiModeManagerService.java | 29 +++++++ 9 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl index cae54b6c0611f..848464cf3823c 100644 --- a/core/java/android/app/IUiModeManager.aidl +++ b/core/java/android/app/IUiModeManager.aidl @@ -52,6 +52,16 @@ interface IUiModeManager { */ int getNightMode(); + /** + * Sets whith theme overlays to use within /vendor/overlay. + */ + void setTheme(String theme); + + /** + * Gets whith theme overlays to use within /vendor/overlay. + */ + String getTheme(); + /** * Tells if UI mode is locked or not. */ diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index 0046b0e4a8bf7..2e2172919dbc4 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -240,6 +240,35 @@ public class UiModeManager { } } + /** + * Sets the vendor theme overlay property, then triggers a reboot. + * @hide + */ + public void setTheme(String theme) { + if (mService != null) { + try { + mService.setTheme(theme); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Gets the vendor theme overlay property. + * @hide + */ + public String getTheme() { + if (mService != null) { + try { + return mService.getTheme(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return null; + } + /** * Returns the currently configured night mode. *

diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 3dea051afb4e4..0f7b5a53e33c7 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3130,6 +3130,12 @@ + + + + + Allow PIP to minimize slightly offscreen + + Changing the theme requires a restart. + + Theme + + Default + diff --git a/packages/SystemUI/res/xml/other_settings.xml b/packages/SystemUI/res/xml/other_settings.xml index ce636cdaf4fb5..18cb9306b1b66 100644 --- a/packages/SystemUI/res/xml/other_settings.xml +++ b/packages/SystemUI/res/xml/other_settings.xml @@ -23,5 +23,10 @@ android:key="power_notification_controls" android:title="@string/tuner_full_importance_settings" android:fragment="com.android.systemui.tuner.PowerNotificationControlsFragment"/> +e + - \ No newline at end of file + diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 99e787676ef59..8292f85d9b31b 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -32,6 +32,7 @@ import android.util.Log; import com.android.systemui.keyboard.KeyboardUI; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.media.RingtonePlayer; +import com.android.systemui.pip.PipUI; import com.android.systemui.plugins.OverlayPlugin; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.PluginManager; @@ -42,7 +43,6 @@ import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.SystemBars; import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.tuner.TunerService; -import com.android.systemui.pip.PipUI; import com.android.systemui.usb.StorageNotification; import com.android.systemui.volume.VolumeUI; diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java new file mode 100644 index 0000000000000..e5bb3d5d88f38 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 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.systemui.tuner; + +import android.app.AlertDialog; +import android.app.UiModeManager; +import android.content.Context; +import android.os.SystemProperties; +import android.support.v7.preference.ListPreference; +import android.text.TextUtils; +import android.util.AttributeSet; + +import com.android.systemui.R; + +import libcore.util.Objects; + +import com.google.android.collect.Lists; + +import java.io.File; +import java.util.ArrayList; + +public class ThemePreference extends ListPreference { + + public ThemePreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void onAttached() { + super.onAttached(); + File file = new File("/vendor/overlay"); + ArrayList options = Lists.newArrayList(file.list()); + String def = SystemProperties.get("ro.boot.vendor.overlay.theme"); + if (TextUtils.isEmpty(def)) { + def = getContext().getString(R.string.default_theme); + } + if (!options.contains(def)) { + options.add(0, def); + } + String[] list = options.toArray(new String[options.size()]); + setVisible(options.size() > 1); + setEntries(list); + setEntryValues(list); + updateValue(); + } + + private void updateValue() { + setValue(getContext().getSystemService(UiModeManager.class).getTheme()); + } + + @Override + protected void notifyChanged() { + super.notifyChanged(); + if (!Objects.equal(getValue(), + getContext().getSystemService(UiModeManager.class).getTheme())) { + new AlertDialog.Builder(getContext()) + .setTitle(R.string.change_theme_reboot) + .setPositiveButton(com.android.internal.R.string.global_action_restart, (d, i) + -> getContext().getSystemService(UiModeManager.class) + .setTheme(getValue())) + .setNegativeButton(android.R.string.cancel, (d, i) -> updateValue()) + .show(); + } + } +} diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 2825cf9d867b4..6268697185809 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -39,19 +39,24 @@ import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.RemoteException; +import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.service.dreams.Sandman; import android.util.Slog; +import android.view.WindowManagerInternal; +import android.view.WindowManagerPolicy; import java.io.FileDescriptor; import java.io.PrintWriter; import com.android.internal.R; import com.android.internal.app.DisableCarModeActivity; +import com.android.server.power.ShutdownThread; import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; import com.android.server.twilight.TwilightState; +import com.android.server.wm.WindowManagerService; final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); @@ -296,6 +301,30 @@ final class UiModeManagerService extends SystemService { } } + @Override + public void setTheme(String theme) { + if (getContext().checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_THEME_OVERLAY) + != PackageManager.PERMISSION_GRANTED) { + Slog.e(TAG, "setTheme requires MODIFY_THEME_OVERLAY permission"); + return; + } + SystemProperties.set("persist.vendor.overlay.theme", theme); + mHandler.post(() -> ShutdownThread.reboot(getContext(), + PowerManager.SHUTDOWN_USER_REQUESTED, false)); + } + + @Override + public String getTheme() { + if (getContext().checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_THEME_OVERLAY) + != PackageManager.PERMISSION_GRANTED) { + Slog.e(TAG, "setTheme requires MODIFY_THEME_OVERLAY permission"); + return null; + } + return SystemProperties.get("persist.vendor.overlay.theme"); + } + @Override public int getNightMode() { synchronized (mLock) {