diff --git a/res/values/strings.xml b/res/values/strings.xml index e2d07dfc8..de6073c47 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -28,12 +28,12 @@ Do not notify of any updates Update history Days to consider apps new or recent: %s - Root access for app installations - Root access is used to install/delete/update applications - Do not request root access to install/delete/update applications - Use system permissions for app installations - F-Droid tries to use system permissions to install/delete/update applications (only possible when installed as system-app) - F-Droid does not try to use system permissions to install/delete/update applications (only possible when installed as system-app) + Install using root access + Request root access to install, update, and remove packages + Do not request root access to install, update, and remove packages + Install using system-permissions + Use system permissions to install, update, and remove packages + Do not use system permissions to install, update, and remove packages Search Results App Details @@ -275,5 +275,7 @@ Update all (De-)Installation Error The (de-)installation failed. If you are using root access, try disabling this setting! + System permissions denied + This option is only available when F-Droid is installed as a system-app. diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index b9571a814..fa534900f 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -54,7 +54,7 @@ android:defaultValue="false" android:key="rootInstaller" /> diff --git a/src/org/fdroid/fdroid/Preferences.java b/src/org/fdroid/fdroid/Preferences.java index 29c2c0d39..44d1c113c 100644 --- a/src/org/fdroid/fdroid/Preferences.java +++ b/src/org/fdroid/fdroid/Preferences.java @@ -43,7 +43,7 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi private static final boolean DEFAULT_ROOTED = true; private static final int DEFAULT_UPD_HISTORY = 14; private static final boolean DEFAULT_ROOT_INSTALLER = false; - private static final boolean DEFAULT_SYSTEM_INSTALLER = true; + private static final boolean DEFAULT_SYSTEM_INSTALLER = false; private boolean compactLayout = DEFAULT_COMPACT_LAYOUT; private boolean filterAppsRequiringRoot = DEFAULT_ROOTED; diff --git a/src/org/fdroid/fdroid/PreferencesActivity.java b/src/org/fdroid/fdroid/PreferencesActivity.java index a8013e4ca..55c36ec3e 100644 --- a/src/org/fdroid/fdroid/PreferencesActivity.java +++ b/src/org/fdroid/fdroid/PreferencesActivity.java @@ -35,6 +35,7 @@ import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.compat.ActionBarCompat; import org.fdroid.fdroid.installer.CheckRootAsyncTask; import org.fdroid.fdroid.installer.CheckRootAsyncTask.CheckRootCallback; +import org.fdroid.fdroid.installer.Installer; public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { @@ -217,13 +218,59 @@ public class PreferencesActivity extends PreferenceActivity implements return true; } }); + } + + /** + * 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); + // we are handling persistence ourself! + pref.setPersistent(false); + + pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + + @Override + public boolean onPreferenceClick(Preference preference) { + final CheckBoxPreference pref = (CheckBoxPreference) preference; + + if (pref.isChecked()) { + if (Installer.hasSystemPermissions(PreferencesActivity.this, PreferencesActivity.this.getPackageManager())) { + // 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.commit(); + pref.setChecked(true); + } else { + // system-permission not available + SharedPreferences.Editor editor = pref.getSharedPreferences().edit(); + editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false); + editor.commit(); + pref.setChecked(false); + + AlertDialog.Builder alertBuilder = new AlertDialog.Builder(PreferencesActivity.this); + alertBuilder.setTitle(R.string.system_permission_denied_title); + alertBuilder.setMessage(PreferencesActivity.this.getString(R.string.system_permission_denied_body)); + alertBuilder.setNeutralButton(android.R.string.ok, null); + alertBuilder.create().show(); + } + } else { + SharedPreferences.Editor editor = pref.getSharedPreferences().edit(); + editor.putBoolean(Preferences.PREF_SYSTEM_INSTALLER, false); + editor.commit(); + pref.setChecked(false); + } + + return true; + } + }); } @Override protected void onResume() { - super.onResume(); + getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); @@ -232,11 +279,13 @@ public class PreferencesActivity extends PreferenceActivity implements } initRootInstallerPreference(); + initSystemInstallerPreference(); } @Override protected void onPause() { super.onPause(); + getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } diff --git a/src/org/fdroid/fdroid/installer/DefaultInstallerSdk14.java b/src/org/fdroid/fdroid/installer/DefaultInstallerSdk14.java index 4a33716ed..b45241b80 100644 --- a/src/org/fdroid/fdroid/installer/DefaultInstallerSdk14.java +++ b/src/org/fdroid/fdroid/installer/DefaultInstallerSdk14.java @@ -121,6 +121,8 @@ public class DefaultInstallerSdk14 extends Installer { mCallback.onError(InstallerCallback.OPERATION_DELETE, InstallerCallback.ERROR_CODE_CANCELED); } else { + // UninstallAppProgress actually returns + // Activity.RESULT_FIRST_USER if something breaks mCallback.onError(InstallerCallback.OPERATION_DELETE, InstallerCallback.ERROR_CODE_OTHER); } diff --git a/src/org/fdroid/fdroid/installer/Installer.java b/src/org/fdroid/fdroid/installer/Installer.java index e2ca27f96..dfcae1b82 100644 --- a/src/org/fdroid/fdroid/installer/Installer.java +++ b/src/org/fdroid/fdroid/installer/Installer.java @@ -118,16 +118,20 @@ abstract public class Installer { } } - // system permissions and pref enabled -> SystemPermissionInstaller + // system permissions and pref enabled -> SystemInstaller boolean isSystemInstallerEnabled = Preferences.get().isSystemInstallerEnabled(); - if (isSystemInstallerEnabled && hasSystemPermissions(activity, pm)) { - Log.d(TAG, "system permissions -> SystemPermissionInstaller"); + if (isSystemInstallerEnabled) { + if (hasSystemPermissions(activity, pm)) { + Log.d(TAG, "system permissions -> SystemInstaller"); - try { - return new SystemPermissionInstaller(activity, pm, callback); - } catch (AndroidNotCompatibleException e) { - Log.e(TAG, "Android not compatible with SystemPermissionInstaller!", e); + try { + return new SystemInstaller(activity, pm, callback); + } catch (AndroidNotCompatibleException e) { + Log.e(TAG, "Android not compatible with SystemInstaller!", e); + } } + } else { + Log.e(TAG, "SystemInstaller is enabled in prefs, but system-perms are not granted!"); } // Fallback -> DefaultInstaller @@ -170,14 +174,14 @@ abstract public class Installer { if (hasSystemPermissions(context, pm)) { // we have system permissions! - return new SystemPermissionInstaller(context, pm, callback); + return new SystemInstaller(context, pm, callback); } else { // nope! throw new AndroidNotCompatibleException(); } } - private static boolean hasSystemPermissions(Context context, PackageManager pm) { + public static boolean hasSystemPermissions(Context context, PackageManager pm) { int checkInstallPermission = pm.checkPermission(permission.INSTALL_PACKAGES, context.getPackageName()); int checkDeletePermission = diff --git a/src/org/fdroid/fdroid/installer/SystemPermissionInstaller.java b/src/org/fdroid/fdroid/installer/SystemInstaller.java similarity index 99% rename from src/org/fdroid/fdroid/installer/SystemPermissionInstaller.java rename to src/org/fdroid/fdroid/installer/SystemInstaller.java index f97cd6858..c3af08249 100644 --- a/src/org/fdroid/fdroid/installer/SystemPermissionInstaller.java +++ b/src/org/fdroid/fdroid/installer/SystemInstaller.java @@ -56,14 +56,14 @@ import android.util.Log; * https://android.googlesource.com/platform * /frameworks/base/+/ccbf84f44c9e6a5ed3c08673614826bb237afc54 */ -public class SystemPermissionInstaller extends Installer { +public class SystemInstaller extends Installer { private PackageInstallObserver mInstallObserver; private PackageDeleteObserver mDeleteObserver; private Method mInstallMethod; private Method mDeleteMethod; - public SystemPermissionInstaller(Context context, PackageManager pm, + public SystemInstaller(Context context, PackageManager pm, InstallerCallback callback) throws AndroidNotCompatibleException { super(context, pm, callback);