/*
* Copyright (C) 2013 - 2014 Alexander "Evisceration" Martinz
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.namelessrom.devicecontrol.modules.device;
import android.app.Activity;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import org.namelessrom.devicecontrol.ActivityCallbacks;
import org.namelessrom.devicecontrol.DeviceConstants;
import org.namelessrom.devicecontrol.R;
import org.namelessrom.devicecontrol.actions.extras.MpDecisionAction;
import org.namelessrom.devicecontrol.hardware.KsmUtils;
import org.namelessrom.devicecontrol.hardware.UksmUtils;
import org.namelessrom.devicecontrol.hardware.VoltageUtils;
import org.namelessrom.devicecontrol.models.BootupConfig;
import org.namelessrom.devicecontrol.modules.bootup.BootupItem;
import org.namelessrom.devicecontrol.preferences.AwesomeListPreference;
import org.namelessrom.devicecontrol.preferences.AwesomeTogglePreference;
import org.namelessrom.devicecontrol.preferences.CustomListPreference;
import org.namelessrom.devicecontrol.preferences.CustomPreference;
import org.namelessrom.devicecontrol.views.CustomPreferenceFragment;
import org.namelessrom.devicecontrol.utils.Utils;
import java.util.ArrayList;
public class DeviceFeatureKernelFragment extends CustomPreferenceFragment implements Preference.OnPreferenceClickListener {
//==============================================================================================
// Files
//==============================================================================================
private static final String TCP_CONGESTION_AVAILABLE =
"/proc/sys/net/ipv4/tcp_available_congestion_control";
private static final String TCP_CONGESTION_CONTROL =
"/proc/sys/net/ipv4/tcp_congestion_control";
//----------------------------------------------------------------------------------------------
private PreferenceScreen mRoot;
//----------------------------------------------------------------------------------------------
private CustomPreference mEntropy;
private CustomPreference mKsm;
private CustomPreference mUksm;
//----------------------------------------------------------------------------------------------
private AwesomeTogglePreference mPowerEfficientWork;
private AwesomeListPreference mMcPowerScheduler;
//----------------------------------------------------------------------------------------------
private AwesomeTogglePreference mMsmDcvs;
private CustomPreference mVoltageControl;
//----------------------------------------------------------------------------------------------
private CustomListPreference mTcpCongestion;
//==============================================================================================
// Overridden Methods
//==============================================================================================
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.device_feature_kernel);
mRoot = getPreferenceScreen();
//------------------------------------------------------------------------------------------
// Kernel Features
//------------------------------------------------------------------------------------------
PreferenceCategory category = (PreferenceCategory) findPreference("kernel_features");
mEntropy = (CustomPreference) findPreference("entropy");
mEntropy.setOnPreferenceClickListener(this);
mKsm = (CustomPreference) findPreference("ksm");
if (Utils.fileExists(KsmUtils.KSM_PATH)) {
mKsm.setOnPreferenceClickListener(this);
} else {
category.removePreference(mKsm);
}
mUksm = (CustomPreference) findPreference("uksm");
if (Utils.fileExists(UksmUtils.UKSM_PATH)) {
mUksm.setOnPreferenceClickListener(this);
} else {
category.removePreference(mUksm);
}
removeIfEmpty(category);
//------------------------------------------------------------------------------------------
// Power Saving
//------------------------------------------------------------------------------------------
category = (PreferenceCategory) findPreference("powersaving");
mPowerEfficientWork = (AwesomeTogglePreference) findPreference("power_efficient_work");
if (mPowerEfficientWork.isSupported()) {
mPowerEfficientWork.initValue();
mPowerEfficientWork.setOnPreferenceChangeListener(this);
} else {
category.removePreference(mPowerEfficientWork);
}
mMcPowerScheduler = (AwesomeListPreference) findPreference("sched_mc_power_savings");
if (mMcPowerScheduler.isSupported()) {
mMcPowerScheduler.initValue();
mMcPowerScheduler.setSummary(mMcPowerScheduler.getEntry());
mMcPowerScheduler.setOnPreferenceChangeListener(this);
} else {
category.removePreference(mMcPowerScheduler);
}
removeIfEmpty(category);
//------------------------------------------------------------------------------------------
// Voltage
//------------------------------------------------------------------------------------------
category = (PreferenceCategory) findPreference("voltage");
mMsmDcvs = (AwesomeTogglePreference) findPreference("msm_dcvs");
if (mMsmDcvs.isSupported()) {
mMsmDcvs.initValue();
mMsmDcvs.setOnPreferenceChangeListener(this);
} else {
category.removePreference(mMsmDcvs);
}
mVoltageControl = (CustomPreference) findPreference("voltage_control");
if (Utils.fileExists(VoltageUtils.VDD_TABLE_FILE) || Utils.fileExists(
VoltageUtils.UV_TABLE_FILE)) {
mVoltageControl.setOnPreferenceClickListener(this);
} else {
category.removePreference(mVoltageControl);
}
removeIfEmpty(category);
//------------------------------------------------------------------------------------------
// Extras
//------------------------------------------------------------------------------------------
category = (PreferenceCategory) findPreference("extras");
buildExtraCategory(category);
removeIfEmpty(category);
isSupported(mRoot, getActivity());
}
private void buildExtraCategory(final PreferenceCategory category) {
mTcpCongestion = (CustomListPreference) findPreference("tcp_congestion_control");
// read the available tcp congestion controls
String tmp = Utils.readFile(TCP_CONGESTION_AVAILABLE);
if (!TextUtils.isEmpty(tmp)) {
// split them
final String[] tcp_avail = tmp.trim().split(" ");
// read the current congestion control
tmp = Utils.readFile(TCP_CONGESTION_CONTROL);
if (!TextUtils.isEmpty(tmp)) {
tmp = tmp.trim();
mTcpCongestion.setEntries(tcp_avail);
mTcpCongestion.setEntryValues(tcp_avail);
mTcpCongestion.setSummary(tmp);
mTcpCongestion.setValue(tmp);
mTcpCongestion.setOnPreferenceChangeListener(this);
}
} else {
category.removePreference(mTcpCongestion);
}
}
private void removeIfEmpty(final PreferenceGroup preferenceGroup) {
if (mRoot != null && preferenceGroup.getPreferenceCount() == 0) {
mRoot.removePreference(preferenceGroup);
}
}
@Override public boolean onPreferenceClick(final Preference preference) {
final int id;
if (mVoltageControl == preference) {
id = DeviceConstants.ID_VOLTAGE;
} else if (mKsm == preference) {
id = DeviceConstants.ID_KSM;
} else if (mUksm == preference) {
id = DeviceConstants.ID_UKSM;
} else if (mEntropy == preference) {
id = DeviceConstants.ID_ENTROPY;
} else {
id = Integer.MIN_VALUE;
}
if (id != Integer.MIN_VALUE) {
final Activity activity = getActivity();
if (activity instanceof ActivityCallbacks) {
((ActivityCallbacks) activity).shouldLoadFragment(id);
}
return true;
}
return false;
}
@Override public boolean onPreferenceChange(Preference preference, Object o) {
if (preference == mPowerEfficientWork) {
mPowerEfficientWork.writeValue((Boolean) o);
return true;
} else if (preference == mMcPowerScheduler) {
final String value = String.valueOf(o);
mMcPowerScheduler.writeValue(value);
if (mMcPowerScheduler.getEntries() != null) {
final String summary =
String.valueOf(mMcPowerScheduler.getEntries()[Utils.parseInt(value)]);
mMcPowerScheduler.setSummary(summary);
}
return true;
} else if (preference == mMsmDcvs) {
mMsmDcvs.writeValue((Boolean) o);
return true;
} else if (preference == mTcpCongestion) {
final String value = String.valueOf(o);
Utils.writeValue(TCP_CONGESTION_CONTROL, value);
BootupConfig.setBootup(new BootupItem(
BootupConfig.CATEGORY_EXTRAS,
mTcpCongestion.getKey(), TCP_CONGESTION_CONTROL, value, true));
preference.setSummary(value);
return true;
}
return false;
}
//==============================================================================================
// Methods
//==============================================================================================
public static String restore(BootupConfig config) {
final ArrayList<BootupItem> items = config
.getItemsByCategory(BootupConfig.CATEGORY_EXTRAS);
if (items.size() == 0) {
return "";
}
final StringBuilder sbCmd = new StringBuilder();
for (final BootupItem item : items) {
if (!item.enabled) {
continue;
}
if (MpDecisionAction.MPDECISION_PATH.equals(item.name)) {
new MpDecisionAction(item.value, false).triggerAction();
} else {
sbCmd.append(Utils.getWriteCommand(item.name, item.value));
}
}
return sbCmd.toString();
}
}