From 3da78002775540f9ede8460de48a492d2e72cf21 Mon Sep 17 00:00:00 2001 From: Andy CrossGate Yan Date: Thu, 22 Sep 2022 12:37:50 +0000 Subject: [PATCH 1/5] TrebleSettings: Screen resolution & refresh rate Change-Id: I4a4679cdb6d4ede55479e9ab2f014342025b0fec --- AndroidManifest.xml | 8 + res/drawable/ic_settings_treble.xml | 10 ++ res/values/menu_keys.xml | 1 + res/values/strings.xml | 10 ++ res/xml/top_level_settings.xml | 9 + res/xml/treble_settings.xml | 18 ++ ...lutionRefreshRatePreferenceController.java | 169 ++++++++++++++++++ .../settings/treble/TrebleSettings.java | 39 ++++ 8 files changed, 264 insertions(+) create mode 100644 res/drawable/ic_settings_treble.xml create mode 100644 res/xml/treble_settings.xml create mode 100644 src/com/android/settings/treble/ScreenResolutionRefreshRatePreferenceController.java create mode 100644 src/com/android/settings/treble/TrebleSettings.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c4fba3defc..92203f3dab 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -221,6 +221,14 @@ android:value="com.android.settings.shortcut.CreateShortcut" /> + + + + + + + + diff --git a/res/values/menu_keys.xml b/res/values/menu_keys.xml index 2841b699c9..c30d6392e9 100755 --- a/res/values/menu_keys.xml +++ b/res/values/menu_keys.xml @@ -16,6 +16,7 @@ + top_level_treble top_level_network top_level_connected_devices top_level_apps diff --git a/res/values/strings.xml b/res/values/strings.xml index bbdefd1427..07ee32662e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8458,6 +8458,16 @@ Show %d hidden items + + Treble settings + + Fixes & tweaks for GSIs + + Display + + + Screen resolution & refresh rate + Network & internet diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml index 5fbc7350b8..c63b2114ec 100644 --- a/res/xml/top_level_settings.xml +++ b/res/xml/top_level_settings.xml @@ -20,6 +20,15 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="top_level_settings"> + + + + + + + + + + + + diff --git a/src/com/android/settings/treble/ScreenResolutionRefreshRatePreferenceController.java b/src/com/android/settings/treble/ScreenResolutionRefreshRatePreferenceController.java new file mode 100644 index 0000000000..5d14f13209 --- /dev/null +++ b/src/com/android/settings/treble/ScreenResolutionRefreshRatePreferenceController.java @@ -0,0 +1,169 @@ +package com.android.settings.treble; + +import static android.content.Intent.ACTION_BOOT_COMPLETED; + +import android.app.ActivityManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.os.Parcel; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.view.SurfaceControl; +import android.view.SurfaceControl.DisplayMode; + +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ScreenResolutionRefreshRatePreferenceController extends BasePreferenceController + implements Preference.OnPreferenceChangeListener { + + private static final String SCREEN_RESOLUTION_REFRESH_RATE_KEY = "screen_resolution_refresh_rate"; + private static final String SURFACE_FLINGER_SERVICE_KEY = "SurfaceFlinger"; + private static final String SURFACE_COMPOSER_INTERFACE_KEY = "android.ui.ISurfaceComposer"; + private static final int SURFACE_FLINGER_CODE = 1035; + private static final String TREBLE_DISPLAY_MODE_PROPERTY = "persist.sys.treble.display_mode"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + + private ActivityManager mAm; + private ListPreference mListPreference; + private List mModes = new ArrayList<>(); + private List mEntries = new ArrayList<>(); + private List mValues = new ArrayList<>(); + + public ScreenResolutionRefreshRatePreferenceController(Context context) { + super(context, SCREEN_RESOLUTION_REFRESH_RATE_KEY); + + mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + + DisplayMode[] supportedDisplayModes = + SurfaceControl.getDynamicDisplayInfo(SurfaceControl.getInternalDisplayToken()).supportedDisplayModes; + Set summarySet = new HashSet<>(); + for (DisplayMode m : supportedDisplayModes) { + String summary = String.format("%dx%d @ %dHz", m.width, m.height, Math.round(m.refreshRate)); + if (!summarySet.contains(summary)) { + summarySet.add(summary); + mModes.add(m); + } + } + Collections.sort(mModes, Comparator.comparing((DisplayMode m)->m.width) + .thenComparing(m->m.height) + .thenComparing(m->m.refreshRate) + .thenComparing(m->m.id)); + for (DisplayMode m : mModes) { + String summary = String.format("%dx%d @ %dHz", m.width, m.height, Math.round(m.refreshRate)); + mEntries.add(summary); + mValues.add(String.valueOf(m.id)); + } + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public String getPreferenceKey() { + return SCREEN_RESOLUTION_REFRESH_RATE_KEY; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + mListPreference = screen.findPreference(getPreferenceKey()); + mListPreference.setEntries(mEntries.toArray(new String[mEntries.size()])); + mListPreference.setEntryValues(mValues.toArray(new String[mValues.size()])); + + if (mEntries.size() <= 1) { + mListPreference.setEnabled(false); + } + + super.displayPreference(screen); + } + + @Override + public void updateState(Preference preference) { + int id = SurfaceControl.getDynamicDisplayInfo(SurfaceControl.getInternalDisplayToken()).activeDisplayModeId; + int index = mListPreference.findIndexOfValue(String.valueOf(id)); + mListPreference.setValueIndex(index); + mListPreference.setSummary(mListPreference.getEntries()[index]); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + DisplayMode currentMode = getCurrentMode(); + int id = Integer.valueOf((String) newValue); + DisplayMode newMode = getModeById(id); + setModeFromBackdoor(id); + SystemProperties.set(TREBLE_DISPLAY_MODE_PROPERTY, (String) newValue); + int index = mListPreference.findIndexOfValue((String) newValue); + mListPreference.setValueIndex(index); + mListPreference.setSummary(mListPreference.getEntries()[index]); + if ((newMode.width != currentMode.width) || (newMode.height != currentMode.height)) { + try { + for (ActivityManager.RunningAppProcessInfo app: mAm.getRunningAppProcesses()) { + if (app.processName.equals(SYSTEMUI_PACKAGE_NAME)) { + ActivityManager.getService().killApplicationProcess(app.processName, app.uid); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return true; + } + + private DisplayMode getCurrentMode() { + int id = SurfaceControl.getDynamicDisplayInfo(SurfaceControl.getInternalDisplayToken()).activeDisplayModeId; + return getModeById(id); + } + + private DisplayMode getModeById(int id) { + for (DisplayMode m : mModes) { + if (m.id == id) { + return m; + } + } + return null; + } + + public static void setModeFromBackdoor(int id) { + IBinder surfaceFlinger = ServiceManager.getService(SURFACE_FLINGER_SERVICE_KEY); + try { + if (surfaceFlinger != null) { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(SURFACE_COMPOSER_INTERFACE_KEY); + data.writeInt(id); + surfaceFlinger.transact(SURFACE_FLINGER_CODE, data, null, 0); + data.recycle(); + } + } catch (RemoteException ex) {} + } + + public static class BootReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_BOOT_COMPLETED.equals(intent.getAction())) { + int id = SystemProperties.getInt(TREBLE_DISPLAY_MODE_PROPERTY, -1); + if (id != -1) { + setModeFromBackdoor(id); + } + } + } + + } + +} diff --git a/src/com/android/settings/treble/TrebleSettings.java b/src/com/android/settings/treble/TrebleSettings.java new file mode 100644 index 0000000000..e581539229 --- /dev/null +++ b/src/com/android/settings/treble/TrebleSettings.java @@ -0,0 +1,39 @@ +package com.android.settings.treble; + +import android.app.settings.SettingsEnums; +import android.content.Context; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.ArrayList; +import java.util.List; + +public class TrebleSettings extends DashboardFragment { + + private static final String TAG = "TrebleSettings"; + + @Override + protected int getPreferenceScreenResId() { + return R.xml.treble_settings; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.SETTINGS_TREBLE_CATEGORY; + } + + @Override + protected List createPreferenceControllers(Context context) { + final List controllers = new ArrayList<>(); + controllers.add(new ScreenResolutionRefreshRatePreferenceController(context)); + return controllers; + } + +} -- 2.25.1