diff options
| author | kleidione Freitas <kleidione@gmail.com> | 2022-03-06 11:57:51 -0300 | 
|---|---|---|
| committer | sinanmohd <pcmsinan@gmail.com> | 2023-01-05 21:30:23 +0530 | 
| commit | 3607af54ca48c8a145a97bab0cf5012d45ade555 (patch) | |
| tree | 4f1a2239da3dd089a49e0eaedcf46a12ca41617b /parts/src | |
| parent | 59e11d3ea1b69feb0a7027fa87eb3fd9a7530c87 (diff) | |
veux: Import XiaomiParts from sm8250
Credits:
https://github.com/xiaomi-sm8250-devs/android_device_xiaomi_sm8250-common
- Adapte to pixelexperiece
- Drop doze
- Drop fod and pop camera
- Add Clear speaker
- Adapte SEPolicy credis: [Sebastiano Barezzi, Chenyang Zhong]
Co-authored-by: Sebastiano Barezzi <barezzisebastiano@gmail.com>
Co-authored-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
Co-authored-by: kubersharma001 <kubersharma001@gmail.com>
Co-authored-by: TheScarastic <warabhishek@gmail.com>
Co-authored-by: Joey <joey@lineageos.org>
Signed-off-by: kleidione <kleidione@gmail.com>
Diffstat (limited to 'parts/src')
8 files changed, 1114 insertions, 0 deletions
| diff --git a/parts/src/org/lineageos/settings/BootCompletedReceiver.java b/parts/src/org/lineageos/settings/BootCompletedReceiver.java new file mode 100644 index 0000000..1652bc0 --- /dev/null +++ b/parts/src/org/lineageos/settings/BootCompletedReceiver.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + *               2017-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; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import org.lineageos.settings.thermal.ThermalUtils; + +public class BootCompletedReceiver extends BroadcastReceiver { + +    private static final boolean DEBUG = false; +    private static final String TAG = "XiaomiParts"; + +    @Override +    public void onReceive(final Context context, Intent intent) { +        if (DEBUG) Log.d(TAG, "Received boot completed intent"); +        ThermalUtils.startService(context); +    } +} 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 0000000..5ac5b35 --- /dev/null +++ b/parts/src/org/lineageos/settings/speaker/ClearSpeakerActivity.java @@ -0,0 +1,43 @@ +/* + * 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 android.view.MenuItem; + +import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity; +import com.android.settingslib.collapsingtoolbar.R; + +public class ClearSpeakerActivity extends CollapsingToolbarBaseActivity { + +    @Override +    protected void onCreate(Bundle savedInstanceState) { +        super.onCreate(savedInstanceState); +        getFragmentManager().beginTransaction() +                .replace(R.id.content_frame,  new ClearSpeakerFragment()) +                .commit(); +    } + +    @Override +    public boolean onOptionsItemSelected(MenuItem item) { +        if (item.getItemId() == android.R.id.home) { +            onBackPressed(); +            return true; +        } +        return super.onOptionsItemSelected(item); +    } +} 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 0000000..7f12fd9 --- /dev/null +++ b/parts/src/org/lineageos/settings/speaker/ClearSpeakerFragment.java @@ -0,0 +1,118 @@ +/* + * 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.content.Context; +import android.content.res.AssetFileDescriptor; +import android.media.AudioManager; +import android.media.AudioAttributes; +import android.media.MediaPlayer; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +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.class.getSimpleName(); + +    private static final String PREF_CLEAR_SPEAKER = "clear_speaker_pref"; + +    private AudioManager mAudioManager; +    private Handler mHandler; +    private MediaPlayer mMediaPlayer; +    private SwitchPreference mClearSpeakerPref; + +    @Override +    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { +        addPreferencesFromResource(R.xml.clear_speaker_settings); + +        mClearSpeakerPref = (SwitchPreference) findPreference(PREF_CLEAR_SPEAKER); +        mClearSpeakerPref.setOnPreferenceChangeListener(this); + +        mHandler = new Handler(); +        mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); +    } + +    @Override +    public boolean onPreferenceChange(Preference preference, Object newValue) { +        if (preference == mClearSpeakerPref) { +            boolean value = (Boolean) newValue; +            if (value) { +                if (startPlaying()) { +                    mHandler.removeCallbacksAndMessages(null); +                    mHandler.postDelayed(() -> { +                        stopPlaying(); +                    }, 30000); +                    return true; +                } +            } +        } +        return false; +    } + +    @Override +    public void onStop() { +        stopPlaying(); +        super.onStop(); +    } + +    public boolean startPlaying() { +        mAudioManager.setParameters("status_earpiece_clean=on"); +        mMediaPlayer = new MediaPlayer(); +        getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC); +        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); +        mMediaPlayer.setLooping(true); +        try { +            AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.clear_speaker_sound); +            try { +                mMediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); +            } finally { +                file.close(); +            } +            mClearSpeakerPref.setEnabled(false); +            mMediaPlayer.setVolume(1.0f, 1.0f); +            mMediaPlayer.prepare(); +            mMediaPlayer.start(); +        } catch (IOException ioe) { +            Log.e(TAG, "Failed to play speaker clean sound!", ioe); +            return false; +        } +        return true; +    } + +    public void stopPlaying() { +        if (mMediaPlayer != null) { +            mMediaPlayer.stop(); +            mMediaPlayer.reset(); +            mMediaPlayer.release(); +        } +        mAudioManager.setParameters("status_earpiece_clean=off"); +        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 0000000..16df382 --- /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; +import com.android.settingslib.collapsingtoolbar.R; + +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(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 0000000..cba9044 --- /dev/null +++ b/parts/src/org/lineageos/settings/thermal/ThermalService.java @@ -0,0 +1,102 @@ +/* + * 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 String mPreviousApp; +    private ThermalUtils mThermalUtils; + +    private IActivityTaskManager mActivityTaskManager; + +    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { +        @Override +        public void onReceive(Context context, Intent intent) { +            mPreviousApp = ""; +            mThermalUtils.setDefaultThermalProfile(); +        } +    }; + +    @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 final TaskStackListener mTaskListener = new TaskStackListener() { +        @Override +        public void onTaskStackChanged() { +            try { +                final RootTaskInfo info = mActivityTaskManager.getFocusedRootTaskInfo(); +                if (info == null || info.topActivity == null) { +                    return; +                } + +                String foregroundApp = info.topActivity.getPackageName(); +                if (!foregroundApp.equals(mPreviousApp)) { +                    mThermalUtils.setThermalProfile(foregroundApp); +                    mPreviousApp = foregroundApp; +                } +            } 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 0000000..6f4e402 --- /dev/null +++ b/parts/src/org/lineageos/settings/thermal/ThermalSettingsFragment.java @@ -0,0 +1,433 @@ +/** + * Copyright (C) 2020 The LineageOS Project + * <p> + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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<String, ApplicationsState.AppEntry> mEntryMap = +            new HashMap<String, ApplicationsState.AppEntry>(); + +    private RecyclerView mAppsRecyclerView; + +    private ThermalUtils mThermalUtils; + +    @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<ApplicationsState.AppEntry> 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<ApplicationsState.AppEntry> entries) { +        final ArrayList<String> sections = new ArrayList<String>(); +        final ArrayList<Integer> positions = new ArrayList<Integer>(); +        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<ViewHolder> +            implements AdapterView.OnItemSelectedListener, SectionIndexer { + +        private List<ApplicationsState.AppEntry> 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<ApplicationsState.AppEntry> entries, +                                List<String> sections, List<Integer> 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<String> mLauncherResolveInfoList = new ArrayList<String>(); + +        private ActivityFilter(PackageManager packageManager) { +            this.mPackageManager = packageManager; + +            updateLauncherInfoList(); +        } + +        public void updateLauncherInfoList() { +            Intent i = new Intent(Intent.ACTION_MAIN); +            i.addCategory(Intent.CATEGORY_LAUNCHER); +            List<ResolveInfo> 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 0000000..79510ed --- /dev/null +++ b/parts/src/org/lineageos/settings/thermal/ThermalUtils.java @@ -0,0 +1,170 @@ +/* + * 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 { + +    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_CONTROL = "thermal_control"; +    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) { +        if (FileUtils.fileExists(THERMAL_SCONFIG)) { +            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) { +             String[] modes = value.split(":"); +             if (modes.length < 5) value = 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/FileUtils.java b/parts/src/org/lineageos/settings/utils/FileUtils.java new file mode 100644 index 0000000..2228ff8 --- /dev/null +++ b/parts/src/org/lineageos/settings/utils/FileUtils.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2016 The CyanogenMod 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); +        } 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; +    } +} | 
