summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl4
-rw-r--r--core/java/com/android/server/backup/PreferredActivityBackupHelper.java71
-rw-r--r--services/core/java/com/android/server/pm/IntentFilterVerificationState.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java264
-rw-r--r--services/core/java/com/android/server/pm/Settings.java123
5 files changed, 387 insertions, 79 deletions
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 0c07bc3..2dbcde9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -282,6 +282,10 @@ interface IPackageManager {
*/
byte[] getPreferredActivityBackup(int userId);
void restorePreferredActivities(in byte[] backup, int userId);
+ byte[] getDefaultAppsBackup(int userId);
+ void restoreDefaultApps(in byte[] backup, int userId);
+ byte[] getIntentFilterVerificationBackup(int userId);
+ void restoreIntentFilterVerification(in byte[] backup, int userId);
/**
* Report the set of 'Home' activity candidates, plus (if any) which of them
diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
index 26f5bf4..458a2ca 100644
--- a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
+++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
@@ -27,48 +27,69 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper {
private static final boolean DEBUG = false;
// current schema of the backup state blob
- private static final int STATE_VERSION = 2;
+ private static final int STATE_VERSION = 3;
// key under which the preferred-activity state blob is committed to backup
private static final String KEY_PREFERRED = "preferred-activity";
+ // key for default-browser [etc] state
+ private static final String KEY_DEFAULT_APPS = "default-apps";
+
+ // intent-filter verification state
+ private static final String KEY_INTENT_VERIFICATION = "intent-verification";
+
public PreferredActivityBackupHelper() {
- super(STATE_VERSION, KEY_PREFERRED);
+ super(STATE_VERSION,
+ KEY_PREFERRED,
+ KEY_DEFAULT_APPS,
+ KEY_INTENT_VERIFICATION);
}
@Override
protected byte[] getBackupPayload(String key) {
- if (KEY_PREFERRED.equals(key)) {
- if (DEBUG) {
- Slog.v(TAG, "Checking whether to back up");
- }
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- return pm.getPreferredActivityBackup(UserHandle.USER_OWNER);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to store backup payload", e);
- // fall through to report null state
+ IPackageManager pm = AppGlobals.getPackageManager();
+ if (DEBUG) {
+ Slog.d(TAG, "Handling backup of " + key);
+ }
+ try {
+ switch (key) {
+ case KEY_PREFERRED:
+ return pm.getPreferredActivityBackup(UserHandle.USER_OWNER);
+ case KEY_DEFAULT_APPS:
+ return pm.getDefaultAppsBackup(UserHandle.USER_OWNER);
+ case KEY_INTENT_VERIFICATION:
+ return pm.getIntentFilterVerificationBackup(UserHandle.USER_OWNER);
+ default:
+ Slog.w(TAG, "Unexpected backup key " + key);
}
- } else {
- Slog.w(TAG, "Unexpected backup key " + key);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to store payload " + key);
}
return null;
}
@Override
protected void applyRestoredPayload(String key, byte[] payload) {
- if (KEY_PREFERRED.equals(key)) {
- if (DEBUG) {
- Slog.v(TAG, "Restoring");
- }
- IPackageManager pm = AppGlobals.getPackageManager();
- try {
- pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to restore", e);
+ IPackageManager pm = AppGlobals.getPackageManager();
+ if (DEBUG) {
+ Slog.d(TAG, "Handling restore of " + key);
+ }
+ try {
+ switch (key) {
+ case KEY_PREFERRED:
+ pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
+ break;
+ case KEY_DEFAULT_APPS:
+ pm.restoreDefaultApps(payload, UserHandle.USER_OWNER);
+ break;
+ case KEY_INTENT_VERIFICATION:
+ pm.restoreIntentFilterVerification(payload, UserHandle.USER_OWNER);
+ break;
+ default:
+ Slog.w(TAG, "Unexpected restore key " + key);
}
- } else {
- Slog.w(TAG, "Unexpected restore key " + key);
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to restore key " + key);
}
}
}
diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
index c09d6ae..c6e7911 100644
--- a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
+++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
@@ -19,7 +19,7 @@ package com.android.server.pm;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.util.ArraySet;
-import android.util.Log;
+import android.util.Slog;
import java.util.ArrayList;
@@ -113,7 +113,7 @@ public class IntentFilterVerificationState {
setState(state);
return true;
}
- Log.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" +
+ Slog.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" +
code + " as required verifierUid is:" + mRequiredVerifierUid);
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d7abad0..41d3ffd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -212,6 +212,7 @@ import com.android.server.pm.PermissionsState.PermissionState;
import com.android.server.storage.DeviceStorageMonitorInternal;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
@@ -556,6 +557,22 @@ public class PackageManagerService extends IPackageManager.Stub {
final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
new DefaultPermissionGrantPolicy(this);
+ private static class IFVerificationParams {
+ PackageParser.Package pkg;
+ boolean replacing;
+ int userId;
+ int verifierUid;
+
+ public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
+ int _userId, int _verifierUid) {
+ pkg = _pkg;
+ replacing = _replacing;
+ userId = _userId;
+ replacing = _replacing;
+ verifierUid = _verifierUid;
+ }
+ }
+
private interface IntentFilterVerifier<T extends IntentFilter> {
boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
T filter, String packageName);
@@ -629,7 +646,7 @@ public class PackageManagerService extends IPackageManager.Stub {
UserHandle user = new UserHandle(userId);
mContext.sendBroadcastAsUser(verificationIntent, user);
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
- "Sending IntenFilter verification broadcast");
+ "Sending IntentFilter verification broadcast");
}
public void receiveVerificationResponse(int verificationId) {
@@ -639,6 +656,10 @@ public class PackageManagerService extends IPackageManager.Stub {
ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
final int count = filters.size();
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Received verification response " + verificationId
+ + " for " + count + " filters, verified=" + verified);
+ }
for (int n=0; n<count; n++) {
PackageParser.ActivityIntentInfo filter = filters.get(n);
filter.setVerified(verified);
@@ -713,30 +734,27 @@ public class PackageManagerService extends IPackageManager.Stub {
}
@Override
- public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
+ public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
ActivityIntentInfo filter, String packageName) {
- if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
- filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
- if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
- "IntentFilter does not contain HTTP nor HTTPS data scheme");
+ if (!hasValidDomains(filter)) {
return false;
}
IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
if (ivs == null) {
- ivs = createDomainVerificationState(verifierId, userId, verificationId,
+ ivs = createDomainVerificationState(verifierUid, userId, verificationId,
packageName);
}
- if (!hasValidDomains(filter)) {
- return false;
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter);
}
ivs.addFilter(filter);
return true;
}
- private IntentFilterVerificationState createDomainVerificationState(int verifierId,
+ private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
int userId, int verificationId, String packageName) {
IntentFilterVerificationState ivs = new IntentFilterVerificationState(
- verifierId, userId, packageName);
+ verifierUid, userId, packageName);
ivs.setPendingState();
synchronized (mPackages) {
mIntentFilterVerificationStates.append(verificationId, ivs);
@@ -888,8 +906,10 @@ public class PackageManagerService extends IPackageManager.Stub {
final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows
- // backup/restore of preferred activity state
+ // XML tags for backup/restore of various bits of state
private static final String TAG_PREFERRED_BACKUP = "pa";
+ private static final String TAG_DEFAULT_APPS = "da";
+ private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
private final String mRequiredVerifierPackage;
@@ -1507,11 +1527,9 @@ public class PackageManagerService extends IPackageManager.Stub {
break;
}
case START_INTENT_FILTER_VERIFICATIONS: {
- int userId = msg.arg1;
- int verifierUid = msg.arg2;
- PackageParser.Package pkg = (PackageParser.Package)msg.obj;
-
- verifyIntentFiltersIfNeeded(userId, verifierUid, pkg);
+ IFVerificationParams params = (IFVerificationParams) msg.obj;
+ verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
+ params.replacing, params.pkg);
break;
}
case INTENT_FILTER_VERIFIED: {
@@ -2357,8 +2375,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final String packageName = getDefaultBrowserPackageName(myUserId);
PackageInfo info = getPackageInfo(packageName, 0, myUserId);
if (info == null) {
- Slog.w(TAG, "Clearing default Browser as its package is no more installed: " +
- packageName);
+ Slog.w(TAG, "Default browser no longer installed: " + packageName);
setDefaultBrowserPackageName(null, myUserId);
}
}
@@ -11863,7 +11880,7 @@ public class PackageManagerService extends IPackageManager.Stub {
return;
}
- startIntentFilterVerifications(args.user.getIdentifier(), pkg);
+ startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
if (replace) {
replacePackageLI(pkg, parseFlags, scanFlags, args.user,
@@ -11880,7 +11897,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) {
+ private void startIntentFilterVerifications(int userId, boolean replacing,
+ PackageParser.Package pkg) {
if (mIntentFilterVerifierComponent == null) {
Slog.w(TAG, "No IntentFilter verification will not be done as "
+ "there is no IntentFilterVerifier available!");
@@ -11893,14 +11911,11 @@ public class PackageManagerService extends IPackageManager.Stub {
mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
- msg.obj = pkg;
- msg.arg1 = userId;
- msg.arg2 = verifierUid;
-
+ msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
mHandler.sendMessage(msg);
}
- private void verifyIntentFiltersIfNeeded(int userId, int verifierUid,
+ private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
PackageParser.Package pkg) {
int size = pkg.activities.size();
if (size == 0) {
@@ -11920,13 +11935,26 @@ public class PackageManagerService extends IPackageManager.Stub {
+ " if any IntentFilter from the " + size
+ " Activities needs verification ...");
- final int verificationId = mIntentFilterVerificationToken++;
int count = 0;
final String packageName = pkg.packageName;
- boolean needToVerify = false;
synchronized (mPackages) {
+ // If this is a new install and we see that we've already run verification for this
+ // package, we have nothing to do: it means the state was restored from backup.
+ if (!replacing) {
+ IntentFilterVerificationInfo ivi =
+ mSettings.getIntentFilterVerificationLPr(packageName);
+ if (ivi != null) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Package " + packageName+ " already verified: status="
+ + ivi.getStatusString());
+ }
+ return;
+ }
+ }
+
// If any filters need to be verified, then all need to be.
+ boolean needToVerify = false;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
@@ -11938,7 +11966,9 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
+
if (needToVerify) {
+ final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
boolean needsFilterVerification = filter.hasWebDataURI();
@@ -13378,9 +13408,45 @@ public class PackageManagerService extends IPackageManager.Stub {
}
/**
+ * Common machinery for picking apart a restored XML blob and passing
+ * it to a caller-supplied functor to be applied to the running system.
+ */
+ private void restoreFromXml(XmlPullParser parser, int userId,
+ String expectedStartTag, BlobXmlRestorer functor)
+ throws IOException, XmlPullParserException {
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ }
+ if (type != XmlPullParser.START_TAG) {
+ // oops didn't find a start tag?!
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Didn't find start tag during restore");
+ }
+ return;
+ }
+
+ // this is supposed to be TAG_PREFERRED_BACKUP
+ if (!expectedStartTag.equals(parser.getName())) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Found unexpected tag " + parser.getName());
+ }
+ return;
+ }
+
+ // skip interfering stuff, then we're aligned with the backing implementation
+ while ((type = parser.next()) == XmlPullParser.TEXT) { }
+ functor.apply(parser, userId);
+ }
+
+ private interface BlobXmlRestorer {
+ public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
+ }
+
+ /**
* Non-Binder method, support for the backup/restore mechanism: write the
- * full set of preferred activities in its canonical XML format. Returns true
- * on success; false otherwise.
+ * full set of preferred activities in its canonical XML format. Returns the
+ * XML output as a byte array, or null if there is none.
*/
@Override
public byte[] getPreferredActivityBackup(int userId) {
@@ -13421,32 +13487,134 @@ public class PackageManagerService extends IPackageManager.Stub {
try {
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+ restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readPreferredActivitiesLPw(parser, userId);
+ }
+ }
+ } );
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
+ }
+ }
+ }
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
+ /**
+ * Non-Binder method, support for the backup/restore mechanism: write the
+ * default browser (etc) settings in its canonical XML format. Returns the default
+ * browser XML representation as a byte array, or null if there is none.
+ */
+ @Override
+ public byte[] getDefaultAppsBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getDefaultAppsBackup()");
+ }
+
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ try {
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_DEFAULT_APPS);
+
+ synchronized (mPackages) {
+ mSettings.writeDefaultAppsLPr(serializer, userId);
}
- if (type != XmlPullParser.START_TAG) {
- // oops didn't find a start tag?!
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Didn't find start tag during restore");
- }
- return;
+
+ serializer.endTag(null, TAG_DEFAULT_APPS);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Unable to write default apps for backup", e);
}
+ return null;
+ }
- // this is supposed to be TAG_PREFERRED_BACKUP
- if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) {
- if (DEBUG_BACKUP) {
- Slog.e(TAG, "Found unexpected tag " + parser.getName());
- }
- return;
+ return dataStream.toByteArray();
+ }
+
+ @Override
+ public void restoreDefaultApps(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restoreDefaultApps()");
+ }
+
+ try {
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+ restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readDefaultAppsLPw(parser, userId);
+ }
+ }
+ } );
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
}
+ }
+ }
+
+ @Override
+ public byte[] getIntentFilterVerificationBackup(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
+ }
+
+ ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+ try {
+ final XmlSerializer serializer = new FastXmlSerializer();
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
- // skip interfering stuff, then we're aligned with the backing implementation
- while ((type = parser.next()) == XmlPullParser.TEXT) { }
synchronized (mPackages) {
- mSettings.readPreferredActivitiesLPw(parser, userId);
+ mSettings.writeAllDomainVerificationsLPr(serializer, userId);
}
+
+ serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
+ serializer.endDocument();
+ serializer.flush();
+ } catch (Exception e) {
+ if (DEBUG_BACKUP) {
+ Slog.e(TAG, "Unable to write default apps for backup", e);
+ }
+ return null;
+ }
+
+ return dataStream.toByteArray();
+ }
+
+ @Override
+ public void restoreIntentFilterVerification(byte[] backup, int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call restorePreferredActivities()");
+ }
+
+ try {
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
+ restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
+ new BlobXmlRestorer() {
+ @Override
+ public void apply(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ synchronized (mPackages) {
+ mSettings.readAllDomainVerificationsLPr(parser, userId);
+ mSettings.writeLPr();
+ }
+ }
+ } );
} catch (Exception e) {
if (DEBUG_BACKUP) {
Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6415343..169f6de 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -174,6 +174,8 @@ final class Settings {
"crossProfile-intent-filters";
public static final String TAG_DOMAIN_VERIFICATION = "domain-verification";
public static final String TAG_DEFAULT_APPS= "default-apps";
+ public static final String TAG_ALL_INTENT_FILTER_VERIFICATION =
+ "all-intent-filter-verifications";
public static final String TAG_DEFAULT_BROWSER= "default-browser";
private static final String ATTR_NAME = "name";
@@ -206,10 +208,15 @@ final class Settings {
final ArrayMap<String, PackageSetting> mPackages =
new ArrayMap<String, PackageSetting>();
+
// List of replaced system applications
private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
new ArrayMap<String, PackageSetting>();
+ // Set of restored intent-filter verification states
+ private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
+ new ArrayMap<String, IntentFilterVerificationInfo>();
+
private static int mFirstAvailableUid = 0;
// TODO: store SDK versions and fingerprint for each volume UUID
@@ -753,7 +760,8 @@ final class Settings {
}
// Utility method that adds a PackageSetting to mPackages and
- // completes updating the shared user attributes
+ // completes updating the shared user attributes and any restored
+ // app link verification state
private void addPackageSettingLPw(PackageSetting p, String name,
SharedUserSetting sharedUser) {
mPackages.put(name, p);
@@ -776,6 +784,14 @@ final class Settings {
p.sharedUser = sharedUser;
p.appId = sharedUser.userId;
}
+ IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name);
+ if (ivi != null) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Applying restored IVI for " + name + " : " + ivi.getStatusString());
+ }
+ mRestoredIntentFilterVerifications.remove(name);
+ p.setIntentFilterVerificationInfo(ivi);
+ }
}
/*
@@ -1259,13 +1275,13 @@ final class Settings {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
- String tagName = parser.getName();
+ final String tagName = parser.getName();
if (tagName.equals(TAG_ITEM)) {
CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser);
editCrossProfileIntentResolverLPw(userId).addFilter(cpif);
} else {
String msg = "Unknown element under " + TAG_CROSS_PROFILE_INTENT_FILTERS + ": " +
- parser.getName();
+ tagName;
PackageManagerService.reportSettingsProblem(Log.WARN, msg);
XmlUtils.skipCurrentTag(parser);
}
@@ -1279,7 +1295,31 @@ final class Settings {
Log.d(TAG, "Read domain verification for package:" + ivi.getPackageName());
}
- private void readDefaultAppsLPw(XmlPullParser parser, int userId)
+ private void readRestoredIntentFilterVerifications(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ final String tagName = parser.getName();
+ if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
+ IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Restored IVI for " + ivi.getPackageName()
+ + " status=" + ivi.getStatusString());
+ }
+ mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi);
+ } else {
+ Slog.w(TAG, "Unknown element: " + tagName);
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
+ void readDefaultAppsLPw(XmlPullParser parser, int userId)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
@@ -1563,6 +1603,62 @@ final class Settings {
}
}
+ // Specifically for backup/restore
+ void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
+ final int N = mPackages.size();
+ for (int i = 0; i < N; i++) {
+ PackageSetting ps = mPackages.valueAt(i);
+ IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
+ if (ivi != null) {
+ writeDomainVerificationsLPr(serializer, ivi);
+ }
+ }
+ serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION);
+ }
+
+ // Specifically for backup/restore
+ void readAllDomainVerificationsLPr(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ mRestoredIntentFilterVerifications.clear();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
+ IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser);
+ final String pkgName = ivi.getPackageName();
+ final PackageSetting ps = mPackages.get(pkgName);
+ if (ps != null) {
+ // known/existing package; update in place
+ ps.setIntentFilterVerificationInfo(ivi);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Restored IVI for existing app " + pkgName
+ + " status=" + ivi.getStatusString());
+ }
+ } else {
+ mRestoredIntentFilterVerifications.put(pkgName, ivi);
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.d(TAG, "Restored IVI for pending app " + pkgName
+ + " status=" + ivi.getStatusString());
+ }
+ }
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Unknown element under <all-intent-filter-verification>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
void writeDefaultAppsLPr(XmlSerializer serializer, int userId)
throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(null, TAG_DEFAULT_APPS);
@@ -2012,6 +2108,23 @@ final class Settings {
}
}
+ final int numIVIs = mRestoredIntentFilterVerifications.size();
+ if (numIVIs > 0) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Writing restored-ivi entries to packages.xml");
+ }
+ serializer.startTag(null, "restored-ivi");
+ for (int i = 0; i < numIVIs; i++) {
+ IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i);
+ writeDomainVerificationsLPr(serializer, ivi);
+ }
+ serializer.endTag(null, "restored-ivi");
+ } else {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, " no restored IVI entries to write");
+ }
+ }
+
mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
serializer.endTag(null, "packages");
@@ -2441,6 +2554,8 @@ final class Settings {
if (nname != null && oname != null) {
mRenamedPackages.put(nname, oname);
}
+ } else if (tagName.equals("restored-ivi")) {
+ readRestoredIntentFilterVerifications(parser);
} else if (tagName.equals("last-platform-version")) {
mInternalSdkPlatform = mExternalSdkPlatform = 0;
try {