From 4b93f46130ab9a972773ebf2be9839109d5c6a08 Mon Sep 17 00:00:00 2001 From: Jason Long Date: Wed, 18 Jan 2017 03:16:04 -0800 Subject: [PATCH] Add that declares AutoFillService metadata. The initial version of may contain a settingsActivity attribute. Test: Manual verification Change-Id: I63a67aa4b7110fbf21d0b01ee53add712bfb0364 --- api/current.txt | 1 + api/system-current.txt | 1 + api/test-current.txt | 1 + .../service/autofill/AutoFillService.java | 13 ++++ .../service/autofill/AutoFillServiceInfo.java | 78 +++++++++++++++++-- core/res/res/values/attrs.xml | 17 +++- .../autofill/AutoFillManagerServiceImpl.java | 2 +- 7 files changed, 103 insertions(+), 10 deletions(-) diff --git a/api/current.txt b/api/current.txt index 849861afe30e4..cc98294847c8d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -35261,6 +35261,7 @@ package android.service.autofill { field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS"; field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + field public static final java.lang.String SERVICE_META_DATA = "android.autofill"; } public final class FillCallback { diff --git a/api/system-current.txt b/api/system-current.txt index 683374adc83da..0ccf799ec5309 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -38160,6 +38160,7 @@ package android.service.autofill { field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS"; field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + field public static final java.lang.String SERVICE_META_DATA = "android.autofill"; } public final class FillCallback { diff --git a/api/test-current.txt b/api/test-current.txt index 6f8a96f457680..068777789270c 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -35380,6 +35380,7 @@ package android.service.autofill { field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS"; field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + field public static final java.lang.String SERVICE_META_DATA = "android.autofill"; } public final class FillCallback { diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java index c2e980c5c2778..805d8e5f1a69c 100644 --- a/core/java/android/service/autofill/AutoFillService.java +++ b/core/java/android/service/autofill/AutoFillService.java @@ -61,6 +61,19 @@ public abstract class AutoFillService extends Service { @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.service.autofill.AutoFillService"; + /** + * Name under which a AutoFillService component publishes information about itself. + * This meta-data should reference an XML resource containing a + * <{@link + * android.R.styleable#AutoFillService autofill-service}> tag. + * This is a a sample XML file configuring an AutoFillService: + *
 <autofill-service
+     *     android:settingsActivity="foo.bar.SettingsActivity"
+     *     . . .
+     * />
+ */ + public static final String SERVICE_META_DATA = "android.autofill"; + // Internal bundle keys. /** @hide */ public static final String KEY_CALLBACK = "callback"; /** @hide */ public static final String KEY_SAVABLE_IDS = "savable_ids"; diff --git a/core/java/android/service/autofill/AutoFillServiceInfo.java b/core/java/android/service/autofill/AutoFillServiceInfo.java index fe2161521b82c..ab86580f1f3ba 100644 --- a/core/java/android/service/autofill/AutoFillServiceInfo.java +++ b/core/java/android/service/autofill/AutoFillServiceInfo.java @@ -16,20 +16,34 @@ package android.service.autofill; import android.Manifest; +import android.annotation.Nullable; import android.app.AppGlobals; import android.content.ComponentName; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; import android.os.RemoteException; +import android.util.AttributeSet; +import android.util.Log; +import android.util.Xml; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; /** @hide */ public final class AutoFillServiceInfo { + static final String TAG = "AutoFillServiceInfo"; private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { try { - final ServiceInfo si = - AppGlobals.getPackageManager().getServiceInfo(comp, 0, userHandle); + ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo( + comp, + PackageManager.GET_META_DATA, + userHandle); if (si != null) { return si; } @@ -38,11 +52,21 @@ public final class AutoFillServiceInfo { throw new PackageManager.NameNotFoundException(comp.toString()); } + @Nullable private String mParseError; + @Nullable private ServiceInfo mServiceInfo; + @Nullable + private String mSettingsActivity; - private AutoFillServiceInfo(ServiceInfo si) { + public AutoFillServiceInfo(PackageManager pm, ComponentName comp, int userHandle) + throws PackageManager.NameNotFoundException { + this(pm, getServiceInfoOrThrow(comp, userHandle)); + } + + public AutoFillServiceInfo(PackageManager pm, ServiceInfo si) + throws PackageManager.NameNotFoundException{ if (si == null) { mParseError = "Service not available"; return; @@ -53,19 +77,57 @@ public final class AutoFillServiceInfo { return; } + XmlResourceParser parser = null; + try { + parser = si.loadXmlMetaData(pm, AutoFillService.SERVICE_META_DATA); + if (parser == null) { + mParseError = "No " + AutoFillService.SERVICE_META_DATA + + " meta-data for " + si.packageName; + return; + } + + Resources res = pm.getResourcesForApplication(si.applicationInfo); + + AttributeSet attrs = Xml.asAttributeSet(parser); + + int type; + while ((type=parser.next()) != XmlPullParser.END_DOCUMENT + && type != XmlPullParser.START_TAG) { + } + + String nodeName = parser.getName(); + if (!"autofill-service".equals(nodeName)) { + mParseError = "Meta-data does not start with autofill-service tag"; + return; + } + + TypedArray array = res.obtainAttributes(attrs, + com.android.internal.R.styleable.AutoFillService); + mSettingsActivity = array.getString( + com.android.internal.R.styleable.AutoFillService_settingsActivity); + array.recycle(); + } catch (XmlPullParserException | IOException | PackageManager.NameNotFoundException e) { + mParseError = "Error parsing auto fill service meta-data: " + e; + Log.w(TAG, "error parsing auto fill service meta-data", e); + return; + } finally { + if (parser != null) parser.close(); + } mServiceInfo = si; } - public AutoFillServiceInfo(ComponentName comp, int userHandle) - throws PackageManager.NameNotFoundException { - this(getServiceInfoOrThrow(comp, userHandle)); - } - + @Nullable public String getParseError() { return mParseError; } + @Nullable public ServiceInfo getServiceInfo() { return mServiceInfo; } + + @Nullable + public String getSettingsActivity() { + return mSettingsActivity; + } } diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 8e9959f5664d5..a5c1a94da47e2 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7616,6 +7616,21 @@ + + + + + + + + + + + @@ -8430,7 +8445,7 @@ -