/*
* 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.performance.sub;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import org.namelessrom.devicecontrol.App;
import org.namelessrom.devicecontrol.DeviceConstants;
import org.namelessrom.devicecontrol.R;
import org.namelessrom.devicecontrol.hardware.ExtraUtils;
import org.namelessrom.devicecontrol.models.ExtraConfig;
import org.namelessrom.devicecontrol.preferences.AwesomeEditTextPreference;
import org.namelessrom.devicecontrol.preferences.CustomPreference;
import org.namelessrom.devicecontrol.preferences.CustomTogglePreference;
import org.namelessrom.devicecontrol.utils.AppHelper;
import org.namelessrom.devicecontrol.utils.ShellOutput;
import org.namelessrom.devicecontrol.utils.Utils;
import org.namelessrom.devicecontrol.views.AttachPreferenceProgressFragment;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import at.amartinz.execution.RootShell;
import timber.log.Timber;
public class EntropyFragment extends AttachPreferenceProgressFragment implements Preference.OnPreferenceChangeListener, ShellOutput.OnShellOutputListener {
private static final String URL_RNG =
"http://sourceforge.net/projects/namelessrom/files/romextras/binaries/rngd/download";
private static final File RNGD = new File(App.get().getFilesDirectory(), "rngd");
private CustomPreference mEntropyAvail;
private AwesomeEditTextPreference mReadWakeupThreshold;
private AwesomeEditTextPreference mWriteWakeupThreshold;
private CustomTogglePreference mRngActive;
private CustomTogglePreference mRngStartup;
@Override protected int getFragmentId() { return DeviceConstants.ID_ENTROPY; }
@Override public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.extras_entropy);
setHasOptionsMenu(true);
PreferenceCategory category = (PreferenceCategory) findPreference("entropy");
mEntropyAvail = (CustomPreference) findPreference("entropy_avail");
if (!Utils.fileExists(ExtraUtils.ENTROPY_AVAIL)) {
category.removePreference(mEntropyAvail);
}
mReadWakeupThreshold =
(AwesomeEditTextPreference) findPreference("entropy_read_wakeup_threshold");
if (mReadWakeupThreshold.isSupported()) {
mReadWakeupThreshold.initValue();
mReadWakeupThreshold.setOnPreferenceChangeListener(this);
} else {
category.removePreference(mReadWakeupThreshold);
}
mWriteWakeupThreshold =
(AwesomeEditTextPreference) findPreference("entropy_write_wakeup_threshold");
if (mWriteWakeupThreshold.isSupported()) {
mWriteWakeupThreshold.initValue();
mWriteWakeupThreshold.setOnPreferenceChangeListener(this);
} else {
category.removePreference(mWriteWakeupThreshold);
}
// category = (PreferenceCategory) findPreference("rng");
mRngStartup = (CustomTogglePreference) findPreference(ExtraConfig.RNG_STARTUP);
mRngStartup.setChecked(ExtraConfig.get().rngStartup);
mRngStartup.setOnPreferenceChangeListener(this);
mRngActive = (CustomTogglePreference) findPreference("rng_active");
AppHelper.getProcess(this, RNGD.getAbsolutePath());
mRngActive.setOnPreferenceChangeListener(this);
new RefreshTask().execute();
isSupported(getPreferenceScreen(), getActivity());
}
@Override public boolean onPreferenceChange(final Preference preference, final Object o) {
if (mReadWakeupThreshold == preference) {
final String value = String.valueOf(o);
mReadWakeupThreshold.writeValue(value);
return true;
} else if (mWriteWakeupThreshold == preference) {
final String value = String.valueOf(o);
mWriteWakeupThreshold.writeValue(value);
return true;
} else if (mRngStartup == preference) {
ExtraConfig.get().rngStartup = (Boolean) o;
ExtraConfig.get().save();
return true;
} else if (mRngActive == preference) {
if (!RNGD.exists()) {
Timber.i("%s does not exist, downloading...", RNGD.getAbsolutePath());
mRngActive.setEnabled(false);
mProgressBar.setVisibility(View.VISIBLE);
// else download it
Ion.with(this)
.load(URL_RNG)
.progress(mProgressBar)
.write(RNGD)
.setCallback(new FutureCallback<File>() {
@Override public void onCompleted(final Exception e, final File res) {
if (e != null) {
Timber.e("Error downloading rngd!");
if (mRngActive != null) {
mRngActive.setSummary(R.string.error_download);
}
return;
}
if (mRngActive != null) {
mRngActive.setEnabled(true);
}
setRngdPermissions();
AppHelper.getProcess(EntropyFragment.this, RNGD.getAbsolutePath());
mProgressBar.setVisibility(View.GONE);
}
});
return false;
}
setRngdPermissions();
if ((Boolean) o) {
Timber.v("Starting rngd");
RootShell.fireAndForget(String.format("%s -P;\n", RNGD.getAbsolutePath()));
} else {
Timber.v("Stopping rngd");
AppHelper.killProcess(getActivity(), RNGD.getAbsolutePath());
}
AppHelper.getProcess(this, RNGD.getAbsolutePath());
return true;
}
return false;
}
public void setRngdPermissions() {
Timber.v("RNGD --> setReadable: %s, setExectuable: %s",
RNGD.setReadable(true, false),
RNGD.setExecutable(true, false));
}
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_refresh, menu);
}
@Override public boolean onOptionsItemSelected(final MenuItem item) {
final int id = item.getItemId();
switch (id) {
case R.id.menu_action_refresh:
new RefreshTask().execute();
AppHelper.getProcess(this, RNGD.getAbsolutePath());
default:
break;
}
return false;
}
public void onShellOutput(final ShellOutput shellOutput) {
if (shellOutput == null) { return; }
if (shellOutput.id == DeviceConstants.ID_PGREP) {
if (mRngActive != null) {
final boolean isActive =
shellOutput.output != null && !shellOutput.output.isEmpty();
mRngActive.setChecked(isActive);
if (!RNGD.exists()) {
mRngActive.setSummary(R.string.install_rng);
mRngStartup.setEnabled(false);
} else {
mRngActive.setSummary("");
mRngStartup.setEnabled(true);
}
}
}
}
public static String restore() {
if (ExtraConfig.get().rngStartup) {
return String.format("%s -P;\n", RNGD.getAbsolutePath());
}
return "";
}
private class RefreshTask extends AsyncTask<Void, Void, List<String>> {
@Override protected List<String> doInBackground(Void... params) {
final ArrayList<String> list = new ArrayList<>();
list.add(Utils.readOneLine(ExtraUtils.ENTROPY_AVAIL)); // 0
return list;
}
@Override protected void onPostExecute(final List<String> strings) {
if (isAdded()) {
String tmp;
if (mEntropyAvail != null) {
tmp = strings.get(0);
Timber.v("strings.get(0): %s", tmp);
mEntropyAvail.setSummary(tmp);
}
}
}
}
}