/*
* Copyright (C) 2015-2016 Willi Ye <williye97@gmail.com>
*
* This file is part of Kernel Adiutor.
*
* Kernel Adiutor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Kernel Adiutor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kernel Adiutor. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.grarak.kerneladiutor.fragments.kernel;
import android.content.DialogInterface;
import android.util.SparseArray;
import com.grarak.kerneladiutor.R;
import com.grarak.kerneladiutor.fragments.ApplyOnBootFragment;
import com.grarak.kerneladiutor.fragments.BaseFragment;
import com.grarak.kerneladiutor.fragments.DescriptionFragment;
import com.grarak.kerneladiutor.fragments.RecyclerViewFragment;
import com.grarak.kerneladiutor.utils.Device;
import com.grarak.kerneladiutor.utils.Utils;
import com.grarak.kerneladiutor.utils.ViewUtils;
import com.grarak.kerneladiutor.utils.kernel.cpu.CPUBoost;
import com.grarak.kerneladiutor.utils.kernel.cpu.CPUFreq;
import com.grarak.kerneladiutor.utils.kernel.cpu.Misc;
import com.grarak.kerneladiutor.utils.root.RootUtils;
import com.grarak.kerneladiutor.views.dialog.Dialog;
import com.grarak.kerneladiutor.views.recyclerview.CardView;
import com.grarak.kerneladiutor.views.recyclerview.DescriptionView;
import com.grarak.kerneladiutor.views.recyclerview.RecyclerViewItem;
import com.grarak.kerneladiutor.views.recyclerview.SeekBarView;
import com.grarak.kerneladiutor.views.recyclerview.SelectView;
import com.grarak.kerneladiutor.views.recyclerview.SwitchView;
import com.grarak.kerneladiutor.views.recyclerview.TitleView;
import com.grarak.kerneladiutor.views.recyclerview.XYGraphView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by willi on 01.05.16.
*/
public class CPUFragment extends RecyclerViewFragment {
private XYGraphView mCPUUsageBig;
private SelectView mCPUMaxBig;
private SelectView mCPUMinBig;
private SelectView mCPUMaxScreenOffBig;
private SelectView mCPUGovernorBig;
private XYGraphView mCPUUsageLITTLE;
private SelectView mCPUMaxLITTLE;
private SelectView mCPUMinLITTLE;
private SelectView mCPUMaxScreenOffLITTLE;
private SelectView mCPUGovernorLITTLE;
private SparseArray<SwitchView> mCoresBig = new SparseArray<>();
private SparseArray<SwitchView> mCoresLITTLE = new SparseArray<>();
private float[] mCPUUsages;
private int mCPUMaxFreqBig;
private int mCPUMinFreqBig;
private int mCPUMaxScreenOffFreqBig;
private String mCPUGovernorStrBig;
private int mCPUMaxFreqLITTLE;
private int mCPUMinFreqLITTLE;
private int mCPUMaxScreenOffFreqLITTLE;
private String mCPUGovernorStrLITTLE;
private PathReaderFragment mGovernorTunableFragment;
private Dialog mGovernorTunableErrorDialog;
private Thread mRefreshThread;
@Override
protected BaseFragment getForegroundFragment() {
return mGovernorTunableFragment = new PathReaderFragment();
}
@Override
protected void init() {
super.init();
addViewPagerFragment(ApplyOnBootFragment.newInstance(this));
addViewPagerFragment(DescriptionFragment.newInstance(getString(CPUFreq.getCpuCount() > 1 ?
R.string.cores : R.string.cores_singular, CPUFreq.getCpuCount()), Device.getBoard()));
if (mGovernorTunableErrorDialog != null) {
mGovernorTunableErrorDialog.show();
}
}
@Override
protected void addItems(List<RecyclerViewItem> items) {
freqInit(items);
if (Misc.hasMcPowerSaving()) {
mcPowerSavingInit(items);
}
if (Misc.hasPowerSavingWq()) {
powerSavingWqInit(items);
}
if (Misc.hasCFSScheduler()) {
cfsSchedulerInit(items);
}
if (Misc.hasCpuQuiet()) {
cpuQuietInit(items);
}
if (CPUBoost.supported()) {
cpuBoostInit(items);
}
if (Misc.hasCpuTouchBoost()) {
cpuTouchBoostInit(items);
}
}
private void freqInit(List<RecyclerViewItem> items) {
CardView bigCard = new CardView(getActivity());
if (CPUFreq.isBigLITTLE()) {
bigCard.setTitle(getString(R.string.cluster_big));
}
mCPUUsageBig = new XYGraphView();
mCPUUsageBig.setTitle(getString(R.string.cpu_usage));
bigCard.addItem(mCPUUsageBig);
final List<Integer> bigCores = CPUFreq.getBigCpuRange();
mCoresBig.clear();
for (final int core : bigCores) {
SwitchView coreSwitch = new SwitchView();
coreSwitch.setSummary(getString(R.string.core, core + 1));
mCoresBig.put(core, coreSwitch);
bigCard.addItem(coreSwitch);
}
mCPUMaxBig = new SelectView();
mCPUMaxBig.setTitle(getString(R.string.cpu_max_freq));
mCPUMaxBig.setSummary(getString(R.string.cpu_max_freq_summary));
mCPUMaxBig.setItems(CPUFreq.getAdjustedFreq(getActivity()));
mCPUMaxBig.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMaxFreq(CPUFreq.getFreqs().get(position), bigCores.get(0),
bigCores.get(bigCores.size() - 1), getActivity());
}
});
bigCard.addItem(mCPUMaxBig);
mCPUMinBig = new SelectView();
mCPUMinBig.setTitle(getString(R.string.cpu_min_freq));
mCPUMinBig.setSummary(getString(R.string.cpu_min_freq_summary));
mCPUMinBig.setItems(CPUFreq.getAdjustedFreq(getActivity()));
mCPUMinBig.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMinFreq(CPUFreq.getFreqs().get(position), bigCores.get(0),
bigCores.get(bigCores.size() - 1), getActivity());
}
});
bigCard.addItem(mCPUMinBig);
if (CPUFreq.hasMaxScreenOffFreq()) {
mCPUMaxScreenOffBig = new SelectView();
mCPUMaxScreenOffBig.setTitle(getString(R.string.cpu_max_screen_off_freq));
mCPUMaxScreenOffBig.setSummary(getString(R.string.cpu_max_screen_off_freq_summary));
mCPUMaxScreenOffBig.setItems(CPUFreq.getAdjustedFreq(getActivity()));
mCPUMaxScreenOffBig.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMaxScreenOffFreq(CPUFreq.getFreqs().get(position), bigCores.get(0),
bigCores.get(bigCores.size() - 1), getActivity());
}
});
bigCard.addItem(mCPUMaxScreenOffBig);
}
mCPUGovernorBig = new SelectView();
mCPUGovernorBig.setTitle(getString(R.string.cpu_governor));
mCPUGovernorBig.setSummary(getString(R.string.cpu_governor_summary));
mCPUGovernorBig.setItems(CPUFreq.getGovernors());
mCPUGovernorBig.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setGovernor(item, bigCores.get(0), bigCores.get(bigCores.size() - 1),
getActivity());
}
});
bigCard.addItem(mCPUGovernorBig);
DescriptionView governorTunablesBig = new DescriptionView();
governorTunablesBig.setTitle(getString(R.string.cpu_governor_tunables));
governorTunablesBig.setSummary(getString(R.string.governor_tunables_summary));
governorTunablesBig.setOnItemClickListener(new RecyclerViewItem.OnItemClickListener() {
@Override
public void onClick(RecyclerViewItem item) {
showGovernorTunables(bigCores.get(0), bigCores.get(bigCores.size() - 1));
}
});
bigCard.addItem(governorTunablesBig);
items.add(bigCard);
if (CPUFreq.isBigLITTLE()) {
CardView LITTLECard = new CardView(getActivity());
LITTLECard.setTitle(getString(R.string.cluster_little));
mCPUUsageLITTLE = new XYGraphView();
mCPUUsageLITTLE.setTitle(getString(R.string.cpu_usage));
LITTLECard.addItem(mCPUUsageLITTLE);
final List<Integer> LITTLECores = CPUFreq.getLITTLECpuRange();
mCoresLITTLE.clear();
for (final int core : LITTLECores) {
SwitchView coreSwitch = new SwitchView();
coreSwitch.setSummary(getString(R.string.core, core + 1));
mCoresLITTLE.put(core, coreSwitch);
LITTLECard.addItem(coreSwitch);
}
mCPUMaxLITTLE = new SelectView();
mCPUMaxLITTLE.setTitle(getString(R.string.cpu_max_freq));
mCPUMaxLITTLE.setSummary(getString(R.string.cpu_max_freq_summary));
mCPUMaxLITTLE.setItems(CPUFreq.getAdjustedFreq(CPUFreq.getLITTLECpu(), getActivity()));
mCPUMaxLITTLE.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMaxFreq(CPUFreq.getFreqs(CPUFreq.getLITTLECpu()).get(position),
LITTLECores.get(0), LITTLECores.get(LITTLECores.size() - 1), getActivity());
}
});
LITTLECard.addItem(mCPUMaxLITTLE);
mCPUMinLITTLE = new SelectView();
mCPUMinLITTLE.setTitle(getString(R.string.cpu_min_freq));
mCPUMinLITTLE.setSummary(getString(R.string.cpu_min_freq_summary));
mCPUMinLITTLE.setItems(CPUFreq.getAdjustedFreq(CPUFreq.getLITTLECpu(), getActivity()));
mCPUMinLITTLE.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMinFreq(CPUFreq.getFreqs(CPUFreq.getLITTLECpu()).get(position),
LITTLECores.get(0), LITTLECores.get(LITTLECores.size() - 1), getActivity());
}
});
LITTLECard.addItem(mCPUMinLITTLE);
if (CPUFreq.hasMaxScreenOffFreq(CPUFreq.getLITTLECpu())) {
mCPUMaxScreenOffLITTLE = new SelectView();
mCPUMaxScreenOffLITTLE.setTitle(getString(R.string.cpu_max_screen_off_freq));
mCPUMaxScreenOffLITTLE.setSummary(getString(R.string.cpu_max_screen_off_freq_summary));
mCPUMaxScreenOffLITTLE.setItems(CPUFreq.getAdjustedFreq(CPUFreq.getLITTLECpu(), getActivity()));
mCPUMaxScreenOffLITTLE.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setMaxScreenOffFreq(CPUFreq.getFreqs(CPUFreq.getLITTLECpu()).get(position),
LITTLECores.get(0), LITTLECores.get(LITTLECores.size() - 1), getActivity());
}
});
LITTLECard.addItem(mCPUMaxScreenOffLITTLE);
}
mCPUGovernorLITTLE = new SelectView();
mCPUGovernorLITTLE.setTitle(getString(R.string.cpu_governor));
mCPUGovernorLITTLE.setSummary(getString(R.string.cpu_governor_summary));
mCPUGovernorLITTLE.setItems(CPUFreq.getGovernors());
mCPUGovernorLITTLE.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUFreq.setGovernor(item, LITTLECores.get(0), LITTLECores.get(LITTLECores.size() - 1),
getActivity());
}
});
LITTLECard.addItem(mCPUGovernorLITTLE);
DescriptionView governorTunablesLITTLE = new DescriptionView();
governorTunablesLITTLE.setTitle(getString(R.string.cpu_governor_tunables));
governorTunablesLITTLE.setSummary(getString(R.string.governor_tunables_summary));
governorTunablesLITTLE.setOnItemClickListener(new RecyclerViewItem.OnItemClickListener() {
@Override
public void onClick(RecyclerViewItem item) {
showGovernorTunables(LITTLECores.get(0), LITTLECores.get(LITTLECores.size() - 1));
}
});
LITTLECard.addItem(governorTunablesLITTLE);
items.add(LITTLECard);
}
}
private void showGovernorTunables(int min, int max) {
boolean offline = CPUFreq.isOffline(min);
if (offline) {
CPUFreq.onlineCpu(min, true, false, null);
}
String governor = CPUFreq.getGovernor(min, false);
if (governor.isEmpty()) {
mGovernorTunableErrorDialog = ViewUtils.dialogBuilder(getString(R.string.cpu_governor_tunables_read_error),
null, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}, new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
mGovernorTunableErrorDialog = null;
}
}, getActivity());
mGovernorTunableErrorDialog.show();
} else {
setForegroundText(governor);
mGovernorTunableFragment.setError(getString(R.string.tunables_error, governor));
mGovernorTunableFragment.setPath(CPUFreq.getGovernorTunablesPath(min, governor), min, max,
ApplyOnBootFragment.CPU);
showForeground();
}
if (offline) {
CPUFreq.onlineCpu(min, false, false, null);
}
}
private void mcPowerSavingInit(List<RecyclerViewItem> items) {
SelectView mcPowerSaving = new SelectView();
mcPowerSaving.setTitle(getString(R.string.mc_power_saving));
mcPowerSaving.setSummary(getString(R.string.mc_power_saving_summary));
mcPowerSaving.setItems(Arrays.asList(getResources().getStringArray(R.array.mc_power_saving_items)));
mcPowerSaving.setItem(Misc.getCurMcPowerSaving());
mcPowerSaving.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
Misc.setMcPowerSaving(position, getActivity());
}
});
items.add(mcPowerSaving);
}
private void powerSavingWqInit(List<RecyclerViewItem> items) {
SwitchView powerSavingWq = new SwitchView();
powerSavingWq.setSummary(getString(R.string.power_saving_wq));
powerSavingWq.setChecked(Misc.isPowerSavingWqEnabled());
powerSavingWq.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
Misc.enablePowerSavingWq(isChecked, getActivity());
}
});
items.add(powerSavingWq);
}
private void cfsSchedulerInit(List<RecyclerViewItem> items) {
SelectView cfsScheduler = new SelectView();
cfsScheduler.setTitle(getString(R.string.cfs_scheduler_policy));
cfsScheduler.setSummary(getString(R.string.cfs_scheduler_policy_summary));
cfsScheduler.setItems(Misc.getAvailableCFSSchedulers());
cfsScheduler.setItem(Misc.getCurrentCFSScheduler());
cfsScheduler.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
Misc.setCFSScheduler(item, getActivity());
}
});
items.add(cfsScheduler);
}
private void cpuQuietInit(List<RecyclerViewItem> items) {
List<RecyclerViewItem> views = new ArrayList<>();
CardView cpuQuietCard = new CardView(getActivity());
cpuQuietCard.setTitle(getString(R.string.cpu_quiet));
if (Misc.hasCpuQuietEnable()) {
SwitchView cpuQuietEnable = new SwitchView();
cpuQuietEnable.setSummary(getString(R.string.cpu_quiet));
cpuQuietEnable.setChecked(Misc.isCpuQuietEnabled());
cpuQuietEnable.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
Misc.enableCpuQuiet(isChecked, getActivity());
}
});
views.add(cpuQuietEnable);
}
if (Misc.hasCpuQuietGovernors()) {
SelectView cpuQuietGovernors = new SelectView();
cpuQuietGovernors.setSummary(getString(R.string.cpu_quiet_governor));
cpuQuietGovernors.setItems(Misc.getCpuQuietAvailableGovernors());
cpuQuietGovernors.setItem(Misc.getCpuQuietCurGovernor());
cpuQuietGovernors.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
Misc.setCpuQuietGovernor(item, getActivity());
}
});
views.add(cpuQuietGovernors);
}
if (views.size() > 0) {
DescriptionView descriptionView = new DescriptionView();
descriptionView.setSummary(getString(R.string.cpu_quiet_summary));
cpuQuietCard.addItem(descriptionView);
for (RecyclerViewItem item : views) {
cpuQuietCard.addItem(item);
}
items.add(cpuQuietCard);
}
}
private void cpuBoostInit(List<RecyclerViewItem> items) {
List<RecyclerViewItem> cpuBoost = new ArrayList<>();
TitleView title = new TitleView();
title.setText(getString(R.string.cpu_boost));
if (CPUBoost.hasEnable()) {
SwitchView enable = new SwitchView();
enable.setSummary(getString(R.string.cpu_boost));
enable.setChecked(CPUBoost.isEnabled());
enable.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
CPUBoost.enableCpuBoost(isChecked, getActivity());
}
});
items.add(enable);
}
if (CPUBoost.hasCpuBoostDebugMask()) {
SwitchView debugMask = new SwitchView();
debugMask.setTitle(getString(R.string.debug_mask));
debugMask.setSummary(getString(R.string.debug_mask_summary));
debugMask.setChecked(CPUBoost.isCpuBoostDebugMaskEnabled());
debugMask.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
CPUBoost.enableCpuBoostDebugMask(isChecked, getActivity());
}
});
cpuBoost.add(debugMask);
}
if (CPUBoost.hasCpuBoostMs()) {
SeekBarView ms = new SeekBarView();
ms.setTitle(getString(R.string.interval));
ms.setSummary(getString(R.string.interval_summary));
ms.setUnit(getString(R.string.ms));
ms.setMax(5000);
ms.setOffset(10);
ms.setProgress(CPUBoost.getCpuBootMs() / 10);
ms.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
CPUBoost.setCpuBoostMs(position * 10, getActivity());
}
});
cpuBoost.add(ms);
}
if (CPUBoost.hasCpuBoostSyncThreshold() && CPUFreq.getFreqs() != null) {
List<String> list = new ArrayList<>();
list.add(getString(R.string.disabled));
list.addAll(CPUFreq.getAdjustedFreq(getActivity()));
SelectView syncThreshold = new SelectView();
syncThreshold.setTitle(getString(R.string.sync_threshold));
syncThreshold.setSummary(getString(R.string.sync_threshold_summary));
syncThreshold.setItems(list);
syncThreshold.setItem(CPUBoost.getCpuBootSyncThreshold());
syncThreshold.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUBoost.setCpuBoostSyncThreshold(position == 0 ? 0 : CPUFreq.getFreqs().get(position - 1),
getActivity());
}
});
cpuBoost.add(syncThreshold);
}
if (CPUBoost.hasCpuBoostInputMs()) {
SeekBarView inputMs = new SeekBarView();
inputMs.setTitle(getString(R.string.input_interval));
inputMs.setSummary(getString(R.string.input_interval_summary));
inputMs.setUnit(getString(R.string.ms));
inputMs.setMax(5000);
inputMs.setOffset(10);
inputMs.setProgress(CPUBoost.getCpuBootInputMs() / 10);
inputMs.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
CPUBoost.setCpuBoostInputMs(position * 10, getActivity());
}
});
cpuBoost.add(inputMs);
}
if (CPUBoost.hasCpuBoostInputFreq()) {
List<Integer> freqs = CPUBoost.getCpuBootInputFreq();
for (int i = 0; i < freqs.size(); i++) {
List<String> list = new ArrayList<>();
list.add(getString(R.string.disabled));
list.addAll(CPUFreq.getAdjustedFreq(i, getActivity()));
SelectView inputCard = new SelectView();
if (freqs.size() > 1) {
inputCard.setTitle(getString(R.string.input_boost_freq_core, i + 1));
} else {
inputCard.setTitle(getString(R.string.input_boost_freq));
}
inputCard.setSummary(getString(R.string.input_boost_freq_summary));
inputCard.setItems(list);
inputCard.setItem(freqs.get(i));
final int core = i;
inputCard.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
CPUBoost.setCpuBoostInputFreq(position == 0 ? 0
: CPUFreq.getFreqs(core).get(position - 1), core, getActivity());
}
});
cpuBoost.add(inputCard);
}
}
if (CPUBoost.hasCpuBoostWakeup()) {
SwitchView wakeup = new SwitchView();
wakeup.setTitle(getString(R.string.wakeup_boost));
wakeup.setSummary(getString(R.string.wakeup_boost_summary));
wakeup.setChecked(CPUBoost.isCpuBoostWakeupEnabled());
wakeup.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
CPUBoost.enableCpuBoostWakeup(isChecked, getActivity());
}
});
cpuBoost.add(wakeup);
}
if (CPUBoost.hasCpuBoostHotplug()) {
SwitchView hotplug = new SwitchView();
hotplug.setTitle(getString(R.string.hotplug_boost));
hotplug.setSummary(getString(R.string.hotplug_boost_summary));
hotplug.setChecked(CPUBoost.isCpuBoostHotplugEnabled());
hotplug.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
CPUBoost.enableCpuBoostHotplug(isChecked, getActivity());
}
});
cpuBoost.add(hotplug);
}
if (cpuBoost.size() > 0) {
items.add(title);
items.addAll(cpuBoost);
}
}
private void cpuTouchBoostInit(List<RecyclerViewItem> items) {
SwitchView touchBoost = new SwitchView();
touchBoost.setTitle(getString(R.string.touch_boost));
touchBoost.setSummary(getString(R.string.touch_boost_summary));
touchBoost.setChecked(Misc.isCpuTouchBoostEnabled());
touchBoost.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
Misc.enableCpuTouchBoost(isChecked, getActivity());
}
});
items.add(touchBoost);
}
@Override
protected void refresh() {
super.refresh();
if (mRefreshThread == null) {
mRefreshThread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
mCPUUsages = CPUFreq.getCpuUsage();
if (mCPUMaxBig != null) {
mCPUMaxFreqBig = CPUFreq.getMaxFreq(mCPUMaxFreqBig == 0);
}
if (mCPUMinBig != null) {
mCPUMinFreqBig = CPUFreq.getMinFreq(mCPUMinFreqBig == 0);
}
if (mCPUMaxScreenOffBig != null) {
mCPUMaxScreenOffFreqBig = CPUFreq.getMaxScreenOffFreq(mCPUMaxScreenOffFreqBig == 0);
}
if (mCPUGovernorBig != null) {
mCPUGovernorStrBig = CPUFreq.getGovernor(mCPUGovernorStrBig == null);
}
if (mCPUMaxLITTLE != null) {
mCPUMaxFreqLITTLE = CPUFreq.getMaxFreq(CPUFreq.getLITTLECpu(), mCPUMaxFreqLITTLE == 0);
}
if (mCPUMinLITTLE != null) {
mCPUMinFreqLITTLE = CPUFreq.getMinFreq(CPUFreq.getLITTLECpu(), mCPUMinFreqLITTLE == 0);
}
if (mCPUMaxScreenOffLITTLE != null) {
mCPUMaxScreenOffFreqLITTLE = CPUFreq.getMaxScreenOffFreq(CPUFreq.getLITTLECpu(),
mCPUMaxScreenOffFreqLITTLE == 0);
}
if (mCPUGovernorLITTLE != null) {
mCPUGovernorStrLITTLE = CPUFreq.getGovernor(CPUFreq.getLITTLECpu(),
mCPUGovernorStrLITTLE == null);
}
if (getActivity() == null) {
RootUtils.closeSU();
}
mRefreshThread = null;
}
}
});
mRefreshThread.start();
}
if (mCPUUsages != null) {
refreshUsages(mCPUUsages, mCPUUsageBig, CPUFreq.getBigCpuRange());
if (CPUFreq.isBigLITTLE()) {
refreshUsages(mCPUUsages, mCPUUsageLITTLE, CPUFreq.getLITTLECpuRange());
}
}
if (mCPUMaxBig != null && mCPUMaxFreqBig != 0) {
mCPUMaxBig.setItem((mCPUMaxFreqBig / 1000) + getString(R.string.mhz));
}
if (mCPUMinBig != null && mCPUMinFreqBig != 0) {
mCPUMinBig.setItem((mCPUMinFreqBig / 1000) + getString(R.string.mhz));
}
if (mCPUMaxScreenOffBig != null && mCPUMaxScreenOffFreqBig != 0) {
mCPUMaxScreenOffBig.setItem((mCPUMaxScreenOffFreqBig / 1000) + getString(R.string.mhz));
}
if (mCPUGovernorBig != null && mCPUGovernorStrBig != null && !mCPUGovernorStrBig.isEmpty()) {
mCPUGovernorBig.setItem(mCPUGovernorStrBig);
}
if (mCPUMaxLITTLE != null && mCPUMaxFreqLITTLE != 0) {
mCPUMaxLITTLE.setItem((mCPUMaxFreqLITTLE / 1000) + getString(R.string.mhz));
}
if (mCPUMinLITTLE != null && mCPUMinFreqLITTLE != 0) {
mCPUMinLITTLE.setItem((mCPUMinFreqLITTLE / 1000) + getString(R.string.mhz));
}
if (mCPUMaxScreenOffLITTLE != null && mCPUMaxScreenOffFreqLITTLE != 0) {
mCPUMaxScreenOffLITTLE.setItem((mCPUMaxScreenOffFreqLITTLE / 1000) + getString(R.string.mhz));
}
if (mCPUGovernorLITTLE != null && mCPUGovernorStrLITTLE != null && !mCPUGovernorStrLITTLE.isEmpty()) {
mCPUGovernorLITTLE.setItem(mCPUGovernorStrLITTLE);
}
refreshCores(mCoresBig);
if (CPUFreq.isBigLITTLE()) {
refreshCores(mCoresLITTLE);
}
}
private void refreshUsages(float[] usages, XYGraphView graph, List<Integer> cores) {
if (graph != null) {
Float average = null;
for (int core : cores) {
if (core + 1 < usages.length && !CPUFreq.isOffline(core)) {
if (average == null) {
average = Utils.getAverage(usages[core + 1]);
} else {
average = Utils.getAverage(average, usages[core + 1]);
}
}
}
if (average != null) {
graph.setText(Math.round(average) + "%");
graph.addPercentage(Math.round(average));
}
}
}
private void refreshCores(SparseArray<SwitchView> array) {
try {
for (int i = 0; i < array.size(); i++) {
SwitchView switchView = array.valueAt(i);
if (switchView != null) {
final int core = array.keyAt(i);
int freq = CPUFreq.getCurFreq(core);
String freqText = freq == 0 ? getString(R.string.offline) : (freq / 1000)
+ getString(R.string.mhz);
switchView.clearOnSwitchListener();
switchView.setChecked(freq != 0);
switchView.setSummary(getString(R.string.core, core + 1) + " - " + freqText);
switchView.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
if (core == 0) {
Utils.toast(R.string.no_offline_core, getActivity());
} else {
CPUFreq.onlineCpu(core, isChecked, true, getActivity());
}
}
});
}
}
} catch (ConcurrentModificationException ignored) {
}
}
}