/*
* 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.hardware;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import org.namelessrom.devicecontrol.App;
import org.namelessrom.devicecontrol.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import at.amartinz.execution.Command;
import at.amartinz.execution.Shell;
import at.amartinz.execution.ShellManager;
import timber.log.Timber;
public class IoUtils {
public static final String[] IO_SCHEDULER_PATH = {
"/sys/block/mmcblk0/queue/scheduler",
"/sys/block/mmcblk1/queue/scheduler"
};
public static final String[] READ_AHEAD_PATH = {
"/sys/block/mmcblk0/queue/read_ahead_kb",
"/sys/block/mmcblk1/queue/read_ahead_kb"
};
public static class IoScheduler {
public final String[] available;
public final String current;
public IoScheduler(final String[] availableIoSchedulers, final String ioScheduler) {
available = availableIoSchedulers;
current = ioScheduler;
}
}
public interface IoSchedulerListener {
void onIoScheduler(final IoScheduler ioScheduler);
}
private static IoUtils sInstance;
private IoUtils() { }
public static IoUtils get() {
if (sInstance == null) {
sInstance = new IoUtils();
}
return sInstance;
}
/**
* Gets available schedulers from file
*
* @return available schedulers
*/
@Nullable public String[] getAvailableIoSchedulers() {
String[] schedulers = null;
final String[] aux = Utils.readStringArray(IO_SCHEDULER_PATH[0]);
if (aux != null) {
schedulers = new String[aux.length];
for (int i = 0; i < aux.length; i++) {
if (aux[i].charAt(0) == '[') {
schedulers[i] = aux[i].substring(1, aux[i].length() - 1);
} else {
schedulers[i] = aux[i];
}
}
}
return schedulers;
}
public void getIoScheduler(final IoSchedulerListener listener) {
final Shell shell;
if (new File(IO_SCHEDULER_PATH[0]).canRead()) {
Timber.v("Using normal shell!");
shell = ShellManager.get().getNormalShell();
} else {
Timber.v("Using root shell!");
shell = ShellManager.get().getRootShell();
}
if (shell == null) {
Timber.e("Could not open shell!");
return;
}
final String cmd = String.format("cat \"%s\" 2> /dev/null;", IO_SCHEDULER_PATH[0]);
final Command command = new IoCommand(cmd, listener);
command.setOutputType(Command.OUTPUT_STRING);
shell.add(command);
}
private static class IoCommand extends Command {
private final IoSchedulerListener listener;
public IoCommand(String cmd, IoSchedulerListener listener) {
super(cmd);
this.listener = listener;
}
@Override public void onCommandCompleted(int id, int exitCode) {
super.onCommandCompleted(id, exitCode);
final String output = getOutput();
if (output == null) {
return;
}
final List<String> result = Arrays.asList(output.split(" "));
if (result.isEmpty()) {
return;
}
final List<String> tmpList = new ArrayList<>();
String tmpString = "";
for (final String s : result) {
if (TextUtils.isEmpty(s)) {
continue;
}
if (s.charAt(0) == '[') {
tmpString = s.substring(1, s.length() - 1);
tmpList.add(tmpString);
} else {
tmpList.add(s);
}
}
final String scheduler = tmpString;
final String[] availableSchedulers = tmpList.toArray(new String[tmpList.size()]);
App.HANDLER.post(new Runnable() {
@Override public void run() {
listener.onIoScheduler(new IoScheduler(availableSchedulers, scheduler));
}
});
}
}
}