summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJay Shrauner <shrauner@google.com>2014-12-03 15:46:26 -0800
committerJay Shrauner <shrauner@google.com>2014-12-05 13:01:35 -0800
commit4e3a17eaeced54b154b76a42d050fdd9b4ac7c02 (patch)
tree76f0b8ee5256d905ec4eba14fdefa55b023c800d /src
parenta639a24cd7a720761b58d347366a4d46e89db3e0 (diff)
downloadandroid_packages_apps_ContactsCommon-4e3a17eaeced54b154b76a42d050fdd9b4ac7c02.tar.gz
android_packages_apps_ContactsCommon-4e3a17eaeced54b154b76a42d050fdd9b4ac7c02.tar.bz2
android_packages_apps_ContactsCommon-4e3a17eaeced54b154b76a42d050fdd9b4ac7c02.zip
Fix package manager TransactionTooLargeExceptions
Change ExternalAcountType.loadContactsXml to use PackageManager.queryIntentServices to avoid grabbing too much data back. Change LocalizedNameResolver.resolveAllContactsNameFromMetaData to use loadContactsXml. Bug:18607092 Change-Id: I9c31615fc3f7e363612b127f54f2c6cb5a6d44d9
Diffstat (limited to 'src')
-rw-r--r--src/com/android/contacts/common/model/account/ExternalAccountType.java62
-rw-r--r--src/com/android/contacts/common/util/LocalizedNameResolver.java25
2 files changed, 37 insertions, 50 deletions
diff --git a/src/com/android/contacts/common/model/account/ExternalAccountType.java b/src/com/android/contacts/common/model/account/ExternalAccountType.java
index e4cef522..53089b84 100644
--- a/src/com/android/contacts/common/model/account/ExternalAccountType.java
+++ b/src/com/android/contacts/common/model/account/ExternalAccountType.java
@@ -17,9 +17,10 @@
package com.android.contacts.common.model.account;
import android.content.Context;
-import android.content.pm.PackageInfo;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -48,12 +49,15 @@ import java.util.List;
public class ExternalAccountType extends BaseAccountType {
private static final String TAG = "ExternalAccountType";
+ private static final String SYNC_META_DATA = "android.content.SyncAdapter";
+
/**
* The metadata name for so-called "contacts.xml".
*
* On LMP and later, we also accept the "alternate" name.
* This is to allow sync adapters to have a contacts.xml without making it visible on older
- * platforms.
+ * platforms. If you modify this also update the corresponding list in
+ * ContactsProvider/PhotoPriorityResolver
*/
private static final String[] METADATA_CONTACTS_NAMES = new String[] {
"android.provider.ALTERNATE_CONTACTS_STRUCTURE",
@@ -114,15 +118,9 @@ public class ExternalAccountType extends BaseAccountType {
this.resourcePackageName = packageName;
this.syncAdapterPackageName = packageName;
- final PackageManager pm = context.getPackageManager();
final XmlResourceParser parser;
if (injectedMetadata == null) {
- try {
- parser = loadContactsXml(context, packageName);
- } catch (NameNotFoundException e1) {
- // If the package name is not found, we can't initialize this account type.
- return;
- }
+ parser = loadContactsXml(context, packageName);
} else {
parser = injectedMetadata;
}
@@ -181,35 +179,41 @@ public class ExternalAccountType extends BaseAccountType {
/**
* Returns the CONTACTS_STRUCTURE metadata (aka "contacts.xml") in the given apk package.
*
- * Unfortunately, there's no public way to determine which service defines a sync service for
- * which account type, so this method looks through all services in the package, and just
- * returns the first CONTACTS_STRUCTURE metadata defined in any of them.
+ * This method looks through all services in the package that handle sync adapter
+ * intents for the first one that contains CONTACTS_STRUCTURE metadata. We have to look
+ * through all sync adapters in the package in case there are contacts and other sync
+ * adapters (eg, calendar) in the same package.
*
* Returns {@code null} if the package has no CONTACTS_STRUCTURE metadata. In this case
* the account type *will* be initialized with minimal configuration.
- *
- * On the other hand, if the package is not found, it throws a {@link NameNotFoundException},
- * in which case the account type will *not* be initialized.
*/
- private XmlResourceParser loadContactsXml(Context context, String resPackageName)
- throws NameNotFoundException {
+ public static XmlResourceParser loadContactsXml(Context context, String resPackageName) {
final PackageManager pm = context.getPackageManager();
- PackageInfo packageInfo = pm.getPackageInfo(resPackageName,
- PackageManager.GET_SERVICES|PackageManager.GET_META_DATA);
- for (ServiceInfo serviceInfo : packageInfo.services) {
- for (String metadataName : METADATA_CONTACTS_NAMES) {
- final XmlResourceParser parser = serviceInfo.loadXmlMetaData(pm,
- metadataName);
- if (parser != null) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, String.format("Metadata loaded from: %s, %s, %s",
- serviceInfo.packageName, serviceInfo.name,
- metadataName));
+ final Intent intent = new Intent(SYNC_META_DATA).setPackage(resPackageName);
+ final List<ResolveInfo> intentServices = pm.queryIntentServices(intent,
+ PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+
+ if (intentServices != null) {
+ for (final ResolveInfo resolveInfo : intentServices) {
+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+ if (serviceInfo == null) {
+ continue;
+ }
+ for (String metadataName : METADATA_CONTACTS_NAMES) {
+ final XmlResourceParser parser = serviceInfo.loadXmlMetaData(
+ pm, metadataName);
+ if (parser != null) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, String.format("Metadata loaded from: %s, %s, %s",
+ serviceInfo.packageName, serviceInfo.name,
+ metadataName));
+ }
+ return parser;
}
- return parser;
}
}
}
+
// Package was found, but that doesn't contain the CONTACTS_STRUCTURE metadata.
return null;
}
diff --git a/src/com/android/contacts/common/util/LocalizedNameResolver.java b/src/com/android/contacts/common/util/LocalizedNameResolver.java
index 3c21946a..92104c44 100644
--- a/src/com/android/contacts/common/util/LocalizedNameResolver.java
+++ b/src/com/android/contacts/common/util/LocalizedNameResolver.java
@@ -19,10 +19,8 @@ package com.android.contacts.common.util;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.Context;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
@@ -32,6 +30,7 @@ import android.util.Log;
import android.util.Xml;
import com.android.contacts.common.R;
+import com.android.contacts.common.model.account.ExternalAccountType;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -45,11 +44,6 @@ import java.io.IOException;
public class LocalizedNameResolver {
private static final String TAG = "LocalizedNameResolver";
- /**
- * Meta-data key for the contacts configuration associated with a sync service.
- */
- private static final String METADATA_CONTACTS = "android.provider.CONTACTS_STRUCTURE";
-
private static final String CONTACTS_DATA_KIND = "ContactsDataKind";
/**
@@ -82,20 +76,9 @@ public class LocalizedNameResolver {
* reads the picture priority from that file.
*/
private static String resolveAllContactsNameFromMetaData(Context context, String packageName) {
- final PackageManager pm = context.getPackageManager();
- try {
- PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SERVICES
- | PackageManager.GET_META_DATA);
- if (pi != null && pi.services != null) {
- for (ServiceInfo si : pi.services) {
- final XmlResourceParser parser = si.loadXmlMetaData(pm, METADATA_CONTACTS);
- if (parser != null) {
- return loadAllContactsNameFromXml(context, parser, packageName);
- }
- }
- }
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Problem loading \"All Contacts\"-name: " + e.toString());
+ final XmlResourceParser parser = ExternalAccountType.loadContactsXml(context, packageName);
+ if (parser != null) {
+ return loadAllContactsNameFromXml(context, parser, packageName);
}
return null;
}