From 5bfc30651af270e18433ed8bc823ba6c776a35f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= <dominik@dominikschuermann.de>
Date: Thu, 27 Aug 2015 00:24:02 +0200
Subject: [PATCH] Refactor, allow installPrivileged from apk path

---
 F-Droid/res/values/strings.xml                |  2 +-
 F-Droid/res/xml/preferences.xml               |  4 +-
 .../src/org/fdroid/fdroid/Preferences.java    | 26 ++++++-------
 .../fdroid/fdroid/installer/Installer.java    |  3 +-
 .../privileged/install/InstallPrivileged.java | 38 +++++++++----------
 .../InstallPrivilegedBootReceiver.java        |  4 +-
 .../InstallPrivilegedDialogActivity.java      |  9 ++---
 .../views/fragments/PreferencesFragment.java  | 23 ++++++-----
 8 files changed, 52 insertions(+), 57 deletions(-)

diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml
index 3c181aa36..8c262df2a 100644
--- a/F-Droid/res/values/strings.xml
+++ b/F-Droid/res/values/strings.xml
@@ -28,7 +28,7 @@
 	<string name="system_installer">Enable privileged F-Droid</string>
 	<string name="system_installer_on">Use privileged permissions to install, update, and remove packages</string>
 	<string name="uninstall_system">Uninstall privileged F-Droid</string>
-	<string name="uninstall_system_summary">Uninstall F-Droid when installed as a privileged app</string>
+	<string name="uninstall_system_summary">Uninstalls the additional privileged F-Droid app</string>
 	<string name="local_repo_name">Name of your Local Repo</string>
 	<string name="local_repo_name_summary">The advertised title of your local repo: %s</string>
 	<string name="local_repo_https">Use Private Connection</string>
diff --git a/F-Droid/res/xml/preferences.xml b/F-Droid/res/xml/preferences.xml
index 708ed5150..e038d5963 100644
--- a/F-Droid/res/xml/preferences.xml
+++ b/F-Droid/res/xml/preferences.xml
@@ -75,11 +75,11 @@
 			android:key="expert" />
 		<CheckBoxPreference android:title="@string/system_installer"
 			android:defaultValue="false"
-			android:key="systemInstaller"
+			android:key="privilegedInstaller"
 			android:dependency="expert" />
 		<Preference android:title="@string/uninstall_system"
 			android:summary="@string/uninstall_system_summary"
-			android:key="uninstallSystemApp"
+			android:key="uninstallPrivilegedApp"
 			android:dependency="expert" />
 	</PreferenceCategory>
 </PreferenceScreen>
diff --git a/F-Droid/src/org/fdroid/fdroid/Preferences.java b/F-Droid/src/org/fdroid/fdroid/Preferences.java
index 1dd04f0a3..2b004d13c 100644
--- a/F-Droid/src/org/fdroid/fdroid/Preferences.java
+++ b/F-Droid/src/org/fdroid/fdroid/Preferences.java
@@ -49,8 +49,8 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
     public static final String PREF_CACHE_APK = "cacheDownloaded";
     public static final String PREF_EXPERT = "expert";
     public static final String PREF_UPD_LAST = "lastUpdateCheck";
-    public static final String PREF_SYSTEM_INSTALLER = "systemInstaller";
-    public static final String PREF_UNINSTALL_SYSTEM_APP = "uninstallSystemApp";
+    public static final String PREF_PRIVILEGED_INSTALLER = "privilegedInstaller";
+    public static final String PREF_UNINSTALL_PRIVILEGED_APP = "uninstallPrivilegedApp";
     public static final String PREF_LOCAL_REPO_NAME = "localRepoName";
     public static final String PREF_LOCAL_REPO_HTTPS = "localRepoHttps";
     public static final String PREF_LANGUAGE = "language";
@@ -59,12 +59,12 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
     public static final String PREF_PROXY_PORT = "proxyPort";
     public static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap";
     public static final String PREF_FIRST_TIME = "firstTime";
-    public static final String PREF_POST_SYSTEM_INSTALL = "postSystemInstall";
+    public static final String PREF_POST_PRIVILEGED_INSTALL = "postPrivilegedInstall";
 
     private static final boolean DEFAULT_COMPACT_LAYOUT = false;
     private static final boolean DEFAULT_ROOTED = true;
     private static final int DEFAULT_UPD_HISTORY = 14;
-    private static final boolean DEFAULT_SYSTEM_INSTALLER = false;
+    private static final boolean DEFAULT_PRIVILEGED_INSTALLER = false;
     private static final boolean DEFAULT_LOCAL_REPO_BONJOUR = true;
     private static final boolean DEFAULT_CACHE_APK = false;
     private static final boolean DEFAULT_LOCAL_REPO_HTTPS = false;
