Refactor, allow installPrivileged from apk path

This commit is contained in:
Dominik Schürmann 2015-08-27 00:24:02 +02:00
parent 57af421561
commit 5bfc30651a
8 changed files with 52 additions and 57 deletions

View File

@ -28,7 +28,7 @@
<string name="system_installer">Enable privileged F-Droid</string> <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="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">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">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_name_summary">The advertised title of your local repo: %s</string>
<string name="local_repo_https">Use Private Connection</string> <string name="local_repo_https">Use Private Connection</string>

View File

@ -75,11 +75,11 @@
android:key="expert" /> android:key="expert" />
<CheckBoxPreference android:title="@string/system_installer" <CheckBoxPreference android:title="@string/system_installer"
android:defaultValue="false" android:defaultValue="false"
android:key="systemInstaller" android:key="privilegedInstaller"
android:dependency="expert" /> android:dependency="expert" />
<Preference android:title="@string/uninstall_system" <Preference android:title="@string/uninstall_system"
android:summary="@string/uninstall_system_summary" android:summary="@string/uninstall_system_summary"
android:key="uninstallSystemApp" android:key="uninstallPrivilegedApp"
android:dependency="expert" /> android:dependency="expert" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@ -49,8 +49,8 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
public static final String PREF_CACHE_APK = "cacheDownloaded"; public static final String PREF_CACHE_APK = "cacheDownloaded";
public static final String PREF_EXPERT = "expert"; public static final String PREF_EXPERT = "expert";
public static final String PREF_UPD_LAST = "lastUpdateCheck"; public static final String PREF_UPD_LAST = "lastUpdateCheck";
public static final String PREF_SYSTEM_INSTALLER = "systemInstaller"; public static final String PREF_PRIVILEGED_INSTALLER = "privilegedInstaller";
public static final String PREF_UNINSTALL_SYSTEM_APP = "uninstallSystemApp"; 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_NAME = "localRepoName";
public static final String PREF_LOCAL_REPO_HTTPS = "localRepoHttps"; public static final String PREF_LOCAL_REPO_HTTPS = "localRepoHttps";
public static final String PREF_LANGUAGE = "language"; 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_PROXY_PORT = "proxyPort";
public static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap"; public static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap";
public static final String PREF_FIRST_TIME = "firstTime"; 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_COMPACT_LAYOUT = false;
private static final boolean DEFAULT_ROOTED = true; private static final boolean DEFAULT_ROOTED = true;
private static final int DEFAULT_UPD_HISTORY = 14; 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_LOCAL_REPO_BONJOUR = true;
private static final boolean DEFAULT_CACHE_APK = false; private static final boolean DEFAULT_CACHE_APK = false;
private static final boolean DEFAULT_LOCAL_REPO_HTTPS = 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 int DEFAULT_PROXY_PORT = 8118;
public static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true; public static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true;
private static final boolean DEFAULT_FIRST_TIME = 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 compactLayout = DEFAULT_COMPACT_LAYOUT;
private boolean filterAppsRequiringRoot = DEFAULT_ROOTED; private boolean filterAppsRequiringRoot = DEFAULT_ROOTED;
@ -101,12 +101,12 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
initialized.put(key, false); initialized.put(key, false);
} }
public boolean isSystemInstallerEnabled() { public boolean isPrivilegedInstallerEnabled() {
return preferences.getBoolean(PREF_SYSTEM_INSTALLER, DEFAULT_SYSTEM_INSTALLER); return preferences.getBoolean(PREF_PRIVILEGED_INSTALLER, DEFAULT_PRIVILEGED_INSTALLER);
} }
public void setSystemInstallerEnabled(boolean enable) { public void setPrivilegedInstallerEnabled(boolean enable) {
preferences.edit().putBoolean(PREF_SYSTEM_INSTALLER, enable).commit(); preferences.edit().putBoolean(PREF_PRIVILEGED_INSTALLER, enable).commit();
} }
public boolean isFirstTime() { public boolean isFirstTime() {
@ -117,12 +117,12 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
preferences.edit().putBoolean(PREF_FIRST_TIME, firstTime).commit(); preferences.edit().putBoolean(PREF_FIRST_TIME, firstTime).commit();
} }
public boolean isPostSystemInstall() { public boolean isPostPrivilegedInstall() {
return preferences.getBoolean(PREF_POST_SYSTEM_INSTALL, DEFAULT_POST_SYSTEM_INSTALL); return preferences.getBoolean(PREF_POST_PRIVILEGED_INSTALL, DEFAULT_POST_PRIVILEGED_INSTALL);
} }
public void setPostSystemInstall(boolean postInstall) { public void setPostPrivilegedInstall(boolean postInstall) {
preferences.edit().putBoolean(PREF_POST_SYSTEM_INSTALL, postInstall).commit(); preferences.edit().putBoolean(PREF_POST_PRIVILEGED_INSTALL, postInstall).commit();
} }
public boolean shouldCacheApks() { public boolean shouldCacheApks() {

View File

@ -19,7 +19,6 @@
package org.fdroid.fdroid.installer; package org.fdroid.fdroid.installer;
import android.Manifest.permission;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -107,7 +106,7 @@ abstract public class Installer {
InstallerCallback callback) { InstallerCallback callback) {
// system permissions and pref enabled -> SystemInstaller // system permissions and pref enabled -> SystemInstaller
boolean isSystemInstallerEnabled = Preferences.get().isSystemInstallerEnabled(); boolean isSystemInstallerEnabled = Preferences.get().isPrivilegedInstallerEnabled();
if (isSystemInstallerEnabled) { if (isSystemInstallerEnabled) {
if (PrivilegedInstaller.isAvailable(activity)) { if (PrivilegedInstaller.isAvailable(activity)) {
Utils.DebugLog(TAG, "system permissions -> SystemInstaller"); Utils.DebugLog(TAG, "system permissions -> SystemInstaller");

View File

@ -38,22 +38,20 @@ import eu.chainfire.libsuperuser.Shell;
abstract class InstallPrivileged { abstract class InstallPrivileged {
protected final Context context; protected final Context context;
protected final String apkPath;
private static final String PACKAGE_NAME = "org.fdroid.fdroid.privileged"; 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.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) { 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) { } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return new KitKatToLollipopImpl(context, apkPath); return new KitKatToLollipopImpl(context);
} else { } else {
return new PreKitKatImpl(context, apkPath); return new PreKitKatImpl(context);
} }
} }
@ -80,19 +78,19 @@ abstract class InstallPrivileged {
Shell.SU.run(commands); Shell.SU.run(commands);
} }
final void runInstall() { final void runInstall(String apkPath) {
onPreInstall(); onPreInstall();
Shell.SU.run(getInstallCommands()); Shell.SU.run(getInstallCommands(apkPath));
} }
protected String getInstallPath() { protected String getInstallPath() {
return getSystemFolder() + "FDroidPrivileged.apk"; return getSystemFolder() + "FDroidPrivileged.apk";
} }
private List<String> getInstallCommands() { private List<String> getInstallCommands(String apkPath) {
final List<String> commands = new ArrayList<>(); final List<String> commands = new ArrayList<>();
commands.add("mount -o rw,remount /system"); commands.add("mount -o rw,remount /system");
commands.addAll(getCopyToSystemCommands()); commands.addAll(getCopyToSystemCommands(apkPath));
commands.add("pm uninstall " + PACKAGE_NAME); commands.add("pm uninstall " + PACKAGE_NAME);
commands.add("mv " + getInstallPath() + ".tmp " + getInstallPath()); commands.add("mv " + getInstallPath() + ".tmp " + getInstallPath());
commands.add("pm install -r " + getInstallPath()); commands.add("pm install -r " + getInstallPath());
@ -103,7 +101,7 @@ abstract class InstallPrivileged {
return commands; return commands;
} }
protected List<String> getCopyToSystemCommands() { protected List<String> getCopyToSystemCommands(String apkPath) {
final List<String> commands = new ArrayList<>(2); final List<String> commands = new ArrayList<>(2);
commands.add("cat " + apkPath + " > " + getInstallPath() + ".tmp"); commands.add("cat " + apkPath + " > " + getInstallPath() + ".tmp");
commands.add("chmod 644 " + getInstallPath() + ".tmp"); commands.add("chmod 644 " + getInstallPath() + ".tmp");
@ -118,8 +116,8 @@ abstract class InstallPrivileged {
private static class PreKitKatImpl extends InstallPrivileged { private static class PreKitKatImpl extends InstallPrivileged {
public PreKitKatImpl(Context context, String apkPath) { public PreKitKatImpl(Context context) {
super(context, apkPath); super(context);
} }
@Override @Override
@ -131,8 +129,8 @@ abstract class InstallPrivileged {
private static class KitKatToLollipopImpl extends InstallPrivileged { private static class KitKatToLollipopImpl extends InstallPrivileged {
public KitKatToLollipopImpl(Context context, String apkPath) { public KitKatToLollipopImpl(Context context) {
super(context, apkPath); super(context);
} }
/** /**
@ -152,14 +150,14 @@ abstract class InstallPrivileged {
*/ */
private static class LollipopImpl extends InstallPrivileged { private static class LollipopImpl extends InstallPrivileged {
public LollipopImpl(Context context, String apkPath) { public LollipopImpl(Context context) {
super(context, apkPath); super(context);
} }
@Override @Override
protected void onPreInstall() { protected void onPreInstall() {
// Setup preference to execute postInstall after reboot // Setup preference to execute postInstall after reboot
Preferences.get().setPostSystemInstall(true); Preferences.get().setPostPrivilegedInstall(true);
} }
public String getWarningInfo() { public String getWarningInfo() {
@ -178,7 +176,7 @@ abstract class InstallPrivileged {
* Create app directory * Create app directory
*/ */
@Override @Override
protected List<String> getCopyToSystemCommands() { protected List<String> getCopyToSystemCommands(String apkPath) {
List<String> commands = new ArrayList<>(3); List<String> commands = new ArrayList<>(3);
commands.add("mkdir -p " + getSystemFolder()); // create app directory if not existing commands.add("mkdir -p " + getSystemFolder()); // create app directory if not existing
commands.add("chmod 755 " + getSystemFolder()); commands.add("chmod 755 " + getSystemFolder());

View File

@ -30,8 +30,8 @@ public class InstallPrivilegedBootReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
if (Preferences.get().isPostSystemInstall()) { if (Preferences.get().isPostPrivilegedInstall()) {
Preferences.get().setPostSystemInstall(false); Preferences.get().setPostPrivilegedInstall(false);
Intent postInstall = new Intent(context.getApplicationContext(), InstallPrivilegedDialogActivity.class); Intent postInstall = new Intent(context.getApplicationContext(), InstallPrivilegedDialogActivity.class);
postInstall.setAction(InstallPrivilegedDialogActivity.ACTION_POST_INSTALL); postInstall.setAction(InstallPrivilegedDialogActivity.ACTION_POST_INSTALL);

View File

@ -40,7 +40,6 @@ import org.fdroid.fdroid.FDroid;
import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R; import org.fdroid.fdroid.R;
import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.installer.PrivilegedInstaller; import org.fdroid.fdroid.installer.PrivilegedInstaller;
import eu.chainfire.libsuperuser.Shell; import eu.chainfire.libsuperuser.Shell;
@ -88,7 +87,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
Preferences.get().setFirstTime(false); Preferences.get().setFirstTime(false);
if (PrivilegedInstaller.isAvailable(context)) { if (PrivilegedInstaller.isAvailable(context)) {
Preferences.get().setSystemInstallerEnabled(true); Preferences.get().setPrivilegedInstallerEnabled(true);
} else { } else {
runFirstTime(context); runFirstTime(context);
} }
@ -160,7 +159,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
ContextThemeWrapper theme = new ContextThemeWrapper(this, FDroidApp.getCurThemeResId()); ContextThemeWrapper theme = new ContextThemeWrapper(this, FDroidApp.getCurThemeResId());
String message = getString(R.string.system_install_first_time_message) + "<br/><br/>" 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) AlertDialog.Builder builder = new AlertDialog.Builder(theme)
.setMessage(Html.fromHtml(message)) .setMessage(Html.fromHtml(message))
@ -269,7 +268,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
@Override @Override
protected Void doInBackground(Void... voids) { protected Void doInBackground(Void... voids) {
InstallPrivileged.create(getApplicationContext()).runInstall(); InstallPrivileged.create(getApplicationContext()).runInstall("test"); // TODO
return null; return null;
} }
}; };
@ -284,7 +283,7 @@ public class InstallPrivilegedDialogActivity extends FragmentActivity {
final boolean success = PrivilegedInstaller.isAvailable(this); final boolean success = PrivilegedInstaller.isAvailable(this);
// enable system installer on installation success // enable system installer on installation success
Preferences.get().setSystemInstallerEnabled(success); Preferences.get().setPrivilegedInstallerEnabled(success);
AlertDialog.Builder builder = new AlertDialog.Builder(theme) AlertDialog.Builder builder = new AlertDialog.Builder(theme)
.setTitle(success ? R.string.system_install_post_success : R.string.system_install_post_fail) .setTitle(success ? R.string.system_install_post_success : R.string.system_install_post_fail)

View File

@ -21,7 +21,6 @@ import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.installer.PrivilegedInstaller; import org.fdroid.fdroid.installer.PrivilegedInstaller;
import org.fdroid.fdroid.privileged.install.InstallPrivilegedDialogActivity; import org.fdroid.fdroid.privileged.install.InstallPrivilegedDialogActivity;
import org.fdroid.fdroid.installer.Installer;
import java.util.Locale; import java.util.Locale;
@ -42,7 +41,7 @@ public class PreferencesFragment extends PreferenceFragment
Preferences.PREF_LANGUAGE, Preferences.PREF_LANGUAGE,
Preferences.PREF_CACHE_APK, Preferences.PREF_CACHE_APK,
Preferences.PREF_EXPERT, Preferences.PREF_EXPERT,
Preferences.PREF_SYSTEM_INSTALLER, Preferences.PREF_PRIVILEGED_INSTALLER,
Preferences.PREF_ENABLE_PROXY, Preferences.PREF_ENABLE_PROXY,
Preferences.PREF_PROXY_HOST, Preferences.PREF_PROXY_HOST,
Preferences.PREF_PROXY_PORT, Preferences.PREF_PROXY_PORT,
@ -150,7 +149,7 @@ public class PreferencesFragment extends PreferenceFragment
checkSummary(key, R.string.expert_on); checkSummary(key, R.string.expert_on);
break; break;
case Preferences.PREF_SYSTEM_INSTALLER: case Preferences.PREF_PRIVILEGED_INSTALLER:
checkSummary(key, R.string.system_installer_on); checkSummary(key, R.string.system_installer_on);
break; 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 * Initializes SystemInstaller preference, which can only be enabled when F-Droid is installed as a system-app
*/ */
protected void initSystemInstallerPreference() { protected void initPrivilegedInstallerPreference() {
CheckBoxPreference pref = (CheckBoxPreference) findPreference(Preferences.PREF_SYSTEM_INSTALLER); CheckBoxPreference pref = (CheckBoxPreference) findPreference(Preferences.PREF_PRIVILEGED_INSTALLER);
// we are handling persistence ourself! // we are handling persistence ourself!
pref.setPersistent(false); pref.setPersistent(false);
@ -199,13 +198,13 @@ public class PreferencesFragment extends PreferenceFragment
if (PrivilegedInstaller.isAvailable(getActivity())) { if (PrivilegedInstaller.isAvailable(getActivity())) {
// system-permission are granted, i.e. F-Droid is a system-app // system-permission are granted, i.e. F-Droid is a system-app
SharedPreferences.Editor editor = pref.getSharedPreferences().edit(); SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, true); editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, true);
editor.commit(); editor.commit();
pref.setChecked(true); pref.setChecked(true);
} else { } else {
// system-permission not available // system-permission not available
SharedPreferences.Editor editor = pref.getSharedPreferences().edit(); SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false); editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, false);
editor.commit(); editor.commit();
pref.setChecked(false); pref.setChecked(false);
@ -232,7 +231,7 @@ public class PreferencesFragment extends PreferenceFragment
} }
} else { } else {
SharedPreferences.Editor editor = pref.getSharedPreferences().edit(); SharedPreferences.Editor editor = pref.getSharedPreferences().edit();
editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false); editor.putBoolean(Preferences.PREF_PRIVILEGED_INSTALLER, false);
editor.commit(); editor.commit();
pref.setChecked(false); pref.setChecked(false);
} }
@ -242,8 +241,8 @@ public class PreferencesFragment extends PreferenceFragment
}); });
} }
protected void initUninstallSystemAppPreference() { protected void initUninstallPrivilegedAppPreference() {
Preference pref = findPreference(Preferences.PREF_UNINSTALL_SYSTEM_APP); Preference pref = findPreference(Preferences.PREF_UNINSTALL_PRIVILEGED_APP);
pref.setPersistent(false); pref.setPersistent(false);
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@ -281,8 +280,8 @@ public class PreferencesFragment extends PreferenceFragment
updateSummary(key, false); updateSummary(key, false);
} }
initSystemInstallerPreference(); initPrivilegedInstallerPreference();
initUninstallSystemAppPreference(); initUninstallPrivilegedAppPreference();
} }
@Override @Override