The package name of the app which has already defined the permission is passed to
* a {@link PackageInstallObserver}, if any, as the {@link #EXTRA_EXISTING_PACKAGE}
* string extra; and the name of the permission being redefined is passed in the
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystem.java b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
similarity index 77%
rename from F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystem.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
index e7fd19643..181244071 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystem.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/install/InstallPrivileged.java
@@ -17,13 +17,14 @@
* MA 02110-1301, USA.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.install;
import android.content.Context;
import android.os.Build;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.installer.PrivilegedInstaller;
import java.util.ArrayList;
import java.util.List;
@@ -35,15 +36,17 @@ import eu.chainfire.libsuperuser.Shell;
* http://omerjerk.in/2014/08/how-to-install-an-app-to-system-partition/
* https://github.com/omerjerk/RemoteDroid/blob/master/app/src/main/java/in/omerjerk/remotedroid/app/MainActivity.java
*/
-abstract class InstallIntoSystem {
+abstract class InstallPrivileged {
protected final Context context;
- public InstallIntoSystem(final Context context) {
+ private static final String APK_FILE_NAME = "FDroidPrivileged.apk";
+
+ public InstallPrivileged(final Context context) {
this.context = context;
}
- public static InstallIntoSystem create(final Context context) {
+ public static InstallPrivileged create(final Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return new LollipopImpl(context);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -65,10 +68,10 @@ abstract class InstallIntoSystem {
final void runUninstall() {
final String[] commands = {
- "am force-stop org.fdroid.fdroid",
- "pm clear org.fdroid.fdroid",
+ "am force-stop " + PrivilegedInstaller.PRIVILEGED_PACKAGE_NAME,
+ "pm clear " + PrivilegedInstaller.PRIVILEGED_PACKAGE_NAME,
"mount -o rw,remount /system",
- "pm uninstall " + context.getPackageName(),
+ "pm uninstall " + PrivilegedInstaller.PRIVILEGED_PACKAGE_NAME,
"rm -f " + getInstallPath(),
"sleep 5",
"mount -o ro,remount /system"
@@ -76,32 +79,32 @@ abstract class InstallIntoSystem {
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() + "FDroid.apk";
+ return getSystemFolder() + APK_FILE_NAME;
}
- private List
" + InstallIntoSystem.create(getApplicationContext()).getWarningInfo();
+ String message = getString(R.string.system_install_first_time_message) + "
"
+ + InstallPrivileged.create(getApplicationContext()).getWarningInfo();
AlertDialog.Builder builder = new AlertDialog.Builder(theme)
.setMessage(Html.fromHtml(message))
.setPositiveButton(R.string.system_permission_install_via_root, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
- installTask.execute();
+ // Open details of F-Droid Privileged
+ Intent intent = new Intent(InstallPrivilegedDialogActivity.this, AppDetails.class);
+ intent.putExtra(AppDetails.EXTRA_APPID,
+ PrivilegedInstaller.PRIVILEGED_PACKAGE_NAME);
+ startActivity(intent);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
- InstallIntoSystemDialogActivity.this.setResult(Activity.RESULT_CANCELED);
- InstallIntoSystemDialogActivity.this.finish();
+ InstallPrivilegedDialogActivity.this.setResult(Activity.RESULT_CANCELED);
+ InstallPrivilegedDialogActivity.this.finish();
}
});
builder.create().show();
@@ -188,7 +202,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
super.onPreExecute();
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
- ContextThemeWrapper theme = new ContextThemeWrapper(InstallIntoSystemDialogActivity.this,
+ ContextThemeWrapper theme = new ContextThemeWrapper(InstallPrivilegedDialogActivity.this,
FDroidApp.getCurThemeResId());
mProgressDialog = new ProgressDialog(theme);
@@ -224,7 +238,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
if (!ACTION_FIRST_TIME.equals(action)) {
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
- ContextThemeWrapper theme = new ContextThemeWrapper(InstallIntoSystemDialogActivity.this,
+ ContextThemeWrapper theme = new ContextThemeWrapper(InstallPrivilegedDialogActivity.this,
FDroidApp.getCurThemeResId());
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(theme)
@@ -233,8 +247,8 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- InstallIntoSystemDialogActivity.this.setResult(Activity.RESULT_CANCELED);
- InstallIntoSystemDialogActivity.this.finish();
+ InstallPrivilegedDialogActivity.this.setResult(Activity.RESULT_CANCELED);
+ InstallPrivilegedDialogActivity.this.finish();
}
});
alertBuilder.create().show();
@@ -254,7 +268,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
super.onPreExecute();
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
- ContextThemeWrapper theme = new ContextThemeWrapper(InstallIntoSystemDialogActivity.this,
+ ContextThemeWrapper theme = new ContextThemeWrapper(InstallPrivilegedDialogActivity.this,
FDroidApp.getCurThemeResId());
mProgressDialog = new ProgressDialog(theme);
@@ -266,7 +280,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
@Override
protected Void doInBackground(Void... voids) {
- InstallIntoSystem.create(getApplicationContext()).runInstall();
+ InstallPrivileged.create(getApplicationContext()).runInstall(apkFile);
return null;
}
};
@@ -278,10 +292,10 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(this, FDroidApp.getCurThemeResId());
- final boolean success = Installer.hasSystemPermissions(this, this.getPackageManager());
+ 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)
@@ -289,9 +303,9 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
- InstallIntoSystemDialogActivity.this.setResult(success ? Activity.RESULT_OK : Activity.RESULT_CANCELED);
- InstallIntoSystemDialogActivity.this.finish();
- startActivity(new Intent(InstallIntoSystemDialogActivity.this, FDroid.class));
+ InstallPrivilegedDialogActivity.this.setResult(success ? Activity.RESULT_OK : Activity.RESULT_CANCELED);
+ InstallPrivilegedDialogActivity.this.finish();
+ startActivity(new Intent(InstallPrivilegedDialogActivity.this, FDroid.class));
}
})
.setCancelable(false);
@@ -302,9 +316,9 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
ContextThemeWrapper theme = new ContextThemeWrapper(this, FDroidApp.getCurThemeResId());
- final boolean systemApp = Installer.hasSystemPermissions(this, this.getPackageManager());
+ final boolean isAvailable = PrivilegedInstaller.isAvailable(this);
- if (systemApp) {
+ if (isAvailable) {
AlertDialog.Builder builder = new AlertDialog.Builder(theme)
.setTitle(R.string.system_uninstall)
.setMessage(R.string.system_uninstall_message)
@@ -317,8 +331,8 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- InstallIntoSystemDialogActivity.this.setResult(Activity.RESULT_CANCELED);
- InstallIntoSystemDialogActivity.this.finish();
+ InstallPrivilegedDialogActivity.this.setResult(Activity.RESULT_CANCELED);
+ InstallPrivilegedDialogActivity.this.finish();
}
});
builder.create().show();
@@ -329,8 +343,8 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- InstallIntoSystemDialogActivity.this.setResult(Activity.RESULT_CANCELED);
- InstallIntoSystemDialogActivity.this.finish();
+ InstallPrivilegedDialogActivity.this.setResult(Activity.RESULT_CANCELED);
+ InstallPrivilegedDialogActivity.this.finish();
}
});
builder.create().show();
@@ -345,7 +359,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
super.onPreExecute();
// hack to get holo design (which is not automatically applied due to activity's Theme.NoDisplay
- ContextThemeWrapper theme = new ContextThemeWrapper(InstallIntoSystemDialogActivity.this,
+ ContextThemeWrapper theme = new ContextThemeWrapper(InstallPrivilegedDialogActivity.this,
FDroidApp.getCurThemeResId());
mProgressDialog = new ProgressDialog(theme);
@@ -357,7 +371,7 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity {
@Override
protected Void doInBackground(Void... voids) {
- InstallIntoSystem.create(getApplicationContext()).runUninstall();
+ InstallPrivileged.create(getApplicationContext()).runUninstall();
return null;
}
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java b/F-Droid/src/org/fdroid/fdroid/privileged/views/AppDiff.java
similarity index 94%
rename from F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/views/AppDiff.java
index 2391cb096..95b94cc28 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/views/AppDiff.java
@@ -16,7 +16,7 @@
** limitations under the License.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.views;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@@ -25,10 +25,10 @@ import android.net.Uri;
public class AppDiff {
- final PackageManager mPm;
- final PackageInfo mPkgInfo;
+ public final PackageManager mPm;
+ public final PackageInfo mPkgInfo;
- ApplicationInfo mInstalledAppInfo = null;
+ public ApplicationInfo mInstalledAppInfo = null;
public AppDiff(PackageManager mPm, Uri mPackageURI) {
this.mPm = mPm;
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/AppSecurityPermissions.java b/F-Droid/src/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java
similarity index 99%
rename from F-Droid/src/org/fdroid/fdroid/installer/AppSecurityPermissions.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java
index e65ef76cf..c6754b71c 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/AppSecurityPermissions.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/views/AppSecurityPermissions.java
@@ -15,7 +15,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.views;
import android.annotation.TargetApi;
import android.content.Context;
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/CaffeinatedScrollView.java b/F-Droid/src/org/fdroid/fdroid/privileged/views/CaffeinatedScrollView.java
similarity index 98%
rename from F-Droid/src/org/fdroid/fdroid/installer/CaffeinatedScrollView.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/views/CaffeinatedScrollView.java
index 37b96b419..f43dbc053 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/CaffeinatedScrollView.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/views/CaffeinatedScrollView.java
@@ -15,7 +15,7 @@
** limitations under the License.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.views;
import android.content.Context;
import android.graphics.Canvas;
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java b/F-Droid/src/org/fdroid/fdroid/privileged/views/InstallConfirmActivity.java
similarity index 99%
rename from F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/views/InstallConfirmActivity.java
index aeaf16e8b..dae78e90f 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/views/InstallConfirmActivity.java
@@ -16,7 +16,7 @@
** limitations under the License.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.views;
import android.app.Activity;
import android.content.Context;
diff --git a/F-Droid/src/org/fdroid/fdroid/installer/TabsAdapter.java b/F-Droid/src/org/fdroid/fdroid/privileged/views/TabsAdapter.java
similarity index 99%
rename from F-Droid/src/org/fdroid/fdroid/installer/TabsAdapter.java
rename to F-Droid/src/org/fdroid/fdroid/privileged/views/TabsAdapter.java
index eef50eb1b..02372fd84 100644
--- a/F-Droid/src/org/fdroid/fdroid/installer/TabsAdapter.java
+++ b/F-Droid/src/org/fdroid/fdroid/privileged/views/TabsAdapter.java
@@ -14,7 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-package org.fdroid.fdroid.installer;
+package org.fdroid.fdroid.privileged.views;
import android.app.Activity;
import android.content.Context;
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 4b111c0d4..00226f399 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
@@ -14,13 +14,14 @@ import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.TextUtils;
+import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.PreferencesActivity;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
-import org.fdroid.fdroid.installer.InstallIntoSystemDialogActivity;
-import org.fdroid.fdroid.installer.Installer;
+import org.fdroid.fdroid.installer.PrivilegedInstaller;
+import org.fdroid.fdroid.privileged.install.InstallPrivilegedDialogActivity;
import java.util.Locale;
@@ -41,7 +42,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,
@@ -149,7 +150,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;
@@ -182,8 +183,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);
@@ -195,16 +196,16 @@ public class PreferencesFragment extends PreferenceFragment
final CheckBoxPreference pref = (CheckBoxPreference) preference;
if (pref.isChecked()) {
- if (Installer.hasSystemPermissions(getActivity(), getActivity().getPackageManager())) {
+ 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);
@@ -221,9 +222,11 @@ public class PreferencesFragment extends PreferenceFragment
alertBuilder.setPositiveButton(R.string.system_permission_install_via_root, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- Intent installIntent = new Intent(getActivity(), InstallIntoSystemDialogActivity.class);
- installIntent.setAction(InstallIntoSystemDialogActivity.ACTION_INSTALL);
- startActivity(installIntent);
+ // Open details of F-Droid Privileged
+ Intent intent = new Intent(getActivity(), AppDetails.class);
+ intent.putExtra(AppDetails.EXTRA_APPID,
+ PrivilegedInstaller.PRIVILEGED_PACKAGE_NAME);
+ startActivity(intent);
}
});
alertBuilder.setNegativeButton(R.string.cancel, null);
@@ -231,7 +234,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);
}
@@ -241,16 +244,16 @@ 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() {
@Override
public boolean onPreferenceClick(Preference preference) {
- Intent uninstallIntent = new Intent(getActivity(), InstallIntoSystemDialogActivity.class);
- uninstallIntent.setAction(InstallIntoSystemDialogActivity.ACTION_UNINSTALL);
+ Intent uninstallIntent = new Intent(getActivity(), InstallPrivilegedDialogActivity.class);
+ uninstallIntent.setAction(InstallPrivilegedDialogActivity.ACTION_UNINSTALL);
startActivity(uninstallIntent);
return true;
@@ -280,8 +283,8 @@ public class PreferencesFragment extends PreferenceFragment
updateSummary(key, false);
}
- initSystemInstallerPreference();
- initUninstallSystemAppPreference();
+ initPrivilegedInstallerPreference();
+ initUninstallPrivilegedAppPreference();
}
@Override
diff --git a/media/fdroid-logo-2015/fdroid-logo-privileged.svg b/media/fdroid-logo-2015/fdroid-logo-privileged.svg
new file mode 100644
index 000000000..d8cf2fc8f
--- /dev/null
+++ b/media/fdroid-logo-2015/fdroid-logo-privileged.svg
@@ -0,0 +1,359 @@
+
+
+
+
diff --git a/media/fdroid-logo-2015/puzzle.svg b/media/fdroid-logo-2015/puzzle.svg
new file mode 100644
index 000000000..1ed0d45f4
--- /dev/null
+++ b/media/fdroid-logo-2015/puzzle.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/privileged-api-lib/build.gradle b/privileged-api-lib/build.gradle
new file mode 100644
index 000000000..392379301
--- /dev/null
+++ b/privileged-api-lib/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion '23.0.0'
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ }
+
+ // Do not abort build if lint finds errors
+ lintOptions {
+ abortOnError false
+ }
+}
\ No newline at end of file
diff --git a/privileged-api-lib/src/main/AndroidManifest.xml b/privileged-api-lib/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..d1978ceea
--- /dev/null
+++ b/privileged-api-lib/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+