@@ -76,7 +76,7 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
     public static final int DEFAULT_PROXY_PORT = 8118;
     public static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true;
     private static final boolean DEFAULT_FIRST_TIME = true;
-    private static final boolean DEFAULT_POST_SYSTEM_INSTALL = false;
+    private static final boolean DEFAULT_POST_PRIVILEGED_INSTALL = false;
 
     private boolean compactLayout = DEFAULT_COMPACT_LAYOUT;
     private boolean filterAppsRequiringRoot = DEFAULT_ROOTED;
@@ -101,12 +101,12 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
         initialized.put(key, false);
     }
 
-    public boolean isSystemInstallerEnabled() {
-        return preferences.getBoolean(PREF_SYSTEM_INSTALLER, DEFAULT_SYSTEM_INSTALLER);
+    public boolean isPrivilegedInstallerEnabled() {
+        return preferences.getBoolean(PREF_PRIVILEGED_INSTALLER, DEFAULT_PRIVILEGED_INSTALLER);
     }
 
-    public void setSystemInstallerEnabled(boolean enable) {
-        preferences.edit().putBoolean(PREF_SYSTEM_INSTALLER, enable).commit();
+    public void setPrivilegedInstallerEnabled(boolean enable) {
+        preferences.edit().putBoolean(PREF_PRIVILEGED_INSTALLER, enable).commit();
     }
 
     public boolean isFirstTime() {
@@ -117,12 +117,12 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
         preferences.edit().putBoolean(PREF_FIRST_TIME, firstTime).commit();
     }
 
-    public boolean isPostSystemInstall() {
-        return preferences.getBoolean(PREF_POST_SYSTEM_INSTALL, DEFAULT_POST_SYSTEM_INSTALL);
+    public boolean isPostPrivilegedInstall() {
+        return preferences.getBoolean(PREF_POST_PRIVILEGED_INSTALL, DEFAULT_POST_PRIVILEGED_INSTALL);
     }
 
-    public void setPostSystemInstall(boolean postInstall) {
-        preferences.edit().putBoolean(PREF_POST_SYSTEM_INSTALL, postInstall).commit();
+    public void setPostPrivilegedInstall(boolean postInstall) {
+        preferences.edit().putBoolean(PREF_POST_PRIVILEGED_INSTALL, postInstall).commit();
     }
 
     public boolean shouldCacheApks() {
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/Installer.java b/F-Droid/src/org/fdroid/fdroid/installer/Installer.java
index 77f3f9143..a6b725b31 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/Installer.java
+++ b/F-Droid/src/org/fdroid/fdroid/installer/Installer.java
@@ -19,7 +19,6 @@
 
 package org.fdroid.fdroid.installer;
 
-import android.Manifest.permission;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -107,7 +106,7 @@ abstract public class Installer {
             InstallerCallback callback) {
 
         // system permissions and pref enabled -> SystemInstaller
-        boolean isSystemInstallerEnabled = Preferences.get().isSystemInstallerEnabled();
+        boolean isSystemInstallerEnabled = Preferences.get().isPrivilegedInstallerEnabled();
         if (isSystemInstallerEnabled) {
             if (PrivilegedInstaller.isAvailable(activity)) {
                 Utils.DebugLog(TAG, "system permissions -> SystemInstaller");
diff --git a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
index c69292f55..a80c650dd 100644
--- a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
@@ -38,22 +38,20 @@ import eu.chainfire.libsuperuser.Shell;
 abstract class InstallPrivileged {
 
     protected final Context context;
-    protected final String apkPath;
 
     private static final String PACKAGE_NAME = "org.fdroid.fdroid.privileged";
 
-    public InstallPrivileged(final Context context, final String apkPath) {
+    public InstallPrivileged(final Context context) {
         this.context = context;
-        this.apkPath = apkPath;
     }
 
-    public static InstallPrivileged create(final Context context, final String apkPath) {
+    public static InstallPrivileged create(final Context context) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            return new LollipopImpl(context, apkPath);
+            return new LollipopImpl(context);
         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            return new KitKatToLollipopImpl(context, apkPath);
+            return new KitKatToLollipopImpl(context);
         } else {
-            return new PreKitKatImpl(context, apkPath);
+            return new PreKitKatImpl(context);
         }
     }
 
@@ -80,19 +78,19 @@ abstract class InstallPrivileged {
         Shell.SU.run(commands);
     }
 
-    final void runInstall() {
+    final void runInstall(String apkPath) {
         onPreInstall();
-        Shell.SU.run(getInstallCommands());
+        Shell.SU.run(getInstallCommands(apkPath));
     }
 
     protected String getInstallPath() {
         return getSystemFolder() + "FDroidPrivileged.apk";
     }
 
-    private List<String> getInstallCommands() {
+    private List<String> getInstallCommands(String apkPath) {
         final List<String> commands = new ArrayList<>();
         commands.add("mount -o rw,remount /system");
-        commands.addAll(getCopyToSystemCommands());
+        commands.addAll(getCopyToSystemCommands(apkPath));
         commands.add("pm uninstall " + PACKAGE_NAME);
         commands.add("mv " + getInstallPath() + ".tmp " + getInstallPath());
         commands.add("pm install -r " + getInstallPath());
@@ -103,7 +101,7 @@ abstract class InstallPrivileged {
         return commands;
     }
 
-    protected List<String> getCopyToSystemCommands() {
+    protected List<String> getCopyToSystemCommands(String apkPath) {
         final List<String> commands = new ArrayList<>(2);
         commands.add("cat " + apkPath + " > " + getInstallPath() + ".tmp");
         commands.add("chmod 644 " + getInstallPath() + ".tmp");
@@ -118,8 +116,8 @@ abstract class InstallPrivileged {
 
     private static class PreKitKatImpl extends InstallPrivileged {
 
-        public PreKitKatImpl(Context context, String apkPath) {
-            super(context, apkPath);
+        public PreKitKatImpl(Context context) {
+            super(context);
         }
 
         @Override
@@ -131,8 +129,8 @@ abstract class InstallPrivileged {
 
     private static class KitKatToLollipopImpl extends InstallPrivileged {
 
-        public KitKatToLollipopImpl(Context context, String apkPath) {
-            super(context, apkPath);
+        public KitKatToLollipopImpl(Context context) {
+            super(context);
         }
 
         /**
@@ -152,14 +150,14 @@ abstract class InstallPrivileged {
      */
     private static class LollipopImpl extends InstallPrivileged {
 
-        public LollipopImpl(Context context, String apkPath) {
-            super(context, apkPath);
+        public LollipopImpl(Context context) {
+            super(context);
         }
 
         @Override
         protected void onPreInstall() {
             // Setup preference to execute postInstall after reboot
-            Preferences.get().setPostSystemInstall(true);
+            Preferences.get().setPostPrivilegedInstall(true);
         }
 
         public String getWarningInfo() {
@@ -178,7 +176,7 @@ abstract class InstallPrivileged {
          * Create app directory
          */
         @Override
-        protected List<String> getCopyToSystemCommands() {
+        protected List<String> getCopyToSystemCommands(String apkPath) {
             List<String> commands = new ArrayList<>(3);
             commands.add("mkdir -p " + getSystemFolder()); // create app directory if not existing
             commands.add("chmod 755 " + getSystemFolder());
diff --git a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedBootReceiver.java b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedBootReceiver.java
index 7f8598243..9a1cc0173 100644
--- a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedBootReceiver.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedBootReceiver.java
@@ -30,8 +30,8 @@ public class InstallPrivilegedBootReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
-            if (Preferences.get().isPostSystemInstall()) {
-                Preferences.get().setPostSystemInstall(false);
+            if (Preferences.get().isPostPrivilegedInstall()) {
+                Preferences.get().setPostPrivilegedInstall(false);
 
                 Intent postInstall = new Intent(context.getApplicationContext(), InstallPrivilegedDialogActivity.class);
                 postInstall.setAction(InstallPrivilegedDialogActivity.ACTION_POST_INSTALL);
diff --git a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedDialogActivity.java b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedDialogActivity.java
index b413cad0b..ece28975a 100644
--- a/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedDialogActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivilegedDialogActivity.java
@@ -40,7 +40,6 @@ import org.fdroid.fdroid.FDroid;
 import org.fdroid.fdroid.FDroidApp;
 import org.fdroid.fdroid.Preferences;
 import org.fdroid.fdroid.R;
-import org.fdroid.fdroid.installer.Installer;
 import org.fdroid.fdroid.installer.PrivilegedInstaller;
 
 import eu.chainfire.libsuperuser.Shell;
@@ -88,7 +87,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
             Preferences.get().setFirstTime(false);
 
             if (PrivilegedInstaller.isAvailable(context)) {
-                Preferences.get().setSystemInstallerEnabled(true);
+                Preferences.get().setPrivilegedInstallerEnabled(true);
             } else {
                 runFirstTime(context);
             }
@@ -160,7 +159,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
         ContextThemeWrapper theme = new ContextThemeWrapper(this, FDroidApp.getCurThemeResId());
 
         String message = getString(R.string.system_install_first_time_message) + "<br/><br/>"
-                + InstallPrivileged.create(getApplicationContext(), null).getWarningInfo();
+                + InstallPrivileged.create(getApplicationContext()).getWarningInfo();
 
         AlertDialog.Builder builder = new AlertDialog.Builder(theme)
                 .setMessage(Html.fromHtml(message))
@@ -269,7 +268,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
 
         @Override
         protected Void doInBackground(Void... voids) {
-            InstallPrivileged.create(getApplicationContext()).runInstall();
+            InstallPrivileged.create(getApplicationContext()).runInstall("test"); // TODO
             return null;
         }
     };
@@ -284,7 +283,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
         final boolean success = PrivilegedInstaller.isAvailable(this);
 
         // enable system installer on installation success
-        Preferences.get().setSystemInstallerEnabled(success);
+        Preferences.get().setPrivilegedInstallerEnabled(success);
 
         AlertDialog.Builder builder = new AlertDialog.Builder(theme)
                 .setTitle(success ? R.string.system_install_post_success : R.string.system_install_post_fail)
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
index f87644e75..69c473651 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
@@ -21,7 +21,6 @@ import org.fdroid.fdroid.R;
 import org.fdroid.fdroid.Utils;
 import org.fdroid.fdroid.installer.PrivilegedInstaller;
 import org.fdroid.fdroid.privileged.install.InstallPrivilegedDialogActivity;
-import org.fdroid.fdroid.installer.Installer;
 
 import java.util.Locale;
 
@@ -42,7 +41,7 @@ public class PreferencesFragment extends PreferenceFragment
         Preferences.PREF_LANGUAGE,
         Preferences.PREF_CACHE_APK,
         Preferences.PREF_EXPERT,
-        Preferences.PREF_SYSTEM_INSTALLER,
+        Preferences.PREF_PRIVILEGED_INSTALLER,
         Preferences.PREF_ENABLE_PROXY,
         Preferences.PREF_PROXY_HOST,
         Preferences.PREF_PROXY_PORT,
@@ -150,7 +149,7 @@ public class PreferencesFragment extends PreferenceFragment
             checkSummary(key, R.string.expert_on);
             break;
 
-        case Preferences.PREF_SYSTEM_INSTALLER:
+        case Preferences.PREF_PRIVILEGED_INSTALLER:
             checkSummary(key, R.string.system_installer_on);
             break;
 
@@ -183,8 +182,8 @@ public class PreferencesFragment extends PreferenceFragment
     /**
      * Initializes SystemInstaller preference, which can only be enabled when F-Droid is installed as a system-app
      */
-    protected void initSystemInstallerPreference() {
-        CheckBoxPreference pref = (CheckBoxPreference) findPreference(Preferences.PREF_SYSTEM_INSTALLER);
+    protected void initPrivilegedInstallerPreference() {
+        CheckBoxPreference pref = (CheckBoxPreference) findPreference(Preferences.PREF_PRIVILEGED_INSTALLER);
 
         // we are handling persistence ourself!
         pref.setPersistent(false);
@@ -199,13 +198,13 @@ public class PreferencesFragment extends PreferenceFragment
                     if (PrivilegedInstaller.isAvailable(getActivity())) {
                         // system-permission are granted, i.e. F-Droid is a system-app
                         SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
-                        editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, true);
+                        editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, true);
                         editor.commit();
                         pref.setChecked(true);
                     } else {
                         // system-permission not available
                         SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
-                        editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false);
+                        editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, false);
                         editor.commit();
                         pref.setChecked(false);
 
@@ -232,7 +231,7 @@ public class PreferencesFragment extends PreferenceFragment
                     }
                 } else {
                     SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
-                    editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false);
+                    editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, false);
                     editor.commit();
                     pref.setChecked(false);
                 }
@@ -242,8 +241,8 @@ public class PreferencesFragment extends PreferenceFragment
         });
     }
 
-    protected void initUninstallSystemAppPreference() {
-        Preference pref = findPreference(Preferences.PREF_UNINSTALL_SYSTEM_APP);
+    protected void initUninstallPrivilegedAppPreference() {
+        Preference pref = findPreference(Preferences.PREF_UNINSTALL_PRIVILEGED_APP);
         pref.setPersistent(false);
 
         pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@@ -281,8 +280,8 @@ public class PreferencesFragment extends PreferenceFragment
             updateSummary(key, false);
         }
 
-        initSystemInstallerPreference();
-        initUninstallSystemAppPreference();
+        initPrivilegedInstallerPreference();
+        initUninstallPrivilegedAppPreference();
     }
 
     @Override