resolveInfoList = mPackageManager.queryIntentActivities(i, 0);
+
+ synchronized (mLauncherResolveInfoList) {
+ mLauncherResolveInfoList.clear();
+ for (ResolveInfo ri : resolveInfoList) {
+ mLauncherResolveInfoList.add(ri.activityInfo.packageName);
+ }
+ }
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public boolean filterApp(ApplicationsState.AppEntry entry) {
+ boolean show = !mAllPackagesAdapter.mEntries.contains(entry.info.packageName);
+ if (show) {
+ synchronized (mLauncherResolveInfoList) {
+ show = mLauncherResolveInfoList.contains(entry.info.packageName);
+ }
+ }
+ return show;
+ }
+ }
+}
diff --git a/parts/src/org/lineageos/settings/refreshrate/RefreshUtils.java b/parts/src/org/lineageos/settings/refreshrate/RefreshUtils.java
new file mode 100644
index 00000000..d9325ab9
--- /dev/null
+++ b/parts/src/org/lineageos/settings/refreshrate/RefreshUtils.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 The LineageOS 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 org.lineageos.settings.refreshrate;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.UserHandle;
+import android.view.Display;
+
+import android.provider.Settings;
+import androidx.preference.PreferenceManager;
+
+public final class RefreshUtils {
+
+ private static final String REFRESH_CONTROL = "refresh_control";
+
+ private static float defaultMaxRate;
+ private static float defaultMinRate;
+ private static final String KEY_PEAK_REFRESH_RATE = "peak_refresh_rate";
+ private static final String KEY_MIN_REFRESH_RATE = "min_refresh_rate";
+ private Context mContext;
+ protected static boolean isAppInList = false;
+
+ protected static final int STATE_DEFAULT = 0;
+ protected static final int STATE_STANDARD = 1;
+ protected static final int STATE_HIGH = 2;
+ protected static final int STATE_EXTREME = 3;
+
+ private static final float REFRESH_STATE_DEFAULT = 120f;
+ private static final float REFRESH_STATE_STANDARD = 60f;
+ private static final float REFRESH_STATE_HIGH = 90f;
+ private static final float REFRESH_STATE_EXTREME = 120f;
+
+ private static final String REFRESH_STANDARD = "refresh.standard=";
+ private static final String REFRESH_HIGH = "refresh.high=";
+ private static final String REFRESH_EXTREME = "refresh.extreme=";
+
+ private SharedPreferences mSharedPrefs;
+
+ protected RefreshUtils(Context context) {
+ mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ mContext = context;
+ }
+
+ public static void startService(Context context) {
+ context.startServiceAsUser(new Intent(context, RefreshService.class),
+ UserHandle.CURRENT);
+ }
+
+ private void writeValue(String profiles) {
+ mSharedPrefs.edit().putString(REFRESH_CONTROL, profiles).apply();
+ }
+
+ protected void getOldRate(){
+ defaultMaxRate = Settings.System.getFloat(mContext.getContentResolver(), KEY_PEAK_REFRESH_RATE, REFRESH_STATE_DEFAULT);
+ defaultMinRate = Settings.System.getFloat(mContext.getContentResolver(), KEY_MIN_REFRESH_RATE, REFRESH_STATE_DEFAULT);
+ }
+
+
+ private String getValue() {
+ String value = mSharedPrefs.getString(REFRESH_CONTROL, null);
+
+ if (value == null || value.isEmpty()) {
+ value = REFRESH_STANDARD + ":" + REFRESH_HIGH + ":" + REFRESH_EXTREME;
+ writeValue(value);
+ }
+ return value;
+ }
+
+ protected void writePackage(String packageName, int mode) {
+ String value = getValue();
+ value = value.replace(packageName + ",", "");
+ String[] modes = value.split(":");
+ String finalString;
+
+ switch (mode) {
+ case STATE_STANDARD:
+ modes[0] = modes[0] + packageName + ",";
+ break;
+ case STATE_HIGH:
+ modes[1] = modes[1] + packageName + ",";
+ break;
+ case STATE_EXTREME:
+ modes[2] = modes[2] + packageName + ",";
+ break;
+ }
+
+ finalString = modes[0] + ":" + modes[1] + ":" + modes[2];
+
+ writeValue(finalString);
+ }
+
+ protected int getStateForPackage(String packageName) {
+ String value = getValue();
+ String[] modes = value.split(":");
+ int state = STATE_DEFAULT;
+ if (modes[0].contains(packageName + ",")) {
+ state = STATE_STANDARD;
+ } else if (modes[1].contains(packageName + ",")) {
+ state = STATE_HIGH;
+ } else if (modes[2].contains(packageName + ",")) {
+ state = STATE_EXTREME;
+ }
+ return state;
+ }
+
+ protected void setRefreshRate(String packageName) {
+ String value = getValue();
+ String modes[];
+ float maxrate = defaultMaxRate;
+ float minrate = defaultMinRate;
+ isAppInList = false;
+
+ if (value != null) {
+ modes = value.split(":");
+
+ if (modes[0].contains(packageName + ",")) {
+ maxrate = REFRESH_STATE_STANDARD;
+ if ( minrate > maxrate){
+ minrate = maxrate;
+ }
+ isAppInList = true;
+ } else if (modes[1].contains(packageName + ",")) {
+ maxrate = REFRESH_STATE_HIGH;
+ if (minrate > maxrate) {
+ minrate = maxrate;
+ }
+ isAppInList = true;
+ } else if (modes[2].contains(packageName + ",")) {
+ maxrate = REFRESH_STATE_EXTREME;
+ if ( minrate > maxrate){
+ minrate = maxrate;
+ }
+ isAppInList = true;
+ }
+ }
+ Settings.System.putFloat(mContext.getContentResolver(), KEY_MIN_REFRESH_RATE, minrate);
+ Settings.System.putFloat(mContext.getContentResolver(), KEY_PEAK_REFRESH_RATE, maxrate);
+ }
+}
diff --git a/parts/src/org/lineageos/settings/saturation/SaturationActivity.java b/parts/src/org/lineageos/settings/saturation/SaturationActivity.java
new file mode 100644
index 00000000..829a37db
--- /dev/null
+++ b/parts/src/org/lineageos/settings/saturation/SaturationActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The LineageOS 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 org.lineageos.settings.saturation;
+
+import android.os.Bundle;
+
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
+
+public class SaturationActivity extends CollapsingToolbarBaseActivity {
+
+ private static final String TAG = "Saturation";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getSupportFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
+ new SaturationFragment(), TAG).commit();
+ }
+}
diff --git a/parts/src/org/lineageos/settings/saturation/SaturationFragment.java b/parts/src/org/lineageos/settings/saturation/SaturationFragment.java
new file mode 100644
index 00000000..8a5aa442
--- /dev/null
+++ b/parts/src/org/lineageos/settings/saturation/SaturationFragment.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2024 The LineageOS 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 org.lineageos.settings.saturation;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.PreferenceManager;
+import androidx.viewpager.widget.PagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.android.settingslib.widget.LayoutPreference;
+
+import org.lineageos.settings.Constants;
+import org.lineageos.settings.CustomSeekBarPreference;
+import org.lineageos.settings.R;
+import org.lineageos.settings.utils.TileUtils;
+
+import java.util.Arrays;
+
+public class SaturationFragment extends PreferenceFragmentCompat
+ implements Preference.OnPreferenceChangeListener {
+
+ private View mViewArrowPrevious;
+ private View mViewArrowNext;
+ private ViewPager mViewPager;
+
+ private ImageView[] mDotIndicators;
+ private View[] mViewPagerImages;
+
+ private CustomSeekBarPreference mSaturationPreference;
+
+ private IBinder mSurfaceFlinger;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.saturation, rootKey);
+ setHasOptionsMenu(true);
+
+ LayoutPreference preview = findPreference(Constants.KEY_SATURATION_PREVIEW);
+ addViewPager(preview);
+
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
+
+ mSaturationPreference = (CustomSeekBarPreference) findPreference(Constants.KEY_SATURATION);
+ mSaturationPreference.setOnPreferenceChangeListener(this);
+ int seekBarValue = sharedPrefs.getInt(Constants.KEY_SATURATION, 100);
+ updateSaturation(seekBarValue);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.saturation_menu, menu);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mSaturationPreference) {
+ int seekBarValue = (Integer) newValue;
+ updateSaturation(seekBarValue);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.add_tile) {
+ TileUtils.requestAddTileService(
+ getContext(),
+ SaturationTileService.class,
+ R.string.saturation_title,
+ R.drawable.ic_saturation_tile
+ );
+ return true;
+ } else {
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ public void updateSaturation(int seekBarValue) {
+ float saturation;
+ if (seekBarValue == 100) {
+ saturation = 1.001f;
+ } else {
+ saturation = seekBarValue / 100.0f;
+ }
+
+ if (mSurfaceFlinger != null) {
+ try {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeFloat(saturation);
+ mSurfaceFlinger.transact(1022, data, null, 0);
+ data.recycle();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+ }
+
+ public void restoreSaturationSetting(Context context) {
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ int seekBarValue = sharedPrefs.getInt(Constants.KEY_SATURATION, 100);
+ updateSaturation(seekBarValue);
+ }
+
+ void addViewPager(LayoutPreference preview) {
+ mViewPager = preview.findViewById(R.id.viewpager);
+
+ int[] drawables = new int[]{
+ R.drawable.image_preview1,
+ R.drawable.image_preview2,
+ R.drawable.image_preview3
+ };
+
+ mViewPagerImages = new View[drawables.length];
+
+ for (int idx = 0; idx < drawables.length; idx++) {
+ mViewPagerImages[idx] = getLayoutInflater().inflate(R.layout.image_layout, null);
+ ImageView imageView = mViewPagerImages[idx].findViewById(R.id.imageView);
+ imageView.setImageResource(drawables[idx]);
+ }
+
+ mViewPager.setAdapter(new ImagePreviewPagerAdapter(mViewPagerImages));
+
+ mViewArrowPrevious = preview.findViewById(R.id.arrow_previous);
+ mViewArrowPrevious.setOnClickListener(v -> mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1, true));
+
+ mViewArrowNext = preview.findViewById(R.id.arrow_next);
+ mViewArrowNext.setOnClickListener(v -> mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, true));
+
+ mViewPager.addOnPageChangeListener(createPageListener());
+
+ final ViewGroup viewGroup = preview.findViewById(R.id.viewGroup);
+ mDotIndicators = new ImageView[mViewPagerImages.length];
+ for (int i = 0; i < mViewPagerImages.length; i++) {
+ final ImageView imageView = new ImageView(getContext());
+ final ViewGroup.MarginLayoutParams lp =
+ new ViewGroup.MarginLayoutParams(12, 12);
+ lp.setMargins(6, 0, 6, 0);
+ imageView.setLayoutParams(lp);
+ mDotIndicators[i] = imageView;
+
+ viewGroup.addView(mDotIndicators[i]);
+ }
+
+ updateIndicator(mViewPager.getCurrentItem());
+ }
+
+ private ViewPager.OnPageChangeListener createPageListener() {
+ return new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(
+ int position, float positionOffset, int positionOffsetPixels) {
+ if (positionOffset != 0) {
+ for (View mViewPagerImage : mViewPagerImages) {
+ mViewPagerImage.setVisibility(View.VISIBLE);
+ }
+ } else {
+ mViewPagerImages[position].setContentDescription(
+ getContext().getString(R.string.image_preview_content_description));
+ updateIndicator(position);
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ }
+ };
+ }
+
+ private void updateIndicator(int position) {
+ for (int i = 0; i < mViewPagerImages.length; i++) {
+ if (position == i) {
+ mDotIndicators[i].setBackgroundResource(
+ R.drawable.ic_image_preview_page_indicator_focused);
+
+ mViewPagerImages[i].setVisibility(View.VISIBLE);
+ } else {
+ mDotIndicators[i].setBackgroundResource(
+ R.drawable.ic_image_preview_page_indicator_unfocused);
+
+ mViewPagerImages[i].setVisibility(View.INVISIBLE);
+ }
+ }
+
+ if (position == 0) {
+ mViewArrowPrevious.setVisibility(View.INVISIBLE);
+ mViewArrowNext.setVisibility(View.VISIBLE);
+ } else if (position == (mViewPagerImages.length - 1)) {
+ mViewArrowPrevious.setVisibility(View.VISIBLE);
+ mViewArrowNext.setVisibility(View.INVISIBLE);
+ } else {
+ mViewArrowPrevious.setVisibility(View.VISIBLE);
+ mViewArrowNext.setVisibility(View.VISIBLE);
+ }
+ }
+
+ static class ImagePreviewPagerAdapter extends PagerAdapter {
+ private final View[] mPageViewList;
+
+ ImagePreviewPagerAdapter(View[] pageViewList) {
+ mPageViewList = pageViewList;
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ if (mPageViewList[position] != null) {
+ container.removeView(mPageViewList[position]);
+ }
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ container.addView(mPageViewList[position]);
+ return mPageViewList[position];
+ }
+
+ @Override
+ public int getCount() {
+ return mPageViewList.length;
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return object == view;
+ }
+ }
+}
diff --git a/parts/src/org/lineageos/settings/saturation/SaturationTileService.java b/parts/src/org/lineageos/settings/saturation/SaturationTileService.java
new file mode 100644
index 00000000..81bd3a11
--- /dev/null
+++ b/parts/src/org/lineageos/settings/saturation/SaturationTileService.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The LineageOS 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 org.lineageos.settings.saturation;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+
+public class SaturationTileService extends TileService {
+
+ @Override
+ public void onStartListening() {
+ super.onStartListening();
+ updateTile();
+ }
+
+ @Override
+ public void onClick() {
+ super.onClick();
+ Intent intent = new Intent(this, SaturationActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ PendingIntent pendingIntent = PendingIntent.getActivity(
+ this,
+ 0,
+ intent,
+ PendingIntent.FLAG_IMMUTABLE
+ );
+ startActivityAndCollapse(pendingIntent);
+ }
+
+ private void updateTile() {
+ final Tile tile = getQsTile();
+ tile.setState(Tile.STATE_ACTIVE);
+ tile.updateTile();
+ }
+}
diff --git a/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsActivity.java b/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsActivity.java
new file mode 100644
index 00000000..c85b22ae
--- /dev/null
+++ b/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2025 GuidixX
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.settings.soundcontrol;
+
+import android.os.Bundle;
+import androidx.appcompat.app.AppCompatActivity;
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
+
+public class SoundControlSettingsActivity extends CollapsingToolbarBaseActivity {
+ private static final String TAG_SOUND_CONTROL = "soundcontrol";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getSupportFragmentManager().beginTransaction().replace(
+ com.android.settingslib.collapsingtoolbar.R.id.content_frame,
+ new SoundControlSettingsFragment(), TAG_SOUND_CONTROL).commit();
+ }
+}
diff --git a/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsFragment.java b/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsFragment.java
new file mode 100644
index 00000000..442829b0
--- /dev/null
+++ b/parts/src/org/lineageos/settings/soundcontrol/SoundControlSettingsFragment.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2025 GuidixX
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.settings.soundcontrol;
+
+import android.os.Bundle;
+import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SeekBarPreference;
+import androidx.preference.SwitchPreferenceCompat;
+import org.lineageos.settings.R;
+
+public class SoundControlSettingsFragment extends PreferenceFragmentCompat {
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.sound_control_settings, rootKey);
+
+ SeekBarPreference micGainPref = findPreference("mic_gain");
+ SeekBarPreference hpLeftGainPref = findPreference("hp_left_gain");
+ SeekBarPreference hpRightGainPref = findPreference("hp_right_gain");
+ SwitchPreferenceCompat enableSwitch = findPreference("sound_control_enable");
+
+ micGainPref.setValue(SoundControlUtils.getSavedMicGain(getContext()));
+ int[] hpGains = SoundControlUtils.getSavedHpGain(getContext());
+ hpLeftGainPref.setValue(hpGains[0]);
+ hpRightGainPref.setValue(hpGains[1]);
+
+ boolean enabled = SoundControlUtils.isEnabled(getContext());
+ enableSwitch.setChecked(enabled);
+ micGainPref.setEnabled(enabled);
+ hpLeftGainPref.setEnabled(enabled);
+ hpRightGainPref.setEnabled(enabled);
+
+ micGainPref.setOnPreferenceChangeListener((pref, newValue) -> {
+ SoundControlUtils.saveMicGain(getContext(), (int) newValue);
+ return true;
+ });
+ hpLeftGainPref.setOnPreferenceChangeListener((pref, newValue) -> {
+ SoundControlUtils.saveHpGain(getContext(), (int) newValue, hpRightGainPref.getValue());
+ return true;
+ });
+ hpRightGainPref.setOnPreferenceChangeListener((pref, newValue) -> {
+ SoundControlUtils.saveHpGain(getContext(), hpLeftGainPref.getValue(), (int) newValue);
+ return true;
+ });
+ enableSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
+ boolean isEnabled = (Boolean) newValue;
+ SoundControlUtils.setEnabled(getContext(), isEnabled);
+ micGainPref.setEnabled(isEnabled);
+ hpLeftGainPref.setEnabled(isEnabled);
+ hpRightGainPref.setEnabled(isEnabled);
+ if (isEnabled) {
+ SoundControlUtils.applyAll(getContext());
+ }
+ return true;
+ });
+ }
+}
diff --git a/parts/src/org/lineageos/settings/soundcontrol/SoundControlUtils.java b/parts/src/org/lineageos/settings/soundcontrol/SoundControlUtils.java
new file mode 100644
index 00000000..b3e76147
--- /dev/null
+++ b/parts/src/org/lineageos/settings/soundcontrol/SoundControlUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2025 GuidixX
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.settings.soundcontrol;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import org.lineageos.settings.utils.FileUtils;
+
+public class SoundControlUtils {
+ private static final String PREF_MIC_GAIN = "sound_mic_gain";
+ private static final String PREF_HP_LEFT_GAIN = "sound_hp_left_gain";
+ private static final String PREF_HP_RIGHT_GAIN = "sound_hp_right_gain";
+ private static final String MIC_GAIN_PATH = "/sys/kernel/sound_control/mic_gain";
+ private static final String HP_GAIN_PATH = "/sys/kernel/sound_control/headphone_gain";
+ private static final String PREF_ENABLE = "sound_control_enable";
+
+ public static void saveMicGain(Context ctx, int value) {
+ PreferenceManager.getDefaultSharedPreferences(ctx).edit().putInt(PREF_MIC_GAIN, value).apply();
+ writeInt(MIC_GAIN_PATH, value);
+ }
+ public static void saveHpGain(Context ctx, int left, int right) {
+ PreferenceManager.getDefaultSharedPreferences(ctx)
+ .edit().putInt(PREF_HP_LEFT_GAIN, left).putInt(PREF_HP_RIGHT_GAIN, right).apply();
+ writeHeadphoneGain(HP_GAIN_PATH, left, right);
+ }
+ public static int getSavedMicGain(Context ctx) {
+ return PreferenceManager.getDefaultSharedPreferences(ctx).getInt(PREF_MIC_GAIN, 0);
+ }
+ public static int[] getSavedHpGain(Context ctx) {
+ return new int[] {
+ PreferenceManager.getDefaultSharedPreferences(ctx).getInt(PREF_HP_LEFT_GAIN, 0),
+ PreferenceManager.getDefaultSharedPreferences(ctx).getInt(PREF_HP_RIGHT_GAIN, 0)
+ };
+ }
+ public static void applyAll(Context ctx) {
+ writeInt(MIC_GAIN_PATH, getSavedMicGain(ctx));
+ int[] hp = getSavedHpGain(ctx);
+ writeHeadphoneGain(HP_GAIN_PATH, hp[0], hp[1]);
+ }
+ public static int readInt(String path, int def) {
+ try {
+ return Integer.parseInt(FileUtils.readOneLine(path));
+ } catch (Exception e) {
+ return def;
+ }
+ }
+ public static void writeInt(String path, int value) {
+ FileUtils.writeLine(path, String.valueOf(value));
+ }
+ public static int[] readHeadphoneGain(String path) {
+ try {
+ String[] vals = FileUtils.readOneLine(path).split(" ");
+ return new int[]{Integer.parseInt(vals[0]), Integer.parseInt(vals[1])};
+ } catch (Exception e) {
+ return new int[]{0, 0};
+ }
+ }
+ public static void writeHeadphoneGain(String path, int left, int right) {
+ FileUtils.writeLine(path, left + " " + right);
+ }
+
+ public static boolean isEnabled(Context ctx) {
+ return PreferenceManager.getDefaultSharedPreferences(ctx).getBoolean(PREF_ENABLE, true);
+ }
+ public static void setEnabled(Context ctx, boolean enabled) {
+ PreferenceManager.getDefaultSharedPreferences(ctx).edit().putBoolean(PREF_ENABLE, enabled).apply();
+ }
+}
diff --git a/parts/src/org/lineageos/settings/speaker/ClearSpeakerActivity.java b/parts/src/org/lineageos/settings/speaker/ClearSpeakerActivity.java
new file mode 100644
index 00000000..3a9b5636
--- /dev/null
+++ b/parts/src/org/lineageos/settings/speaker/ClearSpeakerActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * 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.lineageos.settings.speaker;
+
+import android.os.Bundle;
+
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
+
+public class ClearSpeakerActivity extends CollapsingToolbarBaseActivity {
+
+ private static final String TAG_CLEARSPEAKER = "clearspeaker";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
+ new ClearSpeakerFragment(), TAG_CLEARSPEAKER).commit();
+ }
+}
diff --git a/parts/src/org/lineageos/settings/speaker/ClearSpeakerFragment.java b/parts/src/org/lineageos/settings/speaker/ClearSpeakerFragment.java
new file mode 100644
index 00000000..7242bc16
--- /dev/null
+++ b/parts/src/org/lineageos/settings/speaker/ClearSpeakerFragment.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 Paranoid Android
+ *
+ * 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.lineageos.settings.speaker;
+
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragment;
+import androidx.preference.SwitchPreference;
+
+import org.lineageos.settings.R;
+
+import java.io.IOException;
+
+public class ClearSpeakerFragment extends PreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = "ClearSpeakerFragment";
+ private static final String PREF_CLEAR_SPEAKER = "clear_speaker_pref";
+ private static final int PLAY_DURATION_MS = 30000;
+
+ private Handler mHandler = new Handler(Looper.getMainLooper());
+ private MediaPlayer mMediaPlayer;
+ private SwitchPreference mClearSpeakerPref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.clear_speaker_settings);
+
+ mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER);
+ mClearSpeakerPref.setOnPreferenceChangeListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mClearSpeakerPref) {
+ boolean value = (Boolean) newValue;
+ if (value && startPlaying()) {
+ mHandler.removeCallbacksAndMessages(null);
+ mHandler.postDelayed(this::stopPlaying, PLAY_DURATION_MS);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ stopPlaying();
+ }
+
+ public boolean startPlaying() {
+ getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ mMediaPlayer = new MediaPlayer();
+ mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .build());
+ mMediaPlayer.setLooping(true);
+ try (AssetFileDescriptor afd = getResources().openRawResourceFd(
+ R.raw.clear_speaker_sound)) {
+ mMediaPlayer.setDataSource(afd);
+ mMediaPlayer.setVolume(1.0f, 1.0f);
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ mClearSpeakerPref.setEnabled(false);
+ } catch (IOException | IllegalArgumentException e) {
+ Log.e(TAG, "Failed to play speaker clean sound!", e);
+ return false;
+ }
+ return true;
+ }
+
+ public void stopPlaying() {
+ if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
+ try {
+ mMediaPlayer.stop();
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Failed to stop media player!", e);
+ } finally {
+ mMediaPlayer.reset();
+ mMediaPlayer.release();
+ mMediaPlayer=null;
+ }
+ }
+ mClearSpeakerPref.setEnabled(true);
+ mClearSpeakerPref.setChecked(false);
+ }
+}
diff --git a/parts/src/org/lineageos/settings/thermal/ThermalActivity.java b/parts/src/org/lineageos/settings/thermal/ThermalActivity.java
new file mode 100644
index 00000000..e127c354
--- /dev/null
+++ b/parts/src/org/lineageos/settings/thermal/ThermalActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 The LineageOS 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 org.lineageos.settings.thermal;
+
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
+
+public class ThermalActivity extends CollapsingToolbarBaseActivity {
+
+ private static final String TAG_THERMAL = "thermal";
+ private static final String THERMAL_SCONFIG = "/sys/class/thermal/thermal_message/sconfig";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
+ new ThermalSettingsFragment(), TAG_THERMAL).commit();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/parts/src/org/lineageos/settings/thermal/ThermalService.java b/parts/src/org/lineageos/settings/thermal/ThermalService.java
new file mode 100644
index 00000000..4e29a560
--- /dev/null
+++ b/parts/src/org/lineageos/settings/thermal/ThermalService.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2020 The LineageOS 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 org.lineageos.settings.thermal;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityTaskManager;
+import android.app.TaskStackListener;
+import android.app.Service;
+import android.app.TaskStackListener;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class ThermalService extends Service {
+
+ private static final String TAG = "ThermalService";
+ private static final boolean DEBUG = false;
+
+ private boolean mScreenOn = true;
+ private String mCurrentApp = "";
+ private ThermalUtils mThermalUtils;
+
+ private IActivityTaskManager mActivityTaskManager;
+
+ private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case Intent.ACTION_SCREEN_OFF:
+ mScreenOn = false;
+ setThermalProfile();
+ break;
+ case Intent.ACTION_SCREEN_ON:
+ mScreenOn = true;
+ setThermalProfile();
+ break;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ if (DEBUG) Log.d(TAG, "Creating service");
+ try {
+ mActivityTaskManager = ActivityTaskManager.getService();
+ mActivityTaskManager.registerTaskStackListener(mTaskListener);
+ } catch (RemoteException e) {
+ // Do nothing
+ }
+ mThermalUtils = new ThermalUtils(this);
+ registerReceiver();
+ super.onCreate();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (DEBUG) Log.d(TAG, "Starting service");
+ return START_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private void registerReceiver() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ this.registerReceiver(mIntentReceiver, filter);
+ }
+
+ private void setThermalProfile() {
+ if (mScreenOn) {
+ mThermalUtils.setThermalProfile(mCurrentApp);
+ } else {
+ mThermalUtils.setDefaultThermalProfile();
+ }
+ }
+
+ private final TaskStackListener mTaskListener = new TaskStackListener() {
+ @Override
+ public void onTaskStackChanged() {
+ try {
+ final ActivityTaskManager.RootTaskInfo focusedTask =
+ ActivityTaskManager.getService().getFocusedRootTaskInfo();
+ if (focusedTask != null && focusedTask.topActivity != null) {
+ ComponentName taskComponentName = focusedTask.topActivity;
+ String foregroundApp = taskComponentName.getPackageName();
+ if (!foregroundApp.equals(mCurrentApp)) {
+ mCurrentApp = foregroundApp;
+ setThermalProfile();
+ }
+ }
+ } catch (Exception e) {}
+ }
+ };
+}
diff --git a/parts/src/org/lineageos/settings/thermal/ThermalSettingsFragment.java b/parts/src/org/lineageos/settings/thermal/ThermalSettingsFragment.java
new file mode 100644
index 00000000..d30d9845
--- /dev/null
+++ b/parts/src/org/lineageos/settings/thermal/ThermalSettingsFragment.java
@@ -0,0 +1,432 @@
+/**
+ * Copyright (C) 2020 The LineageOS 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 org.lineageos.settings.thermal;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SectionIndexer;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceFragment;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+import com.android.settingslib.applications.ApplicationsState;
+
+import org.lineageos.settings.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ThermalSettingsFragment extends PreferenceFragment
+ implements ApplicationsState.Callbacks {
+
+ private AllPackagesAdapter mAllPackagesAdapter;
+ private ApplicationsState mApplicationsState;
+ private ApplicationsState.Session mSession;
+ private ActivityFilter mActivityFilter;
+ private Map mEntryMap =
+ new HashMap();
+
+ private ThermalUtils mThermalUtils;
+ private RecyclerView mAppsRecyclerView;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
+ mSession = mApplicationsState.newSession(this);
+ mSession.onResume();
+ mActivityFilter = new ActivityFilter(getActivity().getPackageManager());
+
+ mAllPackagesAdapter = new AllPackagesAdapter(getActivity());
+
+ mThermalUtils = new ThermalUtils(getActivity());
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.thermal_layout, container, false);
+ }
+
+ @Override
+ public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mAppsRecyclerView = view.findViewById(R.id.thermal_rv_view);
+ mAppsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
+ mAppsRecyclerView.setAdapter(mAllPackagesAdapter);
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ getActivity().setTitle(getResources().getString(R.string.thermal_title));
+ rebuild();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ mSession.onPause();
+ mSession.onDestroy();
+ }
+
+ @Override
+ public void onPackageListChanged() {
+ mActivityFilter.updateLauncherInfoList();
+ rebuild();
+ }
+
+ @Override
+ public void onRebuildComplete(ArrayList entries) {
+ if (entries != null) {
+ handleAppEntries(entries);
+ mAllPackagesAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onLoadEntriesCompleted() {
+ rebuild();
+ }
+
+ @Override
+ public void onAllSizesComputed() {
+ }
+
+ @Override
+ public void onLauncherInfoChanged() {
+ }
+
+ @Override
+ public void onPackageIconChanged() {
+ }
+
+ @Override
+ public void onPackageSizeChanged(String packageName) {
+ }
+
+ @Override
+ public void onRunningStateChanged(boolean running) {
+ }
+
+ private void handleAppEntries(List entries) {
+ final ArrayList sections = new ArrayList();
+ final ArrayList positions = new ArrayList();
+ final PackageManager pm = getActivity().getPackageManager();
+ String lastSectionIndex = null;
+ int offset = 0;
+
+ for (int i = 0; i < entries.size(); i++) {
+ final ApplicationInfo info = entries.get(i).info;
+ final String label = (String) info.loadLabel(pm);
+ final String sectionIndex;
+
+ if (!info.enabled) {
+ sectionIndex = "--"; // XXX
+ } else if (TextUtils.isEmpty(label)) {
+ sectionIndex = "";
+ } else {
+ sectionIndex = label.substring(0, 1).toUpperCase();
+ }
+
+ if (lastSectionIndex == null ||
+ !TextUtils.equals(sectionIndex, lastSectionIndex)) {
+ sections.add(sectionIndex);
+ positions.add(offset);
+ lastSectionIndex = sectionIndex;
+ }
+
+ offset++;
+ }
+
+ mAllPackagesAdapter.setEntries(entries, sections, positions);
+ mEntryMap.clear();
+ for (ApplicationsState.AppEntry e : entries) {
+ mEntryMap.put(e.info.packageName, e);
+ }
+ }
+
+ private void rebuild() {
+ mSession.rebuild(mActivityFilter, ApplicationsState.ALPHA_COMPARATOR);
+ }
+
+ private int getStateDrawable(int state) {
+ switch (state) {
+ case ThermalUtils.STATE_BENCHMARK:
+ return R.drawable.ic_thermal_benchmark;
+ case ThermalUtils.STATE_BROWSER:
+ return R.drawable.ic_thermal_browser;
+ case ThermalUtils.STATE_CAMERA:
+ return R.drawable.ic_thermal_camera;
+ case ThermalUtils.STATE_DIALER:
+ return R.drawable.ic_thermal_dialer;
+ case ThermalUtils.STATE_GAMING:
+ return R.drawable.ic_thermal_gaming;
+ case ThermalUtils.STATE_STREAMING:
+ return R.drawable.ic_thermal_streaming;
+ case ThermalUtils.STATE_DEFAULT:
+ default:
+ return R.drawable.ic_thermal_default;
+ }
+ }
+
+ private class ViewHolder extends RecyclerView.ViewHolder {
+ private TextView title;
+ private Spinner mode;
+ private ImageView icon;
+ private View rootView;
+ private ImageView stateIcon;
+
+ private ViewHolder(View view) {
+ super(view);
+ this.title = view.findViewById(R.id.app_name);
+ this.mode = view.findViewById(R.id.app_mode);
+ this.icon = view.findViewById(R.id.app_icon);
+ this.stateIcon = view.findViewById(R.id.state);
+ this.rootView = view;
+
+ view.setTag(this);
+ }
+ }
+
+ private class ModeAdapter extends BaseAdapter {
+
+ private final LayoutInflater inflater;
+ private final int[] items = {
+ R.string.thermal_default,
+ R.string.thermal_benchmark,
+ R.string.thermal_browser,
+ R.string.thermal_camera,
+ R.string.thermal_dialer,
+ R.string.thermal_gaming,
+ R.string.thermal_streaming
+ };
+
+ private ModeAdapter(Context context) {
+ inflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public int getCount() {
+ return items.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return items[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view;
+ if (convertView != null) {
+ view = (TextView) convertView;
+ } else {
+ view = (TextView) inflater.inflate(android.R.layout.simple_spinner_dropdown_item,
+ parent, false);
+ }
+
+ view.setText(items[position]);
+ view.setTextSize(14f);
+
+ return view;
+ }
+ }
+
+ private class AllPackagesAdapter extends RecyclerView.Adapter
+ implements AdapterView.OnItemSelectedListener, SectionIndexer {
+
+ private List mEntries = new ArrayList<>();
+ private String[] mSections;
+ private int[] mPositions;
+
+ public AllPackagesAdapter(Context context) {
+ mActivityFilter = new ActivityFilter(context.getPackageManager());
+ }
+
+ @Override
+ public int getItemCount() {
+ return mEntries.size();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mEntries.get(position).id;
+ }
+
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ ViewHolder holder = new ViewHolder(LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.thermal_list_item, parent, false));
+ Context context = holder.itemView.getContext();
+ holder.mode.setAdapter(new ModeAdapter(context));
+ holder.mode.setOnItemSelectedListener(this);
+ return holder;
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ ApplicationsState.AppEntry entry = mEntries.get(position);
+
+ if (entry == null) {
+ return;
+ }
+
+ holder.title.setText(entry.label);
+ holder.title.setOnClickListener(v -> holder.mode.performClick());
+ mApplicationsState.ensureIcon(entry);
+ holder.icon.setImageDrawable(entry.icon);
+ int packageState = mThermalUtils.getStateForPackage(entry.info.packageName);
+ holder.mode.setSelection(packageState, false);
+ holder.mode.setTag(entry);
+ holder.stateIcon.setImageResource(getStateDrawable(packageState));
+ }
+
+ private void setEntries(List entries,
+ List sections, List positions) {
+ mEntries = entries;
+ mSections = sections.toArray(new String[sections.size()]);
+ mPositions = new int[positions.size()];
+ for (int i = 0; i < positions.size(); i++) {
+ mPositions[i] = positions.get(i);
+ }
+ notifyDataSetChanged();
+ }
+
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ final ApplicationsState.AppEntry entry = (ApplicationsState.AppEntry) parent.getTag();
+ int currentState = mThermalUtils.getStateForPackage(entry.info.packageName);
+ if (currentState != position) {
+ mThermalUtils.writePackage(entry.info.packageName, position);
+ notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ }
+
+ @Override
+ public int getPositionForSection(int section) {
+ if (section < 0 || section >= mSections.length) {
+ return -1;
+ }
+
+ return mPositions[section];
+ }
+
+ @Override
+ public int getSectionForPosition(int position) {
+ if (position < 0 || position >= getItemCount()) {
+ return -1;
+ }
+
+ final int index = Arrays.binarySearch(mPositions, position);
+
+ /*
+ * Consider this example: section positions are 0, 3, 5; the supplied
+ * position is 4. The section corresponding to position 4 starts at
+ * position 3, so the expected return value is 1. Binary search will not
+ * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
+ * To get from that number to the expected value of 1 we need to negate
+ * and subtract 2.
+ */
+ return index >= 0 ? index : -index - 2;
+ }
+
+ @Override
+ public Object[] getSections() {
+ return mSections;
+ }
+ }
+
+ private class ActivityFilter implements ApplicationsState.AppFilter {
+
+ private final PackageManager mPackageManager;
+ private final List mLauncherResolveInfoList = new ArrayList();
+
+ private ActivityFilter(PackageManager packageManager) {
+ this.mPackageManager = packageManager;
+
+ updateLauncherInfoList();
+ }
+
+ public void updateLauncherInfoList() {
+ Intent i = new Intent(Intent.ACTION_MAIN);
+ i.addCategory(Intent.CATEGORY_LAUNCHER);
+ List resolveInfoList = mPackageManager.queryIntentActivities(i, 0);
+
+ synchronized (mLauncherResolveInfoList) {
+ mLauncherResolveInfoList.clear();
+ for (ResolveInfo ri : resolveInfoList) {
+ mLauncherResolveInfoList.add(ri.activityInfo.packageName);
+ }
+ }
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public boolean filterApp(ApplicationsState.AppEntry entry) {
+ boolean show = !mAllPackagesAdapter.mEntries.contains(entry.info.packageName);
+ if (show) {
+ synchronized (mLauncherResolveInfoList) {
+ show = mLauncherResolveInfoList.contains(entry.info.packageName);
+ }
+ }
+ return show;
+ }
+ }
+}
diff --git a/parts/src/org/lineageos/settings/thermal/ThermalUtils.java b/parts/src/org/lineageos/settings/thermal/ThermalUtils.java
new file mode 100644
index 00000000..cf71fbe2
--- /dev/null
+++ b/parts/src/org/lineageos/settings/thermal/ThermalUtils.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2020 The LineageOS 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 org.lineageos.settings.thermal;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.UserHandle;
+
+import androidx.preference.PreferenceManager;
+
+import org.lineageos.settings.utils.FileUtils;
+
+public final class ThermalUtils {
+
+ private static final String THERMAL_CONTROL = "thermal_control";
+
+ protected static final int STATE_DEFAULT = 0;
+ protected static final int STATE_BENCHMARK = 1;
+ protected static final int STATE_BROWSER = 2;
+ protected static final int STATE_CAMERA = 3;
+ protected static final int STATE_DIALER = 4;
+ protected static final int STATE_GAMING = 5;
+ protected static final int STATE_STREAMING = 6;
+
+ private static final String THERMAL_STATE_DEFAULT = "0";
+ private static final String THERMAL_STATE_BENCHMARK = "10";
+ private static final String THERMAL_STATE_BROWSER = "11";
+ private static final String THERMAL_STATE_CAMERA = "12";
+ private static final String THERMAL_STATE_DIALER = "8";
+ private static final String THERMAL_STATE_GAMING = "9";
+ private static final String THERMAL_STATE_STREAMING = "14";
+
+ private static final String THERMAL_BENCHMARK = "thermal.benchmark=";
+ private static final String THERMAL_BROWSER = "thermal.browser=";
+ private static final String THERMAL_CAMERA = "thermal.camera=";
+ private static final String THERMAL_DIALER = "thermal.dialer=";
+ private static final String THERMAL_GAMING = "thermal.gaming=";
+ private static final String THERMAL_STREAMING = "thermal.streaming=";
+
+ private static final String THERMAL_SCONFIG = "/sys/class/thermal/thermal_message/sconfig";
+
+ private SharedPreferences mSharedPrefs;
+
+ protected ThermalUtils(Context context) {
+ mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ public static void startService(Context context) {
+ context.startServiceAsUser(new Intent(context, ThermalService.class),
+ UserHandle.CURRENT);
+ }
+
+ private void writeValue(String profiles) {
+ mSharedPrefs.edit().putString(THERMAL_CONTROL, profiles).apply();
+ }
+
+ private String getValue() {
+ String value = mSharedPrefs.getString(THERMAL_CONTROL, null);
+
+ if (value == null || value.isEmpty()) {
+ value = THERMAL_BENCHMARK + ":" + THERMAL_BROWSER + ":" + THERMAL_CAMERA + ":" +
+ THERMAL_DIALER + ":" + THERMAL_GAMING + ":" + THERMAL_STREAMING;
+ writeValue(value);
+ }
+ return value;
+ }
+
+ protected void writePackage(String packageName, int mode) {
+ String value = getValue();
+ value = value.replace(packageName + ",", "");
+ String[] modes = value.split(":");
+ String finalString;
+
+ switch (mode) {
+ case STATE_BENCHMARK:
+ modes[0] = modes[0] + packageName + ",";
+ break;
+ case STATE_BROWSER:
+ modes[1] = modes[1] + packageName + ",";
+ break;
+ case STATE_CAMERA:
+ modes[2] = modes[2] + packageName + ",";
+ break;
+ case STATE_DIALER:
+ modes[3] = modes[3] + packageName + ",";
+ break;
+ case STATE_GAMING:
+ modes[4] = modes[4] + packageName + ",";
+ break;
+ case STATE_STREAMING:
+ modes[5] = modes[5] + packageName + ",";
+ break;
+ }
+
+ finalString = modes[0] + ":" + modes[1] + ":" + modes[2] + ":" + modes[3] + ":" +
+ modes[4] + ":" + modes[5];
+
+ writeValue(finalString);
+ }
+
+ protected int getStateForPackage(String packageName) {
+ String value = getValue();
+ String[] modes = value.split(":");
+ int state = STATE_DEFAULT;
+ if (modes[0].contains(packageName + ",")) {
+ state = STATE_BENCHMARK;
+ } else if (modes[1].contains(packageName + ",")) {
+ state = STATE_BROWSER;
+ } else if (modes[2].contains(packageName + ",")) {
+ state = STATE_CAMERA;
+ } else if (modes[3].contains(packageName + ",")) {
+ state = STATE_DIALER;
+ } else if (modes[4].contains(packageName + ",")) {
+ state = STATE_GAMING;
+ } else if (modes[5].contains(packageName + ",")) {
+ state = STATE_STREAMING;
+ }
+
+ return state;
+ }
+
+ protected void setDefaultThermalProfile() {
+ FileUtils.writeLine(THERMAL_SCONFIG, THERMAL_STATE_DEFAULT);
+ }
+
+ protected void setThermalProfile(String packageName) {
+ String value = getValue();
+ String modes[];
+ String state = THERMAL_STATE_DEFAULT;
+
+ if (value != null) {
+ modes = value.split(":");
+
+ if (modes[0].contains(packageName + ",")) {
+ state = THERMAL_STATE_BENCHMARK;
+ } else if (modes[1].contains(packageName + ",")) {
+ state = THERMAL_STATE_BROWSER;
+ } else if (modes[2].contains(packageName + ",")) {
+ state = THERMAL_STATE_CAMERA;
+ } else if (modes[3].contains(packageName + ",")) {
+ state = THERMAL_STATE_DIALER;
+ } else if (modes[4].contains(packageName + ",")) {
+ state = THERMAL_STATE_GAMING;
+ } else if (modes[5].contains(packageName + ",")) {
+ state = THERMAL_STATE_STREAMING;
+ }
+ }
+ FileUtils.writeLine(THERMAL_SCONFIG, state);
+ }
+}
diff --git a/parts/src/org/lineageos/settings/utils/ComponentUtils.java b/parts/src/org/lineageos/settings/utils/ComponentUtils.java
new file mode 100644
index 00000000..28701b53
--- /dev/null
+++ b/parts/src/org/lineageos/settings/utils/ComponentUtils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The LineageOS 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 org.lineageos.settings.utils;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+public class ComponentUtils {
+
+ /**
+ * Enables or disables a specified Android component dynamically at runtime.
+ *
+ * @param context The context from which the component will be enabled or disabled.
+ * @param componentClass The class of the component to be enabled or disabled.
+ * @param enable If true, the component will be enabled; if false, it will be disabled.
+ */
+ public static void toggleComponent(Context context, Class> componentClass, boolean enable) {
+ ComponentName componentName = new ComponentName(context, componentClass);
+ PackageManager packageManager = context.getPackageManager();
+ int currentState = packageManager.getComponentEnabledSetting(componentName);
+ int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+
+ if (currentState != newState) {
+ packageManager.setComponentEnabledSetting(
+ componentName,
+ newState,
+ PackageManager.DONT_KILL_APP
+ );
+ }
+ }
+}
diff --git a/parts/src/org/lineageos/settings/utils/FileUtils.java b/parts/src/org/lineageos/settings/utils/FileUtils.java
new file mode 100644
index 00000000..b2bc40dc
--- /dev/null
+++ b/parts/src/org/lineageos/settings/utils/FileUtils.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * 2025 The LineageOS 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 org.lineageos.settings.utils;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+public final class FileUtils {
+ private static final String TAG = "FileUtils";
+
+ private FileUtils() {
+ // This class is not supposed to be instantiated
+ }
+
+ /**
+ * Reads the first line of text from the given file.
+ * Reference {@link BufferedReader#readLine()} for clarification on what a line is
+ *
+ * @return the read line contents, or null on failure
+ */
+ public static String readOneLine(String fileName) {
+ String line = null;
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(fileName), 512);
+ line = reader.readLine();
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for reading", e);
+ } catch (IOException e) {
+ Log.e(TAG, "Could not read from file " + fileName, e);
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return line;
+ }
+
+ /**
+ * Writes the given value into the given file
+ *
+ * @return true on success, false on failure
+ */
+ public static boolean writeLine(String fileName, String value) {
+ BufferedWriter writer = null;
+
+ try {
+ writer = new BufferedWriter(new FileWriter(fileName));
+ writer.write(value);
+ writer.flush();
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for writing", e);
+ return false;
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether the given file exists
+ *
+ * @return true if exists, false if not
+ */
+ public static boolean fileExists(String fileName) {
+ final File file = new File(fileName);
+ return file.exists();
+ }
+
+ /**
+ * Checks whether the given file is readable
+ *
+ * @return true if readable, false if not
+ */
+ public static boolean isFileReadable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canRead();
+ }
+
+ /**
+ * Checks whether the given file is writable
+ *
+ * @return true if writable, false if not
+ */
+ public static boolean isFileWritable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canWrite();
+ }
+
+ /**
+ * Deletes an existing file
+ *
+ * @return true if the delete was successful, false if not
+ */
+ public static boolean delete(String fileName) {
+ final File file = new File(fileName);
+ boolean ok = false;
+ try {
+ ok = file.delete();
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to delete " + fileName, e);
+ }
+ return ok;
+ }
+
+ /**
+ * Renames an existing file
+ *
+ * @return true if the rename was successful, false if not
+ */
+ public static boolean rename(String srcPath, String dstPath) {
+ final File srcFile = new File(srcPath);
+ final File dstFile = new File(dstPath);
+ boolean ok = false;
+ try {
+ ok = srcFile.renameTo(dstFile);
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to rename " + srcPath + " to " + dstPath, e);
+ } catch (NullPointerException e) {
+ Log.e(TAG, "NullPointerException trying to rename " + srcPath + " to " + dstPath, e);
+ }
+ return ok;
+ }
+
+ /**
+ * Writes the given value into the given file.
+ * @return true on success, false on failure
+ */
+ public static boolean writeValue(String fileName, String value) {
+ BufferedWriter writer = null;
+
+ try {
+ writer = new BufferedWriter(new FileWriter(fileName));
+ writer.write(value);
+ writer.flush();
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for writing", e);
+ return false;
+ } catch (IOException e) {
+ Log.e(TAG, "Could not write to file " + fileName, e);
+ return false;
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Reads the value from the given file.
+ * @return the value read from the file, or the default value if an error occurs
+ */
+ public static String getFileValue(String fileName, String defaultValue) {
+ String value = defaultValue;
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(fileName), 512);
+ value = reader.readLine();
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "No such file " + fileName + " for reading", e);
+ } catch (IOException e) {
+ Log.e(TAG, "Could not read from file " + fileName, e);
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ // Ignored, not much we can do anyway
+ }
+ }
+
+ return value;
+ }
+}
+
+
diff --git a/parts/src/org/lineageos/settings/utils/TileUtils.java b/parts/src/org/lineageos/settings/utils/TileUtils.java
new file mode 100644
index 00000000..b3feff49
--- /dev/null
+++ b/parts/src/org/lineageos/settings/utils/TileUtils.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The LineageOS 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 org.lineageos.settings.utils;
+
+import android.app.StatusBarManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.drawable.Icon;
+import android.widget.Toast;
+
+import org.lineageos.settings.R;
+
+public class TileUtils {
+
+ public static void requestAddTileService(Context context, Class> tileServiceClass, int labelResId, int iconResId) {
+ ComponentName componentName = new ComponentName(context, tileServiceClass);
+ String label = context.getString(labelResId);
+ Icon icon = Icon.createWithResource(context, iconResId);
+
+ StatusBarManager sbm = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
+
+ if (sbm != null) {
+ sbm.requestAddTileService(
+ componentName,
+ label,
+ icon,
+ context.getMainExecutor(),
+ result -> handleResult(context, result)
+ );
+ }
+ }
+
+ private static void handleResult(Context context, Integer result) {
+ if (result == null)
+ return;
+ switch (result) {
+ case StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED:
+ Toast.makeText(context, R.string.tile_added, Toast.LENGTH_SHORT).show();
+ break;
+ case StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED:
+ Toast.makeText(context, R.string.tile_not_added, Toast.LENGTH_SHORT).show();
+ break;
+ case StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED:
+ Toast.makeText(context, R.string.tile_already_added, Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+}
diff --git a/proprietary-files.txt b/proprietary-files.txt
index 9e446bb5..93607d5c 100644
--- a/proprietary-files.txt
+++ b/proprietary-files.txt
@@ -1,4 +1,4 @@
-# All unpinned blobs below are extracted from garnet OS2.0.203.0.VNRMIXM
+# All unpinned blobs below are extracted from garnet OS2.0.206.0.VNRMIXM
# ACDB
vendor/etc/acdbdata/Mise/Mise_acdb_cal.acdb
@@ -35,7 +35,7 @@ vendor/lib/rfsa/adsp/libCalculator_skel.so
vendor/lib/rfsa/adsp/libMIAIHDR_skel.so
vendor/lib/rfsa/adsp/libQnnHtpV69.so
vendor/lib/rfsa/adsp/libQnnHtpV69Skel.so
-vendor/lib/rfsa/adsp/libQnnSaver.so
+vendor/lib/rfsa/adsp/libQnnSaver.so;MODULE_SUFFIX=_adsp
vendor/lib/rfsa/adsp/libSnpeDspV65Skel.so
vendor/lib/rfsa/adsp/libSnpeDspV66Skel.so
vendor/lib/rfsa/adsp/libSnpeHtpV68Skel.so
@@ -232,35 +232,6 @@ vendor/lib64/vendor.qti.latency@2.1.so
# Camera
odm/etc/camera/camerabooster.json
odm/etc/camera/camerascene.json
-odm/etc/camera/videofilter/110_BlackGold.png
-odm/etc/camera/videofilter/129_LeicaVivid.png
-odm/etc/camera/videofilter/130_LeicaNatural.png
-odm/etc/camera/videofilter/131_MonochromeTrue.png
-odm/etc/camera/videofilter/132_MonochromeHighContrast.png
-odm/etc/camera/videofilter/133_MonochromeBrown.png
-odm/etc/camera/videofilter/134_MonochromeBlue.png
-odm/etc/camera/videofilter/144_RedHero.png
-odm/etc/camera/videofilter/146_TactileGreen.png
-odm/etc/camera/videofilter/148_Mild.png
-odm/etc/camera/videofilter/149_LilyWhite.png
-odm/etc/camera/videofilter/150_Bright.png
-odm/etc/camera/videofilter/151_Fresh.png
-odm/etc/camera/videofilter/152_Limpid.png
-odm/etc/camera/videofilter/153_KC64.png
-odm/etc/camera/videofilter/154_V250.png
-odm/etc/camera/videofilter/155_H400.png
-odm/etc/camera/videofilter/156_ColdWhite.png
-odm/etc/camera/videofilter/157_Native.png
-odm/etc/camera/videofilter/158_BWClassical.png
-odm/etc/camera/videofilter/159_Flowers.png
-odm/etc/camera/videofilter/160_Vivid.png
-odm/etc/camera/videofilter/161_KP160.png
-odm/etc/camera/videofilter/162_Natural.png
-odm/etc/camera/videofilter/163_KG200.png
-odm/etc/camera/videofilter/164_FC400.png
-odm/etc/camera/videofilter/165_C50D.png
-odm/etc/camera/videofilter/166_F50.png
-odm/lib64/libMiVideoFilter.so
odm/lib64/librfs_warp.so
vendor/bin/hw/vendor.qti.camera.provider@2.7-service_64
vendor/bin/hw/vendor.xiaomi.hardware.quickcamera@1.0-service
@@ -652,7 +623,6 @@ vendor/lib64/camera/components/com.mi.node.superiq.so
vendor/lib64/camera/components/com.mi.node.test_rearvideo.so
vendor/lib64/camera/components/com.mi.node.tsskinbeautifier.so
vendor/lib64/camera/components/com.mi.node.videobokeh.so
-vendor/lib64/camera/components/com.mi.node.videofilter.so
vendor/lib64/camera/components/com.qti.camx.chiiqutils.so
vendor/lib64/camera/components/com.qti.eisv2.so
vendor/lib64/camera/components/com.qti.eisv3.so
@@ -1048,6 +1018,34 @@ vendor/lib64/camera/com.qti.tuned.garnet_sunny_s5khp3_wide_global_i.bin
vendor/lib64/camera/com.qti.tuned.garnet_sunny_s5khp3_wide_i.bin
vendor/lib64/hw/com.qti.chi.override.so
+# Camera Video Filter LUts
+vendor/etc/camera/102_SummerDay.png|854075e4570bbf561063a096dae0fe9d2151809d
+vendor/etc/camera/103_Fantasy.png|0eb52c60f767c4a9b26b22f4ee35ec646545a123
+vendor/etc/camera/104_Meet.png|f72dbf0c125237acb41a115dab40233e275fcf92
+vendor/etc/camera/105_WindSing.png|8d07722a63e5619fbd3b293078ae67dfe271a72c
+vendor/etc/camera/106_Lost.png|61a35b9eb3c6286357ba213cfce0b3e1fc112fd6
+vendor/etc/camera/107_Central.png|64c1e291c873ff7715ee9017c3a0d6cae48a9b6a
+vendor/etc/camera/108_NorthernEurope.png|ae5c9c7ad2e37d4e924bac229af1577be8b2595b
+vendor/etc/camera/109_Rome.png|6a46690036b8e6925b51b1b4c2a687870e486b87
+vendor/etc/camera/110_BlackGold.png|41f2757306323470f32c3a07356362e6903b7b02
+vendor/etc/camera/111_GreenOrange.png|7ccb8c48068296275ab440129750cddc47e26f4d
+vendor/etc/camera/112_CyberPunk.png|a8245aafb5cf4a2bf2aa1ed58ad35dc3140607bb
+vendor/etc/camera/113_BlackIce.png|00bb1b9b499aca960475b79414b5a076324c8b46
+vendor/etc/camera/121_Bleach.png|7cae58047cf3bd9854510cd54cd11c6c0e442f75
+vendor/etc/camera/122_Thriller.png|d73f8b11a3f45a0a646eb5d71b6a1d5bf72e90d3
+vendor/etc/camera/123_TealOrange.png|c7acfd64e602235ef26c0051cc125b15a2d6437b
+vendor/etc/camera/124_JapaneseStyle.png|7dfec84eb0a7728e2503a7d260634e0f26011364
+vendor/etc/camera/125_Latin.png|eac04636de0aeac2480a3be9d1f0e04f58ddfd0b
+vendor/etc/camera/126_Fantasy2.png|8b94fd32b66b3e88129618612f2603b9bdc0b3c9
+vendor/etc/camera/127_Creamy.png|71d1a5bc75edad2eb29ef58b1e41a18c55e5f609
+vendor/etc/camera/128_Sepia.png|ac5cf27142b07425c0775e8939ae2d99524ed622
+vendor/etc/camera/129_Vivid.png|5da99b1616af1d61a62c9e296a5b2e51951e1769
+vendor/etc/camera/130_Natural.png|e6b9363ca508adc198681356ad343c1e29bc695a
+
+# Camera Video Filter Libraries
+vendor/lib64/libMiVideoFilter.so|7a7c64e8bbb4268414bc491ec3668132d60bfdbc|ab5942405e6129c10c42b5c599db610791daa5c2
+vendor/lib64/camera/components/com.mi.node.videofilter.so|503b5bcdc2c0be330c83b5823f54b2a0489f927e
+
# Computer vision
vendor/lib64/libcv_common.so
vendor/lib64/libcvp2_1.so
@@ -1192,12 +1190,12 @@ vendor/bin/qdcmss|727147cbaf4d74f0eb38c534fda9beebdfec31f6
vendor/etc/init/qdcmss.rc|53d78d686678c4f923a9ec4ace7d4d3575b13788
vendor/lib64/libbacklight-calib.so|a5990fa87932196f9e2c38b2ec85786daa6b3a9c
vendor/lib64/libdigital-dimming.so|66506a386dc80da0994c9d4aeac34edfc1830c5c
-vendor/lib64/libdpps.so|d8e9cc561a3ab706697880975413db23bb41640c
+vendor/lib64/libdpps.so|d8e9cc561a3ab706697880975413db23bb41640c|5d3e5f10ce5adff610e67acd837b19a551412876
vendor/lib64/libmemutils.so|e122c3ff95b10a6263e698261abafe62cee98010
vendor/lib64/libqdcm-algo.so|e873dc21878d92d20f6937453c9d3265a0d3a93d
vendor/lib64/libqdcm-json-mode-parser.so|1c8f1a841a877efbed0a0b3db3d551ff1283f14f
vendor/lib64/libqdcm-mode-parser.so|341178dfb18e03b6fabff27a080fb96f15188942
-vendor/lib64/libsnapdragoncolor-manager.so|72291478bd56bada0fc3df3617e765b28ef54f66
+vendor/lib64/libsnapdragoncolor-manager.so|72291478bd56bada0fc3df3617e765b28ef54f66|ba9a38c02dae4cc2211895714969c589faaff1f4
vendor/lib64/libsnapdragoncolor-qdcm.so|9f0bc72290618324e95cd9f4eca6987a6733bd06
# Display SDM - from ingot-user 14 UKQ1.240227.165 release-keys
@@ -1356,6 +1354,9 @@ vendor/etc/init/android.hardware.gatekeeper@1.0-service-qti.rc
vendor/lib64/hw/android.hardware.gatekeeper@1.0-impl-qti.so
# Graphics (Adreno)
+vendor/etc/permissions/android.hardware.vulkan.version-1_3.xml:vendor/etc/permissions/android.hardware.vulkan.version-1_3.xml
+vendor/etc/permissions/android.software.opengles.deqp.level.xml
+vendor/etc/permissions/android.software.vulkan.deqp.level.xml
vendor/gpu/kbc/sequence_manifest.bin
vendor/gpu/kbc/unified_kbcs_32.bin
vendor/gpu/kbc/unified_kbcs_64.bin
@@ -1367,6 +1368,9 @@ vendor/lib/egl/libGLESv2_adreno.so;SYMLINK=vendor/lib/libGLESv2_adreno.so
vendor/lib/egl/libVkLayer_ADRENO_qprofiler.so
vendor/lib/egl/libq3dtools_adreno.so;SYMLINK=vendor/lib/libq3dtools_adreno.so
vendor/lib/egl/libq3dtools_esx.so
+vendor/lib/libOpenCL_adreno.so
+vendor/lib/libadreno_compiler_cl.so
+vendor/lib/libdmabufheap.so
vendor/lib/libCB.so
vendor/lib/libOpenCL.so
vendor/lib/libadreno_app_profiles.so
@@ -1385,6 +1389,7 @@ vendor/lib64/egl/libGLESv2_adreno.so;SYMLINK=vendor/lib64/libGLESv2_adreno.so
vendor/lib64/egl/libVkLayer_ADRENO_qprofiler.so
vendor/lib64/egl/libq3dtools_adreno.so;SYMLINK=vendor/lib64/libq3dtools_adreno.so
vendor/lib64/egl/libq3dtools_esx.so
+vendor/lib64/egl/libPipeline_plugin.so
vendor/lib64/libCB.so
vendor/lib64/libOpenCL.so
vendor/lib64/libadreno_app_profiles.so
@@ -1396,6 +1401,10 @@ vendor/lib64/libkernelmanager.so
vendor/lib64/libllvm-glnext.so
vendor/lib64/libllvm-qcom.so
vendor/lib64/libllvm-qgl.so
+vendor/lib64/libOpenCL_adreno.so
+vendor/lib64/libadreno_compiler_cl.so
+vendor/lib64/libdmabufheap.so
+vendor/lib64/libgamepoweroptfeature.so
# Graphics (Adreno firmware)
vendor/firmware/a710_sqe.fw
@@ -1406,9 +1415,15 @@ vendor/firmware/a710_zap.elf
vendor/firmware/a710_zap.mbn
vendor/firmware/a710_zap.mdt
vendor/firmware/gmu_gen70000.bin
+vendor/firmware/a630_sqe.fw
+vendor/firmware/a650_sqe.fw
+vendor/firmware/a660_sqe.fw
+vendor/firmware/a730_sqe.fw
+vendor/firmware/gen71100_sqe.fw
# Graphics (Vulkan)
vendor/lib64/hw/vulkan.adreno.so
+vendor/lib/hw/vulkan.adreno.so
# Hotword enrollment
product/etc/permissions/privapp-permissions-google-audio-system.xml:product/etc/permissions/privapp-permissions-hotword.xml
@@ -1519,7 +1534,32 @@ vendor/lib64/libqcodec2_v4l2codec.so
vendor/lib64/libvideotxr.so
vendor/lib64/qti.video.utils.videobufferlayout.so
+# Media (Dolby)
+vendor/etc/dolby/dax-default.xml
+
+# Media (Dolby) - YUDI_OS1.0.2.0.UMHCNXM
+vendor/etc/init/vendor.dolby.hardware.dms@2.0-service.rc|29296ebfe89b2697fec573be73cc3757fd97bed6
+vendor/etc/init/vendor.dolby.media.c2@1.0-service.rc|bc1e134139c7dd0e5b4f98952aa51c629ea66dc7
+vendor/etc/media_codecs_dolby_audio.xml|3119c61cc5471bb7902ac8b1ccd5785bb55a1918
+vendor/etc/vintf/manifest/vendor.dolby.hardware.dms.xml|c8095f649de19b80271fb429b4b6b439297a0678
+vendor/bin/hw/vendor.dolby.hardware.dms@2.0-service|556fa97b7fc5a3a8efd89aa413a4e6b508a9425e|f2bdf53f4d9ccc269a0df097e4b0acc7f3badb89
+vendor/bin/hw/vendor.dolby.media.c2@1.0-service|27e7aed8b219b082a66b8150e018f1db1c2bbcd8|e2afe22b6633f0b19fb39830c82c871cc0bc4d60
+vendor/lib64/libcodec2_soft_ac4dec.so|3f7da3e48b391f94e3e4aedbbea514eb5f4283ed
+vendor/lib64/libcodec2_soft_ddpdec.so|55275a7abcfde2d3f44fc48f9dd7a976fb98ebc1
+vendor/lib64/libcodec2_store_dolby.so|d0a85979f9c622cc5ad4071635271fe51c9ecb55
+vendor/lib64/libdapparamstorage.so|6dd6cf3bd92710cdba1cb981b52e64dca2407bd1
+vendor/lib64/libdeccfg.so|8ef3036d0b7a5f2caae277e21b5cf5174b2f085f
+vendor/lib64/libdlbdsservice.so|d4f9aa59644b1f90b221f188fc25a0b54db84c39|905fa82fbb586ff70db2c665546f01d4844e481c
+vendor/lib64/libdlbpreg.so|e1588ec15d1b328c037ffd2f80c426dcd90d6467|464e56435f739fc4f7a1f953e19feaeec7a06850
+vendor/lib64/soundfx/libdlbvol.so|1ebd52ecc1a42e1ec0eb785e541b08d191bf9924|56a4fbd854097e4b3b151e9ad94056699e55e623
+vendor/lib64/soundfx/libhwdap.so|1058720b5930196370e1e792a14e60e16c9a46e1|42dcf6149366ff1e8f3679d771bdcb14bb62a599
+vendor/lib64/soundfx/libswgamedap.so|cac12e23c860270775986d56c8f9b8f58ac07be3
+vendor/lib64/soundfx/libswvqe.so|bcfc527b34066600c4b747cced45ab8012e4c1a5
+vendor/lib64/vendor.dolby.hardware.dms@2.0-impl.so|63db226e3f51448c094ef00ec9a92be089050219
+vendor/lib64/vendor.dolby.hardware.dms@2.0.so|e5c3409c9422297055cc79eff526e625be79ac32
+
# Media Config
+vendor/etc/media_codecs_c2_audio.xml
vendor/etc/media_codecs_parrot_v0.xml
vendor/etc/media_codecs_performance_parrot_v0.xml
vendor/etc/media_parrot_v0/video_system_specs.json
@@ -1533,11 +1573,6 @@ vendor/etc/vintf/manifest/manifest_vendor.xiaomi.hardware.mlipay.xml
vendor/lib64/libmlipay.so
vendor/lib64/libmlipay@1.1.so
-# Modem manager
-vendor/bin/modemManager
-vendor/etc/init/modemManager.rc
-vendor/etc/seccomp_policy/modemManager.policy
-
# NFC
vendor/etc/libnfc-nci.conf
vendor/etc/libnfc-nxp.conf
@@ -1625,25 +1660,6 @@ vendor/lib64/libsubsystem_control.so
vendor/bin/init.qti.qcv.sh
vendor/etc/init/init.qti.qcv.rc
-# QESDK
-vendor/bin/qesdk-manager
-vendor/bin/sensors-qesdk
-vendor/etc/init/qesdk-manager.rc
-vendor/etc/init/vendor.sensors.qesdk.rc
-vendor/etc/seccomp_policy/qesdk.policy
-vendor/etc/seccomp_policy/sensors-qesdk.policy
-vendor/lib64/libqesdk.so
-vendor/lib64/libqesdk_manager.so
-vendor/lib64/vendor.qti.qesdhal@1.0.so
-vendor/lib64/vendor.qti.qesdhal@1.1-impl.so
-vendor/lib64/vendor.qti.qesdhal@1.1.so
-vendor/lib64/vendor.qti.qesdsys-V1-ndk_platform.so
-
-# QGuard
-vendor/bin/qguard
-vendor/etc/init/qguard.rc
-vendor/etc/qguard.json
-
# QMI
system/etc/sysconfig/qti_whitelist.xml
system_ext/etc/sysconfig/qti_telephony_system_packages_config.xml
@@ -1715,6 +1731,7 @@ system_ext/etc/permissions/qcrilhook.xml
system_ext/etc/permissions/qti_permissions.xml
system_ext/etc/permissions/telephony_system-ext_privapp-permissions-qti.xml
system_ext/etc/permissions/vendor.qti.ims.rcsservice.xml
+system_ext/framework/mirilhook.jar
system_ext/framework/qcrilhook.jar
system_ext/framework/vendor.qti.ims.connection-V1.0-java.jar
system_ext/framework/vendor.qti.ims.connectionaidlservice-V1-java.jar
@@ -2063,6 +2080,7 @@ vendor/bin/thermal-engine-v2
vendor/etc/init/hw/init.mi_thermald.rc
vendor/etc/init/init_thermal-engine-v2.rc
vendor/etc/thermal-4k.conf
+vendor/etc/thermal-boost.conf
vendor/etc/thermal-camera.conf
vendor/etc/thermal-cclassvideo.conf
vendor/etc/thermal-cgame.conf
diff --git a/props/system.prop b/props/system.prop
index 6f4b4cec..47ffea50 100644
--- a/props/system.prop
+++ b/props/system.prop
@@ -1,3 +1,12 @@
+# Battery Saving
+persist.radio.add_power_save=1
+pm.sleep_mode=1
+ro.ril.disable.power.collapse=0
+ro.ril.fast.dormancy.rule=1
+ro.ril.fast.dormancy.timeout=3
+ro.mot.eri.losalert.delay=100
+ro.vold.umsdirtyratio=20
+
# CNE
persist.vendor.cne.feature=1
diff --git a/props/vendor.prop b/props/vendor.prop
index 62348bdb..fb1aa226 100644
--- a/props/vendor.prop
+++ b/props/vendor.prop
@@ -42,7 +42,7 @@ vendor.audio.feature.dmabuf.cma.memory.enable=true
vendor.audio.feature.hfp.enable=false
vendor.audio.feature.kpi_optimize.enable=true
vendor.audio.hdr.record.enable=false
-vendor.audio.offload.buffer.size.kb=32
+vendor.audio.offload.buffer.size.kb=256
vendor.audio.safx.pbe.enabled=false
vendor.audio.ull_record_period_multiplier=2
vendor.audio.ultrasound.stoplatency=60
@@ -86,6 +86,13 @@ ro.hardware.camera=xiaomi
# Chipset
ro.soc.manufacturer=QTI
+# Dex2oat
+dalvik.vm.dex2oat64.enabled=true
+dalvik.vm.dex2oat-cpu-set=4,5,6,7
+dalvik.vm.dex2oat-threads=4
+dalvik.vm.image-dex2oat-cpu-set=4,5,6,7
+dalvik.vm.image-dex2oat-threads=4
+
# Display
ro.vendor.display.sensortype=2
ro.vendor.display.svi=1
@@ -117,9 +124,6 @@ persist.vendor.dpm.vndr.idletimer.mode=default
persist.vendor.fingerprint.type=udfps_optical
persist.vendor.fingerprint.sensor_location=610|2437|105
-# FRP
-ro.frp.pst=/dev/block/bootdevice/by-name/frp
-
# FUSE
persist.sys.fuse.passthrough.enable=true
@@ -129,37 +133,50 @@ vendor.gatekeeper.disable_spu=true
# Graphics
debug.sf.auto_latch_unsignaled=0
debug.sf.disable_client_composition_cache=1
+debug.sf.enable_transaction_tracing=false
+debug.sf.enable_gl_backpressure=0
+debug.sf.hw=0
+debug.sf.predict_hwc_composition_strategy=0
+debug.sf.set_idle_timer_ms=0
+debug.sf.treat_170m_as_sRGB=1
debug.sf.early.app.duration=16500000
debug.sf.early.sf.duration=16000000
debug.sf.earlyGl.app.duration=21000000
debug.sf.earlyGl.sf.duration=13500000
-debug.sf.enable_gl_backpressure=1
+debug.sf.enable_gl_backpressure=0
debug.sf.enable_hwc_vds=1
debug.sf.hw=0
+debug.sf.enable_adpf_cpu_hint=true
debug.sf.late.app.duration=20500000
debug.sf.late.sf.duration=10500000
-debug.sf.predict_hwc_composition_strategy=0
-debug.sf.set_idle_timer_ms=1100
-debug.sf.treat_170m_as_sRGB=1
debug.sf.use_phase_offsets_as_durations=1
+debug.sf.defer_refresh_rate_when_off=1
+debug.sf.enable_egl_image_tracker=0
+persist.mm.enable.prefetch=true
persist.sys.sf.color_mode=0
persist.sys.sf.color_saturation=1.0
+ro.gfx.driver.1=com.qualcomm.qti.gpudrivers.pineapple.api34
+persist.sys.force_vulkan=1
+persist.sys.purgeable_assets=1
+ro.surface_flinger.set_display_power_timer_ms=1000
+ro.surface_flinger.set_idle_timer_ms=4000
persist.sys.sf.native_mode=258
ro.hardware.egl=adreno
ro.hardware.vulkan=adreno
ro.opengles.version=196610
ro.surface_flinger.enable_frame_rate_override=false
ro.surface_flinger.force_hwc_copy_for_virtual_displays=true
+ro.surface_flinger.game_default_frame_rate_override=120
ro.surface_flinger.has_HDR_display=true
ro.surface_flinger.has_wide_color_display=true
-ro.surface_flinger.max_frame_buffer_acquired_buffers=3
ro.surface_flinger.max_virtual_display_dimension=4096
ro.surface_flinger.protected_contents=true
ro.surface_flinger.set_touch_timer_ms=200
-ro.surface_flinger.supports_background_blur=1
+ro.surface_flinger.supports_background_blur=0
ro.surface_flinger.use_color_management=true
ro.surface_flinger.use_content_detection_for_refresh_rate=true
ro.surface_flinger.wcg_composition_dataspace=142671872
+ro.surface_flinger.clear_slots_with_set_layer_buffer=true
vendor.gralloc.disable_ubwc=0
# Keystore
@@ -170,8 +187,22 @@ debug.c2.use_dmabufheaps=1
debug.stagefright.c2inputsurface=-1
ro.media.xml_variant.profiles=_parrot_v0
+# Media (Dolby)
+ro.vendor.audio.dolby.dax.support=true
+ro.vendor.audio.dolby.surround.enable=true
+vendor.audio.dolby.ds2.enabled=false
+vendor.audio.dolby.ds2.hardbypass=false
+debug.sdm.support_writeback=0
+
+# Netflix
+ro.netflix.bsp_rev=Q6450-36256-1
+
# Perf
ro.vendor.extension_library=libqti-perfd-client.so
+vendor.perf.framepacing.enable=1
+
+# Ram
+persist.sys.purgeable_assets=1
# Qcomd
persist.vendor.qcomsysd.enabled=1
@@ -216,3 +247,41 @@ persist.vendor.vcb.enable=false
# WLAN
wifi.aware.interface=wifi-aware0
+
+# Netflix
+vendor.netflix.bsp_rev=Q6450-36256-1
+
+# Fling
+ro.min.fling_velocity=160
+ro.max.fling_velocity=20000
+ro.vendor.qti.cgroup_follow.enable=true
+persist.vendor.qti.inputopts.enable=true
+persist.vendor.qti.inputopts.movetouchslop=0.6
+ro.qcom.adreno.qgl.ShaderStorageImageExtendedFormats=0
+
+# HWUI
+ro.hwui.render_ahead=15
+ro.hwui.drop_shadow_cache_size=6
+ro.hwui.gradient_cache_size=1
+ro.hwui.layer_cache_size=48
+ro.hwui.path_cache_size=32
+ro.hwui.r_buffer_cache_size=8
+ro.hwui.text_large_cache_height=1024
+ro.hwui.text_large_cache_width=2048
+ro.hwui.text_small_cache_height=1024
+ro.hwui.text_small_cache_width=1024
+ro.hwui.texture_cache_flushrate=0.4
+ro.hwui.texture_cache_size=72
+debug.hwui.use_hint_manager=true
+debug.hwui.target_cpu_time_percent=30
+debug.hwui.renderer=skiavk
+debug.hwui.show_overdraw=false
+debug.hwui.use_triple_buffering=true
+debug.hwui.vulkan.use_pipeline_cache=true
+debug.renderengine.vulkan=true
+debug.renderengine.backend=vulkan
+renderthread.skia.reduceopstasksplitting=true
+debug.gralloc.enable_fb_ubwc=1
+
+# Performance
+debug.performance.tuning=1
diff --git a/rootdir/etc/init.garnet.rc b/rootdir/etc/init.garnet.rc
index 3a9176e4..9d717c7f 100644
--- a/rootdir/etc/init.garnet.rc
+++ b/rootdir/etc/init.garnet.rc
@@ -31,6 +31,11 @@ on boot
chmod 0700 /sys/bus/platform/devices/soc:fingerprint_fpc/screen
chmod 0666 /dev/input/event2
+on post-fs
+ # Workarround for cache
+ rm /data/resource-cache
+ rm /data/system/package_cache
+
on post-fs-data
mkdir /data/vendor/misc 01771 system system
mkdir /data/vendor/misc/mi_fp 0770 system system
diff --git a/rootdir/etc/init.qcom.rc b/rootdir/etc/init.qcom.rc
index a838a566..53e0d00d 100644
--- a/rootdir/etc/init.qcom.rc
+++ b/rootdir/etc/init.qcom.rc
@@ -540,6 +540,11 @@ on property:vold.decrypt=trigger_restart_framework
start qcom-c_main-sh
start wcnss-service
+on post-fs-data
+ # Charge Bypass
+ chown system system /sys/class/qcom-battery/input_suspend
+ chmod 0660 /sys/class/qcom-battery/input_suspend
+
service vendor.qrtr-ns /vendor/bin/qrtr-ns -f
class core
user vendor_qrtr
diff --git a/sepolicy/private/parts_app.te b/sepolicy/private/parts_app.te
new file mode 100644
index 00000000..299f3521
--- /dev/null
+++ b/sepolicy/private/parts_app.te
@@ -0,0 +1,36 @@
+type parts_app, domain;
+typeattribute parts_app mlstrustedsubject;
+
+app_domain(parts_app)
+
+binder_use(parts_app)
+
+allow parts_app {
+ activity_service
+ activity_task_service
+ audio_service
+ audioserver_service
+ autofill_service
+ batteryproperties_service
+ batterystats_service
+ content_capture_service
+ game_service
+ gpu_service
+ hint_service
+ media_session_service
+ netstats_service
+ radio_service
+ trust_service
+ sensorservice_service
+ surfaceflinger_service
+ vendor_perf_service
+ vibrator_manager_service
+ voiceinteraction_service
+}:service_manager find;
+
+allow parts_app system_app_data_file:dir create_dir_perms;
+allow parts_app system_app_data_file:{
+ file
+ lnk_file
+} create_file_perms;
+
diff --git a/sepolicy/private/property_contexts b/sepolicy/private/property_contexts
new file mode 100644
index 00000000..e71213ae
--- /dev/null
+++ b/sepolicy/private/property_contexts
@@ -0,0 +1,12 @@
+ro.camera.req.fmq. u:object_r:exported_default_prop:s0
+ro.camera.res.fmq. u:object_r:exported_default_prop:s0
+camera.test.auto u:object_r:exported_default_prop:s0
+ro.vendor.aware_available u:object_r:exported_default_prop:s0
+ro.hardware.chipname u:object_r:exported_default_prop:s0
+
+ro.miui.region u:object_r:exported_system_prop:s0
+ro.miui.build.region u:object_r:exported_system_prop:s0
+ro.miui.cust_device u:object_r:exported_system_prop:s0
+
+persist.camera.aiasd.isovalue u:object_r:vendor_persist_camera_prop:s0
+persist.vendor.low.cutoff u:object_r:vendor_persist_camera_prop:s0
diff --git a/sepolicy/private/seapp_contexts b/sepolicy/private/seapp_contexts
new file mode 100644
index 00000000..097472e9
--- /dev/null
+++ b/sepolicy/private/seapp_contexts
@@ -0,0 +1,2 @@
+# EuiccGarnet
+user=system seinfo=platform isPrivApp=true name=com.xiaomi.settings domain=parts_app type=system_app_data_file levelFrom=all
diff --git a/sepolicy/vendor/attributes b/sepolicy/vendor/attributes
new file mode 100644
index 00000000..3bbbd70a
--- /dev/null
+++ b/sepolicy/vendor/attributes
@@ -0,0 +1,9 @@
+# Mi Cam
+attribute vendor_hal_camerapostproc_xiaomi;
+attribute vendor_hal_camerapostproc_xiaomi_client;
+attribute vendor_hal_camerapostproc_xiaomi_server;
+
+# Dolby
+attribute hal_dms;
+attribute hal_dms_client;
+attribute hal_dms_server;
diff --git a/sepolicy/vendor/file.te b/sepolicy/vendor/file.te
index 2291b21b..6f45698a 100644
--- a/sepolicy/vendor/file.te
+++ b/sepolicy/vendor/file.te
@@ -18,5 +18,8 @@ type sys_thermal_max_brightness, fs_type, sysfs_type;
type sys_thermal_wifi_limit, fs_type, sysfs_type;
type thermal_data_file, data_file_type, file_type;
+# Walt
+type proc_walt, fs_type, proc_type;
+
# Wifi
type vendor_mac_vendor_data_file, data_file_type, file_type, mlstrustedobject;
diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts
index 787ce638..b810995b 100644
--- a/sepolicy/vendor/file_contexts
+++ b/sepolicy/vendor/file_contexts
@@ -23,6 +23,11 @@
/vendor/lib(64)?/libcalculator\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libcalculator_htp\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libhta_hexagon_runtime_snpe\.so u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libprocessgroup_shim\.so u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libgui_shim\.so u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libmialgoengine\.so u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libmialgo_.*\.so u:object_r:same_process_hal_file:s0
+/vendor/lib(64)?/libcamera_algoup_jni\.xiaomi\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libmialgo_ai_vision\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libmialgo_utils\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libomp\.so u:object_r:same_process_hal_file:s0
@@ -41,6 +46,11 @@
/dev/mi_display/disp_feature u:object_r:vendor_displayfeature_device:s0
/sys/devices/virtual/mi_display/disp_feature/disp-DSI-+[0-1](/.*)? u:object_r:vendor_sysfs_displayfeature:s0
+# Dolby
+/(vendor|system/vendor)/bin/hw/vendor\.dolby\.hardware\.dms@2\.0-service u:object_r:hal_dms_default_exec:s0
+/(vendor|system/vendor)/bin/hw/vendor\.dolby\.media\.c2@1\.0-service u:object_r:mediacodec_exec:s0
+/data/vendor/dolby(/.*)? u:object_r:vendor_data_file:s0
+
# Fingerprint
/vendor/bin/hw/android\.hardware\.biometrics\.fingerprint-service\.xiaomi u:object_r:hal_fingerprint_default_exec:s0
/data/vendor/fpc(/.*)? u:object_r:vendor_fingerprint_data_file:s0
diff --git a/sepolicy/vendor/genfs_contexts b/sepolicy/vendor/genfs_contexts
index b1ab1cf1..3f906493 100644
--- a/sepolicy/vendor/genfs_contexts
+++ b/sepolicy/vendor/genfs_contexts
@@ -7,6 +7,16 @@ genfscon sysfs /devices/platform/soc/soc:spf_core_platform/soc:spf_core_platform
# Fingerprint
genfscon sysfs /devices/platform/soc/soc:fingerprint_fpc u:object_r:vendor_sysfs_fingerprint:s0
genfscon sysfs /devices/virtual/touch/touch_dev/fod_press_status u:object_r:sysfs_tp_fodstatus:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup26 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup9 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup8 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup11 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup15 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup16 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup19 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup22 u:object_r:sysfs_wakeup:s0
+genfscon sysfs /devices/platform/soc/soc:fpc1020/wakeup/wakeup23 u:object_r:sysfs_wakeup:s0
# Sensors
genfscon sysfs /devices/virtual/touch/touch_dev/fod_longpress_gesture_enabled u:object_r:vendor_sysfs_sensors:s0
@@ -25,3 +35,6 @@ genfscon sysfs /devices/platform/soc/a94000.qcom,qup_uart/wakeup u:object_r:sysf
genfscon sysfs /devices/platform/soc/c42d000.qcom,spmi/spmi-0/0-00/c42d000.qcom,spmi:qcom,pmk8350@0:pon_hlos@1300/c42d000.qcom,spmi:qcom,pmk8350@0:pon_hlos@1300:pwrkey-bark/wakeup u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/platform/soc/c42d000.qcom,spmi/spmi-0/0-00/c42d000.qcom,spmi:qcom,pmk8350@0:pon_hlos@1300/c42d000.qcom,spmi:qcom,pmk8350@0:pon_hlos@1300:pwrkey-resin-bark/wakeup u:object_r:sysfs_wakeup:s0
genfscon sysfs /devices/platform/soc/soc:fingerprint_goodix/wakeup u:object_r:sysfs_wakeup:s0
+
+# Walt
+genfscon proc /sys/walt u:object_r:proc_walt:s0
diff --git a/sepolicy/vendor/hal_audio.te b/sepolicy/vendor/hal_audio.te
index a1a5b499..78bd03d9 100644
--- a/sepolicy/vendor/hal_audio.te
+++ b/sepolicy/vendor/hal_audio.te
@@ -3,4 +3,6 @@ allow hal_audio_default hal_sensors_default:unix_stream_socket connectto;
allow hal_audio_default smartpa_type:file r_file_perms;
allow hal_audio_default vendor_persist_audio_file:file rw_file_perms;
+hal_client_domain(hal_audio_default, hal_dms)
+
set_prop(hal_audio_default, vendor_audio_prop)
diff --git a/sepolicy/vendor/hal_camera.te b/sepolicy/vendor/hal_camera.te
index 851d6b00..2f5e9ab8 100644
--- a/sepolicy/vendor/hal_camera.te
+++ b/sepolicy/vendor/hal_camera.te
@@ -1,6 +1,3 @@
-attribute vendor_hal_camerapostproc_xiaomi;
-attribute vendor_hal_camerapostproc_xiaomi_client;
-attribute vendor_hal_camerapostproc_xiaomi_server;
type hal_quickcamera_hwservice, hwservice_manager_type;
type vendor_hal_camerapostproc_xiaomi_hwservice, hwservice_manager_type;
@@ -28,8 +25,10 @@ allow vendor_hal_camerapostproc_xiaomi_server vendor_hal_camerapostproc_xiaomi_c
allow vendor_hal_camerapostproc_xiaomi_server vendor_hal_camerapostproc_xiaomi_client:binder { call transfer };
allow vendor_hal_camerapostproc_xiaomi_server vendor_hal_camerapostproc_xiaomi_client:fd *;
get_prop(hal_camera_default, serialno_prop)
+hal_client_domain(hal_camera_default, hal_power)
hal_server_domain(hal_camera_default, vendor_hal_camerapostproc_xiaomi)
r_dir_file(hal_camera_default, mnt_vendor_file)
r_dir_file(hal_camera_default, vendor_persist_sensors_file)
set_prop(hal_camera_default, vendor_camera_p3enable_prop)
set_prop(hal_camera_default, vendor_camera_sensor_prop)
+set_prop(hal_camera_default, vendor_camera_prop)
diff --git a/sepolicy/vendor/hal_camera_default.te b/sepolicy/vendor/hal_camera_default.te
new file mode 100644
index 00000000..6924104b
--- /dev/null
+++ b/sepolicy/vendor/hal_camera_default.te
@@ -0,0 +1,17 @@
+binder_call(hal_camera_default, platform_app)
+
+hal_client_domain(hal_camera_default, vendor_hal_qspnhal)
+
+allow hal_camera_default proc_pressure_cpu:file r_file_perms;
+allow hal_camera_default proc_pressure_mem:file r_file_perms;
+allow hal_camera_default proc_meminfo:file r_file_perms;
+allow hal_camera_default proc_pressure_io:file r_file_perms;
+
+allow hal_camera_default vendor_sysfs_kgsl:file r_file_perms;
+allow hal_camera_default vendor_sysfs_kgsl:dir r_dir_perms;
+
+allow hal_camera_default sysfs_devices_system_cpu:file r_file_perms;
+
+allow hal_camera_default sysfs:file { read open getattr };
+allow hal_camera_default proc_meminfo:file r_file_perms;
+allow hal_camera_default proc_pressure_cpu:file r_file_perms;
diff --git a/sepolicy/vendor/hal_dms.te b/sepolicy/vendor/hal_dms.te
new file mode 100644
index 00000000..e610c5cb
--- /dev/null
+++ b/sepolicy/vendor/hal_dms.te
@@ -0,0 +1,24 @@
+type hal_dms_default, domain;
+type hal_dms_default_exec, exec_type, file_type, vendor_file_type;
+type hal_dms_hwservice, hwservice_manager_type;
+
+init_daemon_domain(hal_dms_default)
+
+hal_attribute_hwservice(hal_dms, hal_dms_hwservice)
+hal_server_domain(hal_dms_default, hal_dms)
+
+add_hwservice(hal_dms_server, hal_dms_hwservice)
+
+binder_call(hal_dms_client, hal_dms_server)
+binder_call(hal_dms_server, hal_dms_client)
+
+allow hal_dms_default hal_dms_hwservice:hwservice_manager add;
+
+allow hal_dms_default vendor_data_file:dir rw_dir_perms;
+allow hal_dms_default vendor_data_file:file create_file_perms;
+allow hal_dms_default property_socket:sock_file write;
+
+allow hal_dms_default vendor_audio_prop:property_service set;
+allow hal_dms_default vendor_audio_prop:file {read getattr map open};
+
+allow hal_dms_default init:unix_stream_socket connectto;
diff --git a/sepolicy/vendor/hal_power.te b/sepolicy/vendor/hal_power.te
index c514d1f9..92f56ab2 100644
--- a/sepolicy/vendor/hal_power.te
+++ b/sepolicy/vendor/hal_power.te
@@ -1,2 +1 @@
allow hal_power_default touchfeature_device:chr_file rw_file_perms;
-rw_dir_file(hal_power_default, proc)
diff --git a/sepolicy/vendor/hal_power_default.te b/sepolicy/vendor/hal_power_default.te
new file mode 100644
index 00000000..d18b7e09
--- /dev/null
+++ b/sepolicy/vendor/hal_power_default.te
@@ -0,0 +1,3 @@
+allow hal_power_default proc_walt:dir search;
+allow hal_power_default proc_walt:file rw_file_perms;
+allow hal_power_default vendor_sysfs_msm_perf:file rw_file_perms;
diff --git a/sepolicy/vendor/hwservice_contexts b/sepolicy/vendor/hwservice_contexts
index fde869ee..2a150ddb 100644
--- a/sepolicy/vendor/hwservice_contexts
+++ b/sepolicy/vendor/hwservice_contexts
@@ -3,6 +3,9 @@ vendor.xiaomi.hardware.bgservice::IBGService u:object_r:vendor_h
vendor.xiaomi.hardware.campostproc::IMiPostProcService u:object_r:vendor_hal_camerapostproc_xiaomi_hwservice:s0
vendor.xiaomi.hardware.quickcamera::IQuickCameraService u:object_r:hal_quickcamera_hwservice:s0
+# Dolby
+vendor.dolby.hardware.dms::IDms u:object_r:hal_dms_hwservice:s0
+
# Fingerprint
vendor.xiaomi.hardware.fx.tunnel::IMiFxTunnel u:object_r:vendor_hal_fingerprint_hwservice_xiaomi:s0
diff --git a/sepolicy/vendor/platform_app.te b/sepolicy/vendor/platform_app.te
new file mode 100644
index 00000000..8c5952df
--- /dev/null
+++ b/sepolicy/vendor/platform_app.te
@@ -0,0 +1,25 @@
+hal_client_domain(platform_app, vendor_hal_camerapostproc_xiaomi)
+
+binder_use(platform_app)
+binder_call(platform_app, hal_camera_default)
+binder_call(platform_app, vendor_hal_camerapostproc_xiaomi)
+allow platform_app vendor_hal_camerapostproc_xiaomi_hwservice:hwservice_manager find;
+
+allow platform_app adsprpcd_file:dir { open read search };
+allow platform_app vendor_xdsp_device:chr_file { ioctl open read write };
+allow platform_app vendor_qdsp_device:chr_file { ioctl open read write };
+
+allow platform_app vendor_camera_data_file:dir { append map r_dir_perms write };
+allow platform_app vendor_camera_data_file:file { getattr open read };
+
+allow platform_app same_process_hal_file:file { execute getattr open read map };
+
+allow platform_app app_data_file:file execute;
+
+# Properties
+get_prop(platform_app, vendor_camera_sensor_prop)
+get_prop(platform_app, vendor_display_prop)
+get_prop(platform_app, vendor_panel_info_prop)
+get_prop(platform_app, vendor_persist_camera_prop)
+get_prop(platform_app, vendor_audio_prop)
+get_prop(platform_app, vendor_camera_p3enable_prop)
diff --git a/sepolicy/vendor/qti_init_shell.te b/sepolicy/vendor/qti_init_shell.te
index 008c4f89..8c331968 100644
--- a/sepolicy/vendor/qti_init_shell.te
+++ b/sepolicy/vendor/qti_init_shell.te
@@ -1 +1,3 @@
+allow vendor_qti_init_shell proc_walt:dir search;
+allow vendor_qti_init_shell proc_walt:file rw_file_perms;
allow vendor_qti_init_shell vendor_sysfs_qdss_dev:file { setattr write };
diff --git a/sepolicy/vendor/system_app.te b/sepolicy/vendor/system_app.te
new file mode 100644
index 00000000..d47d940a
--- /dev/null
+++ b/sepolicy/vendor/system_app.te
@@ -0,0 +1,22 @@
+# Allow system_app to access a get true info
+allow system_app proc_stat:file read;
+allow system_app sysfs_thermal:file write;
+allow system_app vendor_sysfs_kgsl:file read;
+allow system_app vendor_sysfs_kgsl_gpuclk:file read;
+allow system_app proc_stat:file open;
+allow system_app vendor_sysfs_kgsl:file open;
+allow system_app vendor_sysfs_kgsl_gpuclk:file open;
+allow system_app proc_stat:file { getattr open read };
+allow system_app vendor_sysfs_kgsl:file { getattr open read };
+allow system_app vendor_sysfs_kgsl_gpuclk:file { getattr open read };
+
+# Fast Charging
+allow system_app vendor_sysfs_battery_supply:dir { search };
+allow system_app vendor_sysfs_battery_supply:file { getattr open read };
+r_dir_file(system_app, vendor_sysfs_battery_supply)
+
+allow system_app sysfs_thermal:file { rw_file_perms getattr };
+
+# Charge Bypass
+allow system_app vendor_sysfs_battery_supply:dir search;
+allow system_app vendor_sysfs_battery_supply:file { getattr open read write };
diff --git a/sepolicy/vendor/system_server.te b/sepolicy/vendor/system_server.te
new file mode 100644
index 00000000..e36ef2dc
--- /dev/null
+++ b/sepolicy/vendor/system_server.te
@@ -0,0 +1,3 @@
+# Allow system_server to read Fast Charging status
+allow system_server vendor_sysfs_battery_supply:file { getattr open read };
+allow system_server vendor_sysfs_battery_supply:file rw_file_perms;