Settings: Implement RefreshRateManager [SQUASHED] [2/2]
Includes: - Per-app refresh rate config - Extreme refresh rate (Force all apps to run in maximum refresh rate) - Temp refresh rate allowed (Used in MEMC) - Refresh rate QS tile Change-Id: I30024eb8ce63f00a6f2fa1ea0230b004ff93ac74 Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Create BasePerAppConfigFragment * Allow more preference types instead of only ListPreference. Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Create PerAppSwitchConfigFragment Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Add top info for per-app settings Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Don't show system apps for sensor block fragment Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Pass uid in per-app config fragment Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Allow specific allowed system app list for per-app fragment * We need to allow dialer/messages/contact for fullscreen display settings. Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Make sure per-app list has no duplicates Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Warn user app reload before switching fullscreen display Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Adapt for Android U QPR2 Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> Settings: Use ArrayMap/Set instead of HashMap/Set Signed-off-by: cjh1249131356 <cjh1249131356@gmail.com> [joeyhuab: Squashed all changes by same author] Settings: Add null check for PreferenceScreen in BasePerAppConfigFragment Co-authored-by: NurKeinNeid <nurkeinneid@derpfest.org> Signed-off-by: NurKeinNeid <nurkeinneid@derpfest.org>
This commit is contained in:
@@ -5802,6 +5802,17 @@
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Screen refresh rate -->
|
||||
<activity android:name="Settings$ScreenRefreshRateActivity"
|
||||
android:label="@string/screen_refresh_rate_title"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="org.evolution.settings.display.refreshrate.ScreenRefreshRateFragment"/>
|
||||
</activity>
|
||||
|
||||
<!-- App lock -->
|
||||
<activity android:name=".security.applock.AppLockCredentialActivity"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
-keep public class com.android.settings*.** extends androidx.fragment.app.Fragment {
|
||||
void <init>();
|
||||
}
|
||||
-keep class org.evolution.settings.**
|
||||
-keep,allowoptimization,allowaccessmodification class org.evolution.settings.** { *; }
|
||||
|
||||
# Keep all preference controllers needed by slice and DashboardFragment.
|
||||
-keep class * extends com.android.settings.core.BasePreferenceController {
|
||||
|
||||
@@ -408,4 +408,25 @@
|
||||
<!-- Pulse on music track change -->
|
||||
<string name="pulse_on_new_tracks_title">Music ticker</string>
|
||||
<string name="pulse_on_new_tracks_summary">Show Ambient Display when a new music track is played</string>
|
||||
|
||||
<!-- Per-app configs -->
|
||||
<string name="per_app_config_empty_text">No installed apps support current settings</string>
|
||||
|
||||
<!-- Per-app refresh rate -->
|
||||
<string name="per_app_refresh_rate_title">Per-app refresh rate config</string>
|
||||
<string name="per_app_refresh_rate_summary">Configure refresh rate individually for each apps</string>
|
||||
<string name="per_app_refresh_rate_default">Follow system</string>
|
||||
|
||||
<!-- Screen refresh rate -->
|
||||
<string name="screen_refresh_rate_title">Screen refresh rate</string>
|
||||
<string name="min_refresh_rate_title">Minimum refresh rate</string>
|
||||
<string name="max_refresh_rate_title">Maximum refresh rate</string>
|
||||
|
||||
<!-- Extreme refresh rate -->
|
||||
<string name="extreme_refresh_rate_title">Extreme refresh rate</string>
|
||||
<string name="extreme_refresh_rate_summary">Force highest refresh rate for all apps</string>
|
||||
<string name="extreme_refresh_rate_warning">This will ensure system select highest refresh rate, ignoring user selected and app preferred options. Apps that require specific refresh rate may run abnormally.</string>
|
||||
|
||||
<!-- Confirm dialog -->
|
||||
<string name="confirm_before_enable_title">Continue to enable?</string>
|
||||
</resources>
|
||||
|
||||
@@ -77,4 +77,18 @@
|
||||
|
||||
<!-- Device specific doze package -->
|
||||
<string name="config_customDozePackage" translatable="false"></string>
|
||||
|
||||
<!-- List of system apps that are allowed to configure per-app settings -->
|
||||
<string-array name="config_perAppConfAllowedSystemApps" translatable="false">
|
||||
<item>com.android.chrome</item>
|
||||
<item>com.android.vending</item>
|
||||
<item>com.oneplus.gallery</item>
|
||||
<item>com.google.android.apps.docs</item>
|
||||
<item>com.google.android.apps.nbu.files</item>
|
||||
<item>com.google.android.apps.photos</item>
|
||||
<item>com.google.android.apps.recorder</item>
|
||||
<item>com.google.android.calculator</item>
|
||||
<item>com.google.android.calendar</item>
|
||||
<item>com.google.android.gm</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
@@ -181,6 +181,12 @@
|
||||
settings:keywords="@string/keywords_screen_resolution"
|
||||
settings:controller="com.android.settings.display.ScreenResolutionController"/>
|
||||
|
||||
<Preference
|
||||
android:key="screen_refresh_rate"
|
||||
android:title="@string/screen_refresh_rate_title"
|
||||
android:fragment="org.evolution.settings.display.refreshrate.ScreenRefreshRateFragment"
|
||||
settings:controller="org.evolution.settings.display.refreshrate.ScreenRefreshRateController"/>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="display_white_balance"
|
||||
android:title="@string/display_white_balance_title"
|
||||
@@ -203,7 +209,7 @@
|
||||
settings:controller="com.android.settings.display.HdrDisplayBrightnessPreferenceController"
|
||||
settings:interval="1"/>
|
||||
|
||||
<ListPreference
|
||||
<!--<ListPreference
|
||||
android:key="max_refresh_rate"
|
||||
android:title="@string/max_refresh_rate_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
@@ -219,7 +225,7 @@
|
||||
android:key="peak_refresh_rate"
|
||||
android:title="@string/peak_refresh_rate_title"
|
||||
android:summary="@string/peak_refresh_rate_summary"
|
||||
settings:controller="com.android.settings.display.PeakRefreshRatePreferenceController"/>
|
||||
settings:controller="com.android.settings.display.PeakRefreshRatePreferenceController"/>-->
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="show_operator_name"
|
||||
|
||||
11
res/xml/per_app_refresh_rate_config.xml
Normal file
11
res/xml/per_app_refresh_rate_config.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023-2024 Nameless-AOSP
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="per_app_refresh_rate_scren"
|
||||
android:title="@string/per_app_refresh_rate_title"
|
||||
settings:searchable="false" />
|
||||
35
res/xml/screen_refresh_rate.xml
Normal file
35
res/xml/screen_refresh_rate.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023-2024 Nameless-AOSP
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/screen_refresh_rate_title">
|
||||
|
||||
<ListPreference
|
||||
android:key="min_refresh_rate"
|
||||
android:title="@string/min_refresh_rate_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="org.evolution.settings.display.refreshrate.MinRefreshRatePreferenceController" />
|
||||
|
||||
<ListPreference
|
||||
android:key="peak_refresh_rate"
|
||||
android:title="@string/max_refresh_rate_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="org.evolution.settings.display.refreshrate.PeakRefreshRatePreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="per_app_refresh_rate"
|
||||
android:title="@string/per_app_refresh_rate_title"
|
||||
android:summary="@string/per_app_refresh_rate_summary"
|
||||
android:fragment="org.evolution.settings.display.refreshrate.PerAppRefreshRateFragment"
|
||||
settings:controller="org.evolution.settings.display.refreshrate.PerAppRefreshRatePreferenceController"/>
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="extreme_refresh_rate"
|
||||
android:title="@string/extreme_refresh_rate_title"
|
||||
android:summary="@string/extreme_refresh_rate_summary"
|
||||
settings:controller="org.evolution.settings.display.refreshrate.ExtremeRefreshRatePreferenceController"/>
|
||||
</PreferenceScreen>
|
||||
@@ -545,4 +545,6 @@ public class Settings extends SettingsActivity {
|
||||
public static class SmartPixelsActivity extends SettingsActivity {}
|
||||
|
||||
public static class DevRunningServicesActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
public static class ScreenRefreshRateActivity extends SettingsActivity {}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.android.settings.MainClear;
|
||||
import com.android.settings.MainClearConfirm;
|
||||
import com.android.settings.ResetNetwork;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.Settings.ScreenRefreshRateActivity;
|
||||
import com.android.settings.TestingSettings;
|
||||
import com.android.settings.TrustedCredentialsSettings;
|
||||
import com.android.settings.accessibility.AccessibilityDetailsSettingsFragment;
|
||||
@@ -221,6 +222,7 @@ import com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSetting
|
||||
import com.android.settings.wifi.tether.WifiTetherSettings;
|
||||
|
||||
import org.evolution.settings.EvolutionSettings;
|
||||
import org.evolution.settings.display.refreshrate.ScreenRefreshRateFragment;
|
||||
import org.evolution.settings.fragments.miscellaneous.SmartPixels;
|
||||
|
||||
public class SettingsGateway {
|
||||
@@ -433,6 +435,7 @@ public class SettingsGateway {
|
||||
VolumeStepsSettings.class.getName(),
|
||||
SmartPixels.class.getName(),
|
||||
RunningServices.class.getName(),
|
||||
ScreenRefreshRateFragment.class.getName(),
|
||||
};
|
||||
|
||||
public static final String[] SETTINGS_FOR_RESTRICTED = {
|
||||
@@ -484,5 +487,6 @@ public class SettingsGateway {
|
||||
Settings.PrivateDnsSettingsActivity.class.getName(),
|
||||
Settings.SmartPixelsActivity.class.getName(),
|
||||
Settings.DevRunningServicesActivity.class.getName(),
|
||||
Settings.ScreenRefreshRateActivity.class.getName(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
import org.evolution.display.RefreshRateManager;
|
||||
|
||||
public class ExtremeRefreshRatePreferenceController extends TogglePreferenceController {
|
||||
|
||||
private final RefreshRateManager mRefreshRateManager;
|
||||
|
||||
public ExtremeRefreshRatePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mRefreshRateManager = context.getSystemService(RefreshRateManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.System.getIntForUser(mContext.getContentResolver(),
|
||||
EXTREME_REFRESH_RATE, 0, UserHandle.USER_CURRENT) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
if (!isChecked) {
|
||||
mRefreshRateManager.setExtremeRefreshRateEnabled(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(mContext)
|
||||
.setTitle(mContext.getText(R.string.confirm_before_enable_title))
|
||||
.setMessage(mContext.getText(R.string.extreme_refresh_rate_warning))
|
||||
.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mRefreshRateManager.setExtremeRefreshRateEnabled(true);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
return isChecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSliceHighlightMenuRes() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The LineageOS Project
|
||||
* Copyright (C) 2022-2024 Nameless-AOSP
|
||||
*
|
||||
* 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 org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.util.evolution.DisplayRefreshRateHelper;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MinRefreshRatePreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final ArrayList<Integer> mSupportedList;
|
||||
private final DisplayRefreshRateHelper mHelper;
|
||||
|
||||
private ListPreference mListPreference;
|
||||
|
||||
public MinRefreshRatePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
|
||||
mHelper = DisplayRefreshRateHelper.getInstance(context);
|
||||
mSupportedList = mHelper.getSupportedRefreshRateList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mSupportedList.size() > 1 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mListPreference = screen.findPreference(getPreferenceKey());
|
||||
|
||||
final List<String> entries = new ArrayList<>();
|
||||
final List<String> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < mSupportedList.size(); ++i) {
|
||||
final String refreshRate = String.valueOf(mSupportedList.get(i));
|
||||
entries.add(refreshRate + " Hz");
|
||||
values.add(refreshRate);
|
||||
}
|
||||
|
||||
mListPreference.setEntries(entries.toArray(new String[entries.size()]));
|
||||
mListPreference.setEntryValues(values.toArray(new String[values.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final String refreshRate = String.valueOf(mHelper.getMinimumRefreshRate());
|
||||
final int index = mListPreference.findIndexOfValue(refreshRate);
|
||||
if (index != -1) {
|
||||
mListPreference.setValueIndex(index);
|
||||
mListPreference.setSummary(mListPreference.getEntries()[index]);
|
||||
} else {
|
||||
mListPreference.setSummary(refreshRate + " Hz");
|
||||
}
|
||||
|
||||
final int minRefreshRate = Integer.parseInt(refreshRate);
|
||||
final int peakRefreshRate = mHelper.getPeakRefreshRate();
|
||||
if (peakRefreshRate < minRefreshRate) {
|
||||
mHelper.setPeakRefreshRate(minRefreshRate);
|
||||
}
|
||||
|
||||
final boolean extremeMode = Settings.System.getIntForUser(
|
||||
mContext.getContentResolver(), EXTREME_REFRESH_RATE,
|
||||
0, UserHandle.USER_CURRENT) != 0;
|
||||
mListPreference.setEnabled(!extremeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mHelper.setMinimumRefreshRate(Integer.parseInt((String) newValue));
|
||||
updateState(preference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The LineageOS Project
|
||||
* Copyright (C) 2022-2024 Nameless-AOSP
|
||||
*
|
||||
* 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 org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.util.evolution.DisplayRefreshRateHelper;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PeakRefreshRatePreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final ArrayList<Integer> mSupportedList;
|
||||
private final DisplayRefreshRateHelper mHelper;
|
||||
|
||||
private ListPreference mListPreference;
|
||||
|
||||
public PeakRefreshRatePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
|
||||
mHelper = DisplayRefreshRateHelper.getInstance(context);
|
||||
mSupportedList = mHelper.getSupportedRefreshRateList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mSupportedList.size() > 1 ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mListPreference = screen.findPreference(getPreferenceKey());
|
||||
|
||||
final List<String> entries = new ArrayList<>();
|
||||
final List<String> values = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < mSupportedList.size(); ++i) {
|
||||
final String refreshRate = String.valueOf(mSupportedList.get(i));
|
||||
entries.add(refreshRate + " Hz");
|
||||
values.add(refreshRate);
|
||||
}
|
||||
|
||||
mListPreference.setEntries(entries.toArray(new String[entries.size()]));
|
||||
mListPreference.setEntryValues(values.toArray(new String[values.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final String refreshRate = String.valueOf(mHelper.getPeakRefreshRate());
|
||||
final int index = mListPreference.findIndexOfValue(refreshRate);
|
||||
if (index != -1) {
|
||||
mListPreference.setValueIndex(index);
|
||||
mListPreference.setSummary(mListPreference.getEntries()[index]);
|
||||
} else {
|
||||
mListPreference.setSummary(refreshRate + " Hz");
|
||||
}
|
||||
|
||||
final int peakRefreshRate = Integer.parseInt(refreshRate);
|
||||
final int minRefreshRate = mHelper.getMinimumRefreshRate();
|
||||
if (minRefreshRate > peakRefreshRate) {
|
||||
mHelper.setMinimumRefreshRate(peakRefreshRate);
|
||||
}
|
||||
|
||||
final boolean extremeMode = Settings.System.getIntForUser(
|
||||
mContext.getContentResolver(), EXTREME_REFRESH_RATE,
|
||||
0, UserHandle.USER_CURRENT) != 0;
|
||||
mListPreference.setEnabled(!extremeMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mHelper.setPeakRefreshRate(Integer.parseInt(String.valueOf(newValue)));
|
||||
updateState(preference);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.display.refreshrate;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.internal.util.evolution.DisplayRefreshRateHelper;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.evolution.display.RefreshRateManager;
|
||||
import org.evolution.settings.fragment.PerAppListConfigFragment;
|
||||
|
||||
public class PerAppRefreshRateFragment extends PerAppListConfigFragment {
|
||||
|
||||
private DisplayRefreshRateHelper mHelper;
|
||||
private RefreshRateManager mRefreshRateManager;
|
||||
|
||||
private List<String> mEntries;
|
||||
private List<Integer> mValues;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mHelper = DisplayRefreshRateHelper.getInstance(getActivity());
|
||||
mRefreshRateManager = getActivity().getSystemService(RefreshRateManager.class);
|
||||
|
||||
mEntries = new ArrayList<>();
|
||||
mEntries.add(getString(R.string.per_app_refresh_rate_default));
|
||||
mValues = new ArrayList<>();
|
||||
mValues.add(-1);
|
||||
|
||||
for (int refreshRate : mHelper.getSupportedRefreshRateList()) {
|
||||
mEntries.add(String.valueOf(refreshRate) + " Hz");
|
||||
mValues.add(refreshRate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.per_app_refresh_rate_config;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTopInfoResId() {
|
||||
return R.string.per_app_refresh_rate_summary;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getEntries() {
|
||||
return mEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Integer> getValues() {
|
||||
return mValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getCurrentValue(String packageName, int uid) {
|
||||
return mRefreshRateManager.getRefreshRateForPackage(packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onValueChanged(String packageName, int uid, int value) {
|
||||
if (value > 0) {
|
||||
mRefreshRateManager.setRefreshRateForPackage(packageName, value);
|
||||
} else {
|
||||
mRefreshRateManager.unsetRefreshRateForPackage(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.util.evolution.DisplayRefreshRateHelper;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
public class PerAppRefreshRatePreferenceController extends BasePreferenceController {
|
||||
|
||||
private final DisplayRefreshRateHelper mHelper;
|
||||
|
||||
private Preference mPreference;
|
||||
|
||||
public PerAppRefreshRatePreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mHelper = DisplayRefreshRateHelper.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mHelper.getSupportedRefreshRateList().size() > 1
|
||||
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final boolean extremeMode = Settings.System.getIntForUser(
|
||||
mContext.getContentResolver(), EXTREME_REFRESH_RATE,
|
||||
0, UserHandle.USER_CURRENT) != 0;
|
||||
mPreference.setEnabled(!extremeMode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.MIN_REFRESH_RATE;
|
||||
import static android.provider.Settings.System.PEAK_REFRESH_RATE;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.util.evolution.DisplayRefreshRateHelper;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ScreenRefreshRateController extends BasePreferenceController implements
|
||||
LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
private final DisplayRefreshRateHelper mHelper;
|
||||
|
||||
private Preference mPreference;
|
||||
private SettingObserver mSettingObserver;
|
||||
|
||||
public ScreenRefreshRateController(Context context, String key) {
|
||||
super(context, key);
|
||||
mHelper = DisplayRefreshRateHelper.getInstance(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return mHelper.getSupportedRefreshRateList().size() > 1
|
||||
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
mSettingObserver = new SettingObserver(mPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (mSettingObserver != null) {
|
||||
mSettingObserver.register(mContext.getContentResolver());
|
||||
mSettingObserver.onChange(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (mSettingObserver != null) {
|
||||
mSettingObserver.unregister(mContext.getContentResolver());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
String summary = null;
|
||||
|
||||
final int minRefreshRate = mHelper.getMinimumRefreshRate();
|
||||
final int maxRefreshRate = mHelper.getPeakRefreshRate();
|
||||
|
||||
final boolean extremeMode = Settings.System.getIntForUser(
|
||||
mContext.getContentResolver(), EXTREME_REFRESH_RATE,
|
||||
0, UserHandle.USER_CURRENT) != 0;
|
||||
final ArrayList<Integer> supportedList = mHelper.getSupportedRefreshRateList();
|
||||
|
||||
if (extremeMode && supportedList.size() > 0) {
|
||||
final int maxAllowed = supportedList.get(supportedList.size() - 1);
|
||||
summary = String.valueOf(maxAllowed) + " Hz";
|
||||
} else if (minRefreshRate == maxRefreshRate) {
|
||||
summary = String.valueOf(maxRefreshRate) + " Hz";
|
||||
} else {
|
||||
summary = String.valueOf(minRefreshRate) + " ~ " + String.valueOf(maxRefreshRate) + " Hz";
|
||||
}
|
||||
|
||||
if (summary != null) {
|
||||
preference.setSummary(summary);
|
||||
}
|
||||
|
||||
super.updateState(preference);
|
||||
}
|
||||
|
||||
private class SettingObserver extends ContentObserver {
|
||||
|
||||
private final Uri mMinUri = Settings.System.getUriFor(MIN_REFRESH_RATE);
|
||||
private final Uri mPeakUri = Settings.System.getUriFor(PEAK_REFRESH_RATE);
|
||||
private final Uri mExtremeUri = Settings.System.getUriFor(EXTREME_REFRESH_RATE);
|
||||
|
||||
private final Preference mPreference;
|
||||
|
||||
SettingObserver(Preference preference) {
|
||||
super(new Handler());
|
||||
mPreference = preference;
|
||||
}
|
||||
|
||||
public void register(ContentResolver cr) {
|
||||
cr.registerContentObserver(mMinUri, false, this);
|
||||
cr.registerContentObserver(mPeakUri, false, this);
|
||||
}
|
||||
|
||||
public void unregister(ContentResolver cr) {
|
||||
cr.unregisterContentObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateState(mPreference);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.display.refreshrate;
|
||||
|
||||
import static android.provider.Settings.System.MIN_REFRESH_RATE;
|
||||
import static android.provider.Settings.System.PEAK_REFRESH_RATE;
|
||||
|
||||
import static android.provider.Settings.System.EXTREME_REFRESH_RATE;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ContentResolver;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
|
||||
public class ScreenRefreshRateFragment extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "ScreenRefreshRateFragment";
|
||||
|
||||
private final SettingsObserver mObserver = new SettingsObserver();
|
||||
|
||||
private final class SettingsObserver extends ContentObserver {
|
||||
|
||||
private final Uri mMinUri = Settings.System.getUriFor(MIN_REFRESH_RATE);
|
||||
private final Uri mPeakUri = Settings.System.getUriFor(PEAK_REFRESH_RATE);
|
||||
private final Uri mExtremeUri = Settings.System.getUriFor(EXTREME_REFRESH_RATE);
|
||||
|
||||
SettingsObserver() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
void register(ContentResolver cr) {
|
||||
cr.registerContentObserver(mMinUri, false, this);
|
||||
cr.registerContentObserver(mPeakUri, false, this);
|
||||
cr.registerContentObserver(mExtremeUri, false, this);
|
||||
}
|
||||
|
||||
void unregister(ContentResolver cr) {
|
||||
cr.unregisterContentObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
updatePreferenceStates();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
mObserver.register(getContext().getContentResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mObserver.unregister(getContext().getContentResolver());
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.PAGE_UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.screen_refresh_rate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.fragment;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.widget.EmptyTextSettings;
|
||||
|
||||
import com.android.settingslib.widget.TopIntroPreference;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BasePerAppConfigFragment extends EmptyTextSettings {
|
||||
|
||||
protected Context mContext;
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
/**
|
||||
* Comparator by label, if null or empty then packageName.
|
||||
*/
|
||||
private static class AppComparator implements Comparator<AppData> {
|
||||
|
||||
private final Collator mCollator = Collator.getInstance();
|
||||
|
||||
@Override
|
||||
public final int compare(AppData a, AppData b) {
|
||||
String sa = a.label;
|
||||
if (TextUtils.isEmpty(sa)) sa = a.packageName;
|
||||
String sb = b.label;
|
||||
if (TextUtils.isEmpty(sb)) sb = b.packageName;
|
||||
return mCollator.compare(sa, sb);
|
||||
}
|
||||
}
|
||||
|
||||
protected final class AppData {
|
||||
protected String label;
|
||||
protected String packageName;
|
||||
protected int uid;
|
||||
|
||||
protected AppData(String label, String packageName, int uid) {
|
||||
this.label = label;
|
||||
this.packageName = packageName;
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof AppData) {
|
||||
final AppData other = (AppData) obj;
|
||||
return label.equals(other.label) &&
|
||||
packageName.equals(other.packageName) &&
|
||||
uid == other.uid;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = label.hashCode();
|
||||
result = 31 * result + packageName.hashCode();
|
||||
result = 31 * result + uid;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
mContext = getActivity();
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
final Context prefContext = getPrefContext();
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the prefs
|
||||
screen.removeAll();
|
||||
|
||||
// Add TopIntroPreference if resource id is valid
|
||||
if (getTopInfoResId() > 0) {
|
||||
try {
|
||||
final String title = mContext.getResources().getString(getTopInfoResId());
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
final TopIntroPreference topInfoPref = new TopIntroPreference(prefContext);
|
||||
topInfoPref.setTitle(title);
|
||||
screen.addPreference(topInfoPref);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
// Rebuild the list of prefs
|
||||
final ArrayList<AppData> apps = collectApps();
|
||||
for (final AppData appData : apps) {
|
||||
screen.addPreference(createAppPreference(prefContext, appData));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
setEmptyText(R.string.per_app_config_empty_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.PAGE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sorted list of AppData of all applications for current user,
|
||||
* with extra system applications defined in R.array.config_perAppConfAllowedSystemApps.
|
||||
*/
|
||||
private ArrayList<AppData> collectApps() {
|
||||
final ArraySet<AppData> apps = new ArraySet<>();
|
||||
final List<PackageInfo> installedPackages =
|
||||
mPackageManager.getInstalledPackages(0);
|
||||
for (PackageInfo pi : installedPackages) {
|
||||
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
continue;
|
||||
}
|
||||
apps.add(new AppData(
|
||||
pi.applicationInfo.loadLabel(mPackageManager).toString(),
|
||||
pi.packageName, pi.applicationInfo.uid));
|
||||
}
|
||||
if (getAllowedSystemAppListResId() > 0) {
|
||||
try {
|
||||
final String[] systemApps = mContext.getResources().getStringArray(
|
||||
getAllowedSystemAppListResId());
|
||||
for (String app : systemApps) {
|
||||
try {
|
||||
final PackageInfo pi = mPackageManager.getPackageInfo(app, 0);
|
||||
apps.add(new AppData(
|
||||
pi.applicationInfo.loadLabel(mPackageManager).toString(),
|
||||
app, pi.applicationInfo.uid));
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
final ArrayList<AppData> appList = new ArrayList<>();
|
||||
appList.addAll(apps);
|
||||
Collections.sort(appList, new AppComparator());
|
||||
return appList;
|
||||
}
|
||||
|
||||
protected Drawable getIcon(String packageName) {
|
||||
Drawable loadIcon = null;
|
||||
if (packageName != null) {
|
||||
try {
|
||||
loadIcon = mPackageManager.getApplicationIcon(packageName);
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
return loadIcon != null ? loadIcon : mPackageManager.getDefaultActivityIcon();
|
||||
}
|
||||
|
||||
protected int getAllowedSystemAppListResId() {
|
||||
return R.array.config_perAppConfAllowedSystemApps;
|
||||
}
|
||||
|
||||
protected int getTopInfoResId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected abstract Preference createAppPreference(Context prefContext, AppData appData);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceChangeListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.evolution.settings.widget.AppListPreference;
|
||||
|
||||
public abstract class PerAppListConfigFragment extends BasePerAppConfigFragment {
|
||||
|
||||
@Override
|
||||
protected Preference createAppPreference(Context prefContext, AppData appData) {
|
||||
final ListPreference pref = new AppListPreference(prefContext);
|
||||
pref.setIcon(getIcon(appData.packageName));
|
||||
pref.setTitle(appData.label);
|
||||
pref.setDialogTitle(appData.label);
|
||||
|
||||
int size = getEntries().size();
|
||||
|
||||
CharSequence[] entries = new CharSequence[size];
|
||||
CharSequence[] values = new CharSequence[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
entries[i] = getEntries().get(i);
|
||||
values[i] = String.valueOf(getValues().get(i));
|
||||
}
|
||||
pref.setEntries(entries);
|
||||
pref.setEntryValues(values);
|
||||
|
||||
final String value = String.valueOf(getCurrentValue(appData.packageName, appData.uid));
|
||||
CharSequence summary = "-1";
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (values[i].equals(value)) {
|
||||
summary = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
pref.setValue(value);
|
||||
pref.setSummary(summary);
|
||||
|
||||
pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String newValueStr = String.valueOf(newValue);
|
||||
onValueChanged(appData.packageName, appData.uid, Integer.parseInt(newValueStr));
|
||||
CharSequence[] entries = pref.getEntries();
|
||||
CharSequence[] values = pref.getEntryValues();
|
||||
CharSequence summary = entries[0];
|
||||
for (int i = 0; i < entries.length; ++i) {
|
||||
if (values[i].equals(newValueStr)) {
|
||||
summary = entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
pref.setSummary(summary);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
protected abstract List<String> getEntries();
|
||||
|
||||
protected abstract List<Integer> getValues();
|
||||
|
||||
protected abstract int getCurrentValue(String packageName, int uid);
|
||||
|
||||
protected abstract void onValueChanged(String packageName, int uid, int value);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2024 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceChangeListener;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.evolution.settings.widget.AppSwitchPreference;
|
||||
|
||||
public abstract class PerAppSwitchConfigFragment extends BasePerAppConfigFragment {
|
||||
|
||||
private final ArrayMap<String, Boolean> mPkgCheckState = new ArrayMap<>();
|
||||
|
||||
@Override
|
||||
protected Preference createAppPreference(Context prefContext, AppData appData) {
|
||||
final SwitchPreferenceCompat pref = new AppSwitchPreference(prefContext);
|
||||
pref.setIcon(getIcon(appData.packageName));
|
||||
pref.setTitle(appData.label);
|
||||
pref.setSummary(appData.packageName);
|
||||
|
||||
final boolean checked = isChecked(appData.packageName, appData.uid);
|
||||
pref.setChecked(checked);
|
||||
mPkgCheckState.put(appData.packageName, checked);
|
||||
|
||||
pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean ret = onSetChecked((SwitchPreferenceCompat) preference,
|
||||
appData.packageName, appData.uid, (Boolean) newValue);
|
||||
if (ret) {
|
||||
mPkgCheckState.put(appData.packageName, (Boolean) newValue);
|
||||
onCheckedListUpdated(generateCheckedPkgList());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
private List<String> generateCheckedPkgList() {
|
||||
final List<String> ret = new ArrayList<>();
|
||||
for (String pkg : mPkgCheckState.keySet()) {
|
||||
if (mPkgCheckState.get(pkg)) {
|
||||
ret.add(pkg);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected abstract boolean isChecked(String packageName, int uid);
|
||||
|
||||
protected abstract boolean onSetChecked(SwitchPreferenceCompat pref, String packageName, int uid, boolean checked);
|
||||
|
||||
protected abstract void onCheckedListUpdated(List<String> pkgList);
|
||||
}
|
||||
37
src/org/evolution/settings/widget/AppListPreference.java
Normal file
37
src/org/evolution/settings/widget/AppListPreference.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
|
||||
/**
|
||||
* The ListPreference for the pages need to show apps icon.
|
||||
*/
|
||||
public class AppListPreference extends ListPreference {
|
||||
|
||||
public AppListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppListPreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppListPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
}
|
||||
37
src/org/evolution/settings/widget/AppSwitchPreference.java
Normal file
37
src/org/evolution/settings/widget/AppSwitchPreference.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Nameless-AOSP Project
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.evolution.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
/**
|
||||
* The SwitchPreference for the pages need to show apps icon.
|
||||
*/
|
||||
public class AppSwitchPreference extends SwitchPreferenceCompat {
|
||||
|
||||
public AppSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppSwitchPreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
|
||||
public AppSwitchPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLayoutResource(com.android.settingslib.widget.preference.app.R.layout.preference_app);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user