summaryrefslogtreecommitdiff
path: root/src/main/com
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2017-07-12 17:55:43 +0100
committerNeil Fuller <nfuller@google.com>2017-07-13 14:54:23 +0100
commit12c0bfbdbc6019d52f55d7f2428ec7b4207a0b1b (patch)
tree76d8ef3f33b1ce12ca2feb7aae8f7e283fe13c06 /src/main/com
parent53a61b123befa14bf1cdd465f10faa4f6fbc63c8 (diff)
downloadTimeZoneUpdater-12c0bfbdbc6019d52f55d7f2428ec7b4207a0b1b.tar.gz
Modify RulesCheckReceiver to stage an uninstall
RulesCheckReceiver now stages an uninstall if the device reverts to the /system version of the TimeZoneData app rather than attempting to stage an install of the /system version. This reduces the number of states a "clean" device could be in from 2 (no distro installed / system version distro installed) to 1 (no distro installed). It also means that in the event that a device ships with an old or incompatible distro file in the /system version of the .apk, an install won't even be tried (it would be reject by the TimeZoneDistroInstaller anyway, but more protection means libcore engineers can sleep more soundly). Bug: 31008728 Test: Ran pending PTS test (in internal branch) Change-Id: I1c8ecc99fb861473831352a55a400e389e98770c
Diffstat (limited to 'src/main/com')
-rw-r--r--src/main/com/android/timezone/updater/RulesCheckReceiver.java36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/main/com/android/timezone/updater/RulesCheckReceiver.java b/src/main/com/android/timezone/updater/RulesCheckReceiver.java
index 79abfd4..b2c30c6 100644
--- a/src/main/com/android/timezone/updater/RulesCheckReceiver.java
+++ b/src/main/com/android/timezone/updater/RulesCheckReceiver.java
@@ -24,6 +24,9 @@ import android.app.timezone.RulesUpdaterContract;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
@@ -88,6 +91,14 @@ public class RulesCheckReceiver extends BroadcastReceiver {
byte[] token = intent.getByteArrayExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN);
+ if (shouldUninstallCurrentInstall(context)) {
+ Log.i(TAG, "Device should be returned to having no time zone distro installed, issuing"
+ + " uninstall request");
+ // Uninstall is a no-op if nothing is installed.
+ handleUninstall(token);
+ return;
+ }
+
// Note: We rely on the system server to check that the configured data application is the
// one that exposes the content provider with the well-known authority, and is a privileged
// application as required. It is *not* checked here and it is assumed the updater can trust
@@ -124,6 +135,31 @@ public class RulesCheckReceiver extends BroadcastReceiver {
}
}
+ private boolean shouldUninstallCurrentInstall(Context context) {
+ int flags = PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+ PackageManager packageManager = context.getPackageManager();
+ ProviderInfo providerInfo =
+ packageManager.resolveContentProvider(TimeZoneRulesDataContract.AUTHORITY, flags);
+ if (providerInfo == null || providerInfo.applicationInfo == null) {
+ Log.w(TAG, "No package/application info available for content provider "
+ + TimeZoneRulesDataContract.AUTHORITY);
+ // Something has gone wrong. Trying to return the device to clean is a reasonable
+ // response.
+ return true;
+ }
+
+ // If the data app is the one from /system, we can treat this as "uninstall": if nothing
+ // is installed then the system will treat this as a no-op, and if something is installed
+ // this will stage an uninstall.
+ // We could install the distro from an app contained in the system image but we assume it's
+ // going to contain the same time zone data as in /system and would be a no op.
+
+ ApplicationInfo applicationInfo = providerInfo.applicationInfo;
+ // isPrivilegedApp() => initial install directory for app /system/priv-app (required)
+ // isUpdatedSystemApp() => app has been replaced by an updated version that resides in /data
+ return applicationInfo.isPrivilegedApp() && !applicationInfo.isUpdatedSystemApp();
+ }
+
private DistroOperation getOperation(Context context) {
Cursor c = context.getContentResolver()
.query(TimeZoneRulesDataContract.Operation.CONTENT_URI,