package de.theknut.xposedgelsettings.ui;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.support.v4.app.ActivityCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import de.theknut.xposedgelsettings.R;
import de.theknut.xposedgelsettings.hooks.Common;
import de.theknut.xposedgelsettings.hooks.Utils;
@SuppressLint("SdCardPath")
public class FragmentBackupRestore extends FragmentBase {
public FragmentBackupRestore() { }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.options_fragment, container, false);
addPreferencesFromResource(R.xml.backuprestore_fragment);
OnPreferenceClickListener BackupRestoreHomescreenListener = new OnPreferenceClickListener() {
String copyCommand = "cat ";
@SuppressLint("WorldReadableFiles")
public boolean onPreferenceClick(Preference preference) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Common.XGELS_CONTEXT = mActivity;
Utils.requestPermission(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 55);
return false;
}
String path = getExternalSDCardDirectory();
String sd_trebuchet = path + "XposedGELSettings/Trebuchet/";
String data_trebuchet = "/data/data/" + Common.TREBUCHET_PACKAGE + "/";
String sd_gel = path + "XposedGELSettings/GEL/";
String data_gel = "/data/data/" + Common.GEL_PACKAGE + "/";
String sdcard_gel_launcherDB = sd_gel + "launcher.db";
String sdcard_gel_launcherDBJournal = sd_gel + "launcher.db-journal";
String data_gel_launcherDB = data_gel + "databases/launcher.db";
String data_gel_launcherDBJournal = data_gel + "databases/launcher.db-journal";
String sdcard_trebuchet_launcherDB = sd_trebuchet + "launcher.db";
String sdcard_trebuchet_launcherDBJournal = sd_trebuchet + "launcher.db-journal";
String data_trebuchet_launcherDB = data_trebuchet + "databases/launcher.db";
String data_trebuchet_launcherDBJournal = data_trebuchet + "databases/launcher.db-journal";
//sdcard_xgels.getParentFile().mkdirs();
if (preference.getKey().contains("restorehomescreen")) {
if (CommonUI.isPackageInstalled(Common.GEL_PACKAGE, mContext)) {
File launcherDBJournal = new File(data_gel_launcherDBJournal);
if (launcherDBJournal.length() == 0) {
// copy from sdcard to data
String sd2data_1 = copyCommand + sdcard_gel_launcherDB + " > " + data_gel_launcherDB;
copy(Common.GEL_PACKAGE, sd2data_1, true);
}
else {
// copy from sdcard to data
String sd2data_1 = copyCommand + sdcard_gel_launcherDB + " > " + data_gel_launcherDB;
String sd2data_2 = copyCommand + sdcard_gel_launcherDBJournal + " > " + data_gel_launcherDBJournal;
copy(Common.GEL_PACKAGE, sd2data_1, sd2data_2, true);
}
}
if (CommonUI.isPackageInstalled(Common.TREBUCHET_PACKAGE, mContext)) {
File launcherDBJournal = new File(data_trebuchet_launcherDBJournal);
if (launcherDBJournal.length() == 0) {
// copy from sdcard to data
String sd2data_3 = copyCommand + sdcard_trebuchet_launcherDB + " > " + data_trebuchet_launcherDB;
copy(Common.TREBUCHET_PACKAGE, sd2data_3, true);
}
else {
// copy from sdcard to data
String sd2data_3 = copyCommand + sdcard_trebuchet_launcherDB + " > " + data_trebuchet_launcherDB;
String sd2data_4 = copyCommand + sdcard_trebuchet_launcherDBJournal + " > " + data_trebuchet_launcherDBJournal;
copy(Common.TREBUCHET_PACKAGE, sd2data_3, sd2data_4, true);
}
}
restartLauncher();
}
else if (preference.getKey().contains("backuphomescreen")) {
if (CommonUI.isPackageInstalled(Common.GEL_PACKAGE, mContext)) {
File launcherDBJournal = new File(data_gel_launcherDBJournal);
if (launcherDBJournal.length() == 0) {
String data2sd_1 = copyCommand + data_gel_launcherDB + " > " + sdcard_gel_launcherDB;
//sdcard_gels.getParentFile().mkdirs();
copy(Common.GEL_PACKAGE, data2sd_1, false);
}
else {
String data2sd_1 = copyCommand + data_gel_launcherDB + " > " + sdcard_gel_launcherDB;
String data2sd_2 = copyCommand + data_gel_launcherDBJournal + " > " + sdcard_gel_launcherDBJournal;
//sdcard_gels.getParentFile().mkdirs();
copy(Common.GEL_PACKAGE, data2sd_1, data2sd_2, false);
}
}
if (CommonUI.isPackageInstalled(Common.TREBUCHET_PACKAGE, mContext)) {
File launcherDBJournal = new File(data_trebuchet_launcherDBJournal);
if (launcherDBJournal.length() == 0) {
String data2sd_1 = copyCommand + data_trebuchet_launcherDB + " > " + sdcard_trebuchet_launcherDB;
//sdcard_trebuchet.getParentFile().mkdirs();
copy(Common.TREBUCHET_PACKAGE, data2sd_1, false);
}
else {
String data2sd_3 = copyCommand + data_trebuchet_launcherDB + " > " + sdcard_trebuchet_launcherDB;
String data2sd_4 = copyCommand + data_trebuchet_launcherDBJournal + " > " + sdcard_trebuchet_launcherDBJournal;
//sdcard_trebuchet.getParentFile().mkdirs();
copy(Common.TREBUCHET_PACKAGE, data2sd_3, data2sd_4, false);
}
}
}
return true;
}
public boolean restartLauncher() {
Context context = mContext;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String msg = "Killed:\n";
List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
for (RunningAppProcessInfo process : processes) {
if (Common.PACKAGE_NAMES.contains(process.processName)) {
am.killBackgroundProcesses(process.processName);
msg += process.processName + "\n";
}
}
if (msg.equals("Killed:\n")) {
msg = msg.substring(0, msg.lastIndexOf('\n')) + " " + context.getString(R.string.toast_reboot_failed_nothing_msg) + "... :(\n" + context.getString(R.string.toast_reboot_failed);
}
else {
msg = msg.substring(0, msg.lastIndexOf('\n'));
}
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
return true;
}
public boolean copy(String packageName, String command1, String command2, boolean setPermissions) {
String data_launcherDB = "/data/data/" + packageName + "/databases/launcher.db";
String data_launcherDBJournal = "/data/data/" + packageName + "/databases/launcher.db-journal";
ArrayList<String> commands = new ArrayList<String>();
commands.add("su");
commands.add("mkdir -p " + getExternalSDCardDirectory() + "/XposedGELSettings/GEL");
commands.add("mkdir -p " + getExternalSDCardDirectory() + "/XposedGELSettings/Trebuchet");
commands.add(command1);
commands.add(command2);
if (setPermissions) {
commands.add("chmod 0660 " + data_launcherDB);
commands.add("chmod 0700 " + data_launcherDBJournal);
}
CommonUI.openRootShell(commands.toArray(new String[commands.size()]));
return true;
}
public boolean copy(String packageName, String command1, boolean setPermissions) {
String data_launcherDB = "/data/data/" + packageName + "/databases/launcher.db";
ArrayList<String> commands = new ArrayList<String>();
commands.add("su");
commands.add("mkdir -p " + getExternalSDCardDirectory() + "/XposedGELSettings/GEL");
commands.add("mkdir -p " + getExternalSDCardDirectory() + "/XposedGELSettings/Trebuchet");
commands.add(command1);
if (setPermissions) {
commands.add("chmod 0660 " + data_launcherDB);
}
CommonUI.openRootShell(commands.toArray(new String[commands.size()]));
return true;
}
public String getExternalSDCardDirectory()
{
return "/mnt/sdcard/";
}
};
this.findPreference("backuphomescreen").setOnPreferenceClickListener(BackupRestoreHomescreenListener);
this.findPreference("restorehomescreen").setOnPreferenceClickListener(BackupRestoreHomescreenListener);
OnPreferenceClickListener ImExportResetSettingsListener = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation")
@SuppressLint("WorldReadableFiles")
public boolean onPreferenceClick(Preference preference) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Common.XGELS_CONTEXT = mActivity;
Utils.requestPermission(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 55);
return false;
}
File sdcard = new File(Environment.getExternalStorageDirectory().getPath() + "/XposedGELSettings/" + Common.PREFERENCES_NAME + ".xml");
File data = new File(mContext.getFilesDir(), "../shared_prefs/"+ Common.PREFERENCES_NAME + ".xml");
sdcard.getParentFile().mkdirs();
data.getParentFile().mkdirs();
if (preference.getKey().contains("importsettings")) {
boolean success = false;
try {
// copy from sdcard to data
success = copy(sdcard, data);
// set permissions
chmod(new File (mContext.getFilesDir(), "../shared_prefs"), 0771);
chmod(data, 0664);
} catch (Exception e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(mContext, getString(R.string.toast_import), Toast.LENGTH_LONG).show();
CommonUI.restartLauncher(false);
CommonUI.restartActivity();
}
else {
Toast.makeText(mContext, getString(R.string.toast_import_failed), Toast.LENGTH_LONG).show();
}
}
else if (preference.getKey().contains("exportsettings")) {
boolean success = false;
try {
// copy from data to sdcard
success = copy(data, sdcard);
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(mContext, getString(R.string.toast_export), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(mContext, getString(R.string.toast_export_failed), Toast.LENGTH_LONG).show();
}
}
else if (preference.getKey().contains("resetsettings")) {
boolean success = mContext.getSharedPreferences(Common.PREFERENCES_NAME, Context.MODE_WORLD_READABLE).edit().clear().commit();
if (success) {
Toast.makeText(mContext, getString(R.string.toast_reset), Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(mContext, getString(R.string.toast_reset_failed), Toast.LENGTH_LONG).show();
}
}
return true;
}
public boolean copy(File src, File dst) throws IOException {
if (!src.exists()) {
src.createNewFile();
}
if (!dst.exists()) {
dst.createNewFile();
}
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
return true;
}
public int chmod(File path, int mode) throws Exception {
Class<?> fileUtils = Class.forName("android.os.FileUtils");
Method setPermissions = fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class);
return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1);
}
};
this.findPreference("importsettings").setOnPreferenceClickListener(ImExportResetSettingsListener);
this.findPreference("exportsettings").setOnPreferenceClickListener(ImExportResetSettingsListener);
this.findPreference("resetsettings").setOnPreferenceClickListener(ImExportResetSettingsListener);
PreferenceScreen preferenceScreen = getPreferenceScreen();
if (!InAppPurchase.isPremium) {
for (int i = 0; i < preferenceScreen.getPreferenceCount(); i++) {
Preference pref = preferenceScreen.getPreference(i);
if (pref.hasKey() && pref.getKey().equals("needsDonate")) {
continue;
}
pref.setEnabled(false);
}
this.findPreference("needsDonate").setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
CommonUI.needFullReboot = true;
return false;
}
});
}
else {
preferenceScreen.removePreference(this.findPreference("needsDonate"));
}
rootView = CommonUI.setBackground(rootView, R.id.prefbackground);
return rootView;
}
}