/*
* 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.services;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.TextUtils;
import org.namelessrom.devicecontrol.hardware.GpuUtils;
import org.namelessrom.devicecontrol.models.BootupConfig;
import org.namelessrom.devicecontrol.models.DeviceConfig;
import org.namelessrom.devicecontrol.models.TaskerConfig;
import org.namelessrom.devicecontrol.modules.bootup.BootupItem;
import org.namelessrom.devicecontrol.modules.cpu.CpuUtils;
import org.namelessrom.devicecontrol.modules.device.DeviceFeatureFragment;
import org.namelessrom.devicecontrol.modules.device.DeviceFeatureKernelFragment;
import org.namelessrom.devicecontrol.modules.editor.SysctlFragment;
import org.namelessrom.devicecontrol.modules.performance.sub.EntropyFragment;
import org.namelessrom.devicecontrol.modules.performance.sub.VoltageFragment;
import org.namelessrom.devicecontrol.utils.AlarmHelper;
import org.namelessrom.devicecontrol.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import at.amartinz.execution.BusyBox;
import at.amartinz.execution.RootCheck;
import at.amartinz.execution.RootShell;
import at.amartinz.execution.ShellManager;
import hugo.weaving.DebugLog;
import io.paperdb.Paper;
import timber.log.Timber;
public class BootupService extends IntentService {
public BootupService() {
super("BootupService");
}
@Override protected void onHandleIntent(Intent intent) {
if (intent == null) {
stopSelf();
return;
}
startBootupRestoration();
}
@Override public void onDestroy() {
Timber.d("closing shells");
ShellManager.get().cleanupShells();
super.onDestroy();
}
private void startBootupRestoration() {
Paper.init(this);
final DeviceConfig configuration = DeviceConfig.get();
if (configuration.dcFirstStart) {
Timber.i("First start not completed, exiting");
return;
}
//========================================================================================================================
// No Root, No Friends, That's Life ...
//========================================================================================================================
if (!RootCheck.isRooted()) {
Timber.e("No Root, No Friends, That's Life ...");
return;
}
// patch sepolicy
Utils.patchSEPolicy(this);
final BootupConfig bootupConfig = BootupConfig.get();
final int delay = bootupConfig.automatedRestorationDelay;
if (delay > 0) {
Timber.v("Delaying bootup restoration by %s seconds", delay);
}
new Handler().postDelayed(new BootupRunnable(getApplicationContext(), bootupConfig), delay);
}
private static final class BootupRunnable implements Runnable {
private BootupConfig bootupConfig;
private Context context;
public BootupRunnable(Context context, BootupConfig bootupConfig) {
this.context = context;
this.bootupConfig = bootupConfig;
}
@DebugLog @Override public void run() {
//========================================================================================================================
// Tasker
//========================================================================================================================
final TaskerConfig taskerConfig = TaskerConfig.get();
if (taskerConfig.fstrimEnabled) {
Timber.v("Scheduling Tasker - FSTRIM");
AlarmHelper.setAlarmFstrim(context, taskerConfig.fstrimInterval);
}
//========================================================================================================================
// Fields For Reapplying
//========================================================================================================================
final StringBuilder sbCmd = new StringBuilder();
String cmd;
//========================================================================================================================
// Custom Shell Command
//========================================================================================================================
//sbCmd.append(PreferenceHelper.getString(CUSTOM_SHELL_COMMAND,"echo \"Hello world!\"")).append(";\n");
//========================================================================================================================
// Device
//========================================================================================================================
Timber.v("----- DEVICE START -----");
cmd = DeviceFeatureFragment.restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- DEVICE END -----");
//========================================================================================================================
// Performance
//========================================================================================================================
Timber.v("----- CPU START -----");
cmd = CpuUtils.get().restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- CPU END -----");
Timber.v("----- GPU START -----");
cmd = GpuUtils.get().restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- GPU END -----");
Timber.v("----- EXTRAS START -----");
cmd = DeviceFeatureKernelFragment.restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- EXTRAS END -----");
Timber.v("----- VOLTAGE START -----");
// TODO: FULLY convert to bootup
cmd = VoltageFragment.restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- VOLTAGE END -----");
//========================================================================================================================
// Tools
//========================================================================================================================
Timber.v("----- TOOLS START -----");
cmd = SysctlFragment.restore(bootupConfig);
Timber.v(cmd);
sbCmd.append(cmd);
if (new File("/system/etc/sysctl.conf").exists()) {
sbCmd.append(BusyBox.callBusyBoxApplet("sysctl", "-p;"));
}
cmd = EntropyFragment.restore();
if (!TextUtils.isEmpty(cmd)) {
Timber.v(cmd);
sbCmd.append(cmd);
}
Timber.v("----- TOOLS END -----");
Timber.v("----- SPECIAL START -----");
cmd = restoreCategory(bootupConfig, BootupConfig.CATEGORY_INTELLI_HOTPLUG);
Timber.v(cmd);
sbCmd.append(cmd);
cmd = restoreCategory(bootupConfig, BootupConfig.CATEGORY_MAKO_HOTPLUG);
Timber.v(cmd);
sbCmd.append(cmd);
Timber.v("----- SPECIAL END -----");
//========================================================================================================================
// Execute
//========================================================================================================================
cmd = sbCmd.toString();
Timber.v("Starting bootup with cmd:\n%s", cmd);
if (!cmd.isEmpty()) {
RootShell.fireAndBlock(cmd);
}
Timber.v("Bootup Done!");
}
private String restoreCategory(BootupConfig config, String category) {
final ArrayList<BootupItem> items = config.getItemsByCategory(category);
if (items.size() == 0) {
return "";
}
final StringBuilder sbCmd = new StringBuilder();
for (final BootupItem item : items) {
if (!item.enabled) {
continue;
}
sbCmd.append(Utils.getWriteCommand(item.filename, item.value));
}
return sbCmd.toString();
}
}
}