diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml index 5155416c5..6c8c27318 100644 --- a/F-Droid/res/values/strings.xml +++ b/F-Droid/res/values/strings.xml @@ -296,6 +296,8 @@ System permissions denied This option is only available when F-Droid is installed as a system-app. Install as system-app + Install F-Droid as a system-app? + Looks like you have root access on your device. You could install F-Droid as a system-app to enable extended features, such as automatic app updates.\nYou can also do this later from F-Droid\'s preferences. Successful installation as system-app Installation as system-app failed F-Droid has been successfully installed into the system partition. This enables extended features, such as automatic app updates. @@ -358,7 +360,6 @@ Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access. - New All Privacy diff --git a/F-Droid/src/org/fdroid/fdroid/FDroid.java b/F-Droid/src/org/fdroid/fdroid/FDroid.java index bf4f0ffb7..e811e00ef 100644 --- a/F-Droid/src/org/fdroid/fdroid/FDroid.java +++ b/F-Droid/src/org/fdroid/fdroid/FDroid.java @@ -104,16 +104,7 @@ public class FDroid extends ActionBarActivity { Uri uri = AppProvider.getContentUri(); getContentResolver().registerContentObserver(uri, true, new AppObserver()); - if (Preferences.get().isFirstTime()) { - if (Installer.hasSystemPermissions(this, this.getPackageManager())) { - Preferences.get().setSystemInstallerEnabled(true); - Preferences.get().setFirstTime(false); - } else { - Intent installIntent = new Intent(this, InstallIntoSystemDialogActivity.class); - installIntent.setAction(InstallIntoSystemDialogActivity.ACTION_FIRST_TIME); - startActivity(installIntent); - } - } + InstallIntoSystemDialogActivity.firstTime(this); } @Override diff --git a/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java b/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java index c38a7409a..e9d9ede17 100644 --- a/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java +++ b/F-Droid/src/org/fdroid/fdroid/installer/AppDiff.java @@ -28,7 +28,7 @@ public class AppDiff { PackageManager mPm; PackageInfo mPkgInfo; - ApplicationInfo mAppInfo = null; + ApplicationInfo mInstalledAppInfo = null; public AppDiff(PackageManager mPm, Uri mPackageURI) { this.mPm = mPm; @@ -52,18 +52,18 @@ public class AppDiff { mPkgInfo.packageName = pkgName; mPkgInfo.applicationInfo.packageName = pkgName; } - // Check if package is already installed. display confirmation dialog if replacing pkg + // Check if package is already installed try { // This is a little convoluted because we want to get all uninstalled // apps, but this may include apps with just data, and if it is just // data we still want to count it as "installed". - mAppInfo = mPm.getApplicationInfo(pkgName, + mInstalledAppInfo = mPm.getApplicationInfo(pkgName, PackageManager.GET_UNINSTALLED_PACKAGES); - if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { - mAppInfo = null; + if ((mInstalledAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { + mInstalledAppInfo = null; } } catch (PackageManager.NameNotFoundException e) { - mAppInfo = null; + mInstalledAppInfo = null; } } } diff --git a/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java b/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java index e38d1d1ae..298913284 100644 --- a/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/installer/InstallConfirmActivity.java @@ -87,8 +87,8 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener AppSecurityPermissions perms = new AppSecurityPermissions(this, mAppDiff.mPkgInfo); final int NP = perms.getPermissionCount(AppSecurityPermissions.WHICH_PERSONAL); final int ND = perms.getPermissionCount(AppSecurityPermissions.WHICH_DEVICE); - if (mAppDiff.mAppInfo != null) { - msg = (mAppDiff.mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 + if (mAppDiff.mInstalledAppInfo != null) { + msg = (mAppDiff.mInstalledAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ? R.string.install_confirm_update_system : R.string.install_confirm_update; mScrollView = new CaffeinatedScrollView(this); @@ -133,10 +133,10 @@ public class InstallConfirmActivity extends Activity implements OnCancelListener } } if (!permVisible) { - if (mAppDiff.mAppInfo != null) { + if (mAppDiff.mInstalledAppInfo != null) { // This is an update to an application, but there are no // permissions at all. - msg = (mAppDiff.mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 + msg = (mAppDiff.mInstalledAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ? R.string.install_confirm_update_system_no_perms : R.string.install_confirm_update_no_perms; } else { diff --git a/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystemDialogActivity.java b/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystemDialogActivity.java index 0634a24ba..e856f64f9 100644 --- a/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystemDialogActivity.java +++ b/F-Droid/src/org/fdroid/fdroid/installer/InstallIntoSystemDialogActivity.java @@ -21,12 +21,18 @@ package org.fdroid.fdroid.installer; import android.app.Activity; import android.app.AlertDialog; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.ProgressDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.FragmentActivity; +import android.support.v4.app.NotificationCompat; import android.text.Html; import android.util.Log; import android.view.ContextThemeWrapper; @@ -70,13 +76,84 @@ public class InstallIntoSystemDialogActivity extends FragmentActivity { } else if (ACTION_INSTALL.equals(action)) { checkRootTask.execute(); } else if (ACTION_FIRST_TIME.equals(action)) { - Preferences.get().setFirstTime(false); checkRootTask.execute(); } else if (ACTION_POST_INSTALL.equals(action)) { postInstall(); } } + public static void firstTime(final Context context) { + if (Preferences.get().isFirstTime()) { + Preferences.get().setFirstTime(false); + + if (Installer.hasSystemPermissions(context, context.getPackageManager())) { + Preferences.get().setSystemInstallerEnabled(true); + } else { + runFirstTime(context); + } + } + } + + public static void runFirstTime(final Context context) { + // don't do a "real" root access, just look up if "su" is present and has a version! + // a real check would annoy the user + AsyncTask checkRoot = new AsyncTask() { + + @Override + protected Boolean doInBackground(Void... params) { + return (Shell.SU.version(true) != null); + } + + @Override + protected void onPostExecute(Boolean probablyRoot) { + super.onPostExecute(probablyRoot); + + if (probablyRoot) { + // looks like we have root, at least su has a version number and is present + + // final int icon = Build.VERSION.SDK_INT >= 11 ? R.drawable.ic_stat_notify_updates : R.drawable.ic_launcher; + final int icon = R.drawable.ic_launcher; + + Intent installIntent = new Intent(context, InstallIntoSystemDialogActivity.class); + installIntent.setAction(InstallIntoSystemDialogActivity.ACTION_FIRST_TIME); + installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + PendingIntent resultPendingIntent = + PendingIntent.getActivity( + context, + 0, + installIntent, + PendingIntent.FLAG_UPDATE_CURRENT + ); + + String msg = context.getString(R.string.system_install_first_time_notification_message); + + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context) + .setContentIntent(resultPendingIntent) + .setSmallIcon(icon) + .setContentTitle(context.getString(R.string.system_install_first_time_notification)) + .setContentText(msg) + .setDefaults(Notification.DEFAULT_ALL) + .setAutoCancel(true) + /* + * Sets the big view "big text" style and supplies the + * text (the user's reminder message) that will be displayed + * in the detail area of the expanded notification. + * These calls are ignored by the support library for + * pre-4.1 devices. + */ + .setStyle(new NotificationCompat.BigTextStyle() + .bigText(msg)); + + NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(42, builder.build()); + } + } + }; + checkRoot.execute(); + } + /** * first time */ diff --git a/F-Droid/src/org/fdroid/fdroid/installer/SystemInstaller.java b/F-Droid/src/org/fdroid/fdroid/installer/SystemInstaller.java index 88d4db2df..8794409ec 100644 --- a/F-Droid/src/org/fdroid/fdroid/installer/SystemInstaller.java +++ b/F-Droid/src/org/fdroid/fdroid/installer/SystemInstaller.java @@ -157,7 +157,7 @@ public class SystemInstaller extends Installer { AppDiff appDiff = new AppDiff(mContext.getPackageManager(), packageUri); if (appDiff.mPkgInfo != null) { AppSecurityPermissions perms = new AppSecurityPermissions(mContext, appDiff.mPkgInfo); - if (appDiff.mAppInfo != null) { // it is an update to an existing app + if (appDiff.mInstalledAppInfo != null) { // it is an update to an existing app // return false if there are no new permissions return (perms.getPermissionCount(AppSecurityPermissions.WHICH_NEW) > 0); }