Merge "Back up / restore default app and intent filter verification state" into mnc-dev

This commit is contained in:
Christopher Tate
2015-06-23 01:02:11 +00:00
committed by Android (Google) Code Review
5 changed files with 390 additions and 82 deletions

View File

@@ -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

View File

@@ -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();
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);
}
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
}
} 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();
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);
}
IPackageManager pm = AppGlobals.getPackageManager();
try {
pm.restorePreferredActivities(payload, UserHandle.USER_OWNER);
} catch (Exception e) {
Slog.e(TAG, "Unable to restore", e);
}
} else {
Slog.w(TAG, "Unexpected restore key " + key);
} catch (Exception e) {
Slog.w(TAG, "Unable to restore key " + key);
}
}
}

View File

@@ -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;
}

View File

@@ -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();
@@ -13377,10 +13407,46 @@ 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());
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;
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());
}
}
}
// 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;
}
/**
* 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);
// skip interfering stuff, then we're aligned with the backing implementation
while ((type = parser.next()) == XmlPullParser.TEXT) { }
synchronized (mPackages) {
mSettings.readPreferredActivitiesLPw(parser, userId);
mSettings.writeDefaultAppsLPr(serializer, userId);
}
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;
}
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);
synchronized (mPackages) {
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());

View File

@@ -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 {