Loading core/java/android/provider/Settings.java +8 −1 Original line number Diff line number Diff line Loading @@ -11510,7 +11510,14 @@ public final class Settings { /** * The packages whitelisted to be run in autofill compatibility mode. The list * of packages is ":" colon delimited. * of packages is {@code ":"} colon delimited, and each entry has the name of the * package and an optional list of url bar resource ids (the list is delimited by * brackets&mdash{@code [} and {@code ]}&mdash and is also comma delimited). * * <p>For example, a list with 3 packages {@code p1}, {@code p2}, and {@code p3}, where * package {@code p1} have one id ({@code url_bar}, {@code p2} has none, and {@code p3 } * have 2 ids {@code url_foo} and {@code url_bas}) would be * {@code p1[url_bar]:p2:p3[url_foo,url_bas]} * * @hide */ Loading core/java/android/service/autofill/AutofillServiceInfo.java +14 −24 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; import android.util.Xml; import com.android.internal.R; Loading Loading @@ -79,7 +78,7 @@ public final class AutofillServiceInfo { private final String mSettingsActivity; @Nullable private final ArrayMap<String, Pair<Long, String>> mCompatibilityPackages; private final ArrayMap<String, Long> mCompatibilityPackages; public AutofillServiceInfo(Context context, ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { Loading Loading @@ -117,7 +116,7 @@ public final class AutofillServiceInfo { } String settingsActivity = null; ArrayMap<String, Pair<Long, String>> compatibilityPackages = null; ArrayMap<String, Long> compatibilityPackages = null; try { final Resources resources = context.getPackageManager().getResourcesForApplication( Loading Loading @@ -153,10 +152,9 @@ public final class AutofillServiceInfo { mCompatibilityPackages = compatibilityPackages; } private ArrayMap<String, Pair<Long, String>> parseCompatibilityPackages(XmlPullParser parser, Resources resources) throws IOException, XmlPullParserException { ArrayMap<String, Pair<Long, String>> compatibilityPackages = null; private ArrayMap<String, Long> parseCompatibilityPackages(XmlPullParser parser, Resources resources) throws IOException, XmlPullParserException { ArrayMap<String, Long> compatibilityPackages = null; final int outerDepth = parser.getDepth(); int type; Loading Loading @@ -200,13 +198,18 @@ public final class AutofillServiceInfo { } else { maxVersionCode = Long.MAX_VALUE; } if (true) { // TODO(b/74445943): remove block after P DP2 is branched final String urlBarResourceId = cpAttributes.getString( R.styleable.AutofillService_CompatibilityPackage_urlBarResourceId); if (urlBarResourceId != null) { Log.e(TAG, "Service is using deprecated attribute 'urlBarResourceId'"); } } if (compatibilityPackages == null) { compatibilityPackages = new ArrayMap<>(); } compatibilityPackages.put(name, new Pair<>(maxVersionCode, urlBarResourceId)); compatibilityPackages.put(name, maxVersionCode); } finally { XmlUtils.skipCurrentTag(parser); if (cpAttributes != null) { Loading @@ -228,23 +231,10 @@ public final class AutofillServiceInfo { return mSettingsActivity; } public ArrayMap<String, Pair<Long, String>> getCompatibilityPackages() { public ArrayMap<String, Long> getCompatibilityPackages() { return mCompatibilityPackages; } /** * Gets the resource id of the URL bar for a package. Used in compat mode */ // TODO: return a list of strings instead @Nullable public String getUrlBarResourceId(String packageName) { if (mCompatibilityPackages == null) { return null; } final Pair<Long, String> pair = mCompatibilityPackages.get(packageName); return pair == null ? null : pair.second; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); Loading core/res/res/values/attrs.xml +1 −3 Original line number Diff line number Diff line Loading @@ -7978,9 +7978,7 @@ android.content.pm.PackageInfo#getLongVersionCode()} for the target package. --> <attr name="maxLongVersionCode" format="string" /> <!-- The resource id of view that contains the URL bar of the HTML page being loaded. Typically used when compatibility mode is used in a browser. --> <!-- TODO(b/74445943): STOPSHIP (urlBarResourceId should be removed after P DP2 is branched)--> <attr name="urlBarResourceId" format="string" /> </declare-styleable> Loading core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2869,6 +2869,7 @@ <public name="outlineSpotShadowColor" /> <public name="outlineAmbientShadowColor" /> <public name="maxLongVersionCode" /> <!-- TODO(b/74445943): STOPSHIP (urlBarResourceId should be removed after P DP2 is branched)--> <public name="urlBarResourceId" /> <!-- @hide @SystemApi --> <public name="userRestriction" /> Loading services/autofill/java/com/android/server/autofill/AutofillManagerService.java +118 −24 Original line number Diff line number Diff line Loading @@ -59,9 +59,7 @@ import android.service.autofill.UserData; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LocalLog; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading @@ -73,6 +71,7 @@ import android.view.autofill.IAutoFillManager; import android.view.autofill.IAutoFillManagerClient; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; import com.android.internal.os.IResultReceiver; Loading @@ -88,8 +87,8 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * Entry point service for autofill management. Loading @@ -105,6 +104,9 @@ public final class AutofillManagerService extends SystemService { static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions"; private static final char COMPAT_PACKAGE_DELIMITER = ':'; private static final char COMPAT_PACKAGE_URL_IDS_DELIMITER = ','; private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN = '['; private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_END = ']'; private final Context mContext; private final AutoFillUI mUi; Loading Loading @@ -326,7 +328,7 @@ public final class AutofillManagerService extends SystemService { if (service == null) { service = new AutofillManagerServiceImpl(mContext, mLock, mRequestsHistory, mUiLatencyHistory, mWtfHistory, resolvedUserId, mUi, mDisabledUsers.get(resolvedUserId)); mAutofillCompatState, mDisabledUsers.get(resolvedUserId)); mServicesCache.put(userId, service); addCompatibilityModeRequestsLocked(service, userId); } Loading Loading @@ -544,23 +546,24 @@ public final class AutofillManagerService extends SystemService { private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service , int userId) { mAutofillCompatState.reset(); final ArrayMap<String, Pair<Long, String>> compatPackages = final ArrayMap<String, Long> compatPackages = service.getCompatibilityPackagesLocked(); if (compatPackages == null || compatPackages.isEmpty()) { return; } final Set<String> whiteListedPackages = getWhitelistedCompatModePackages(); final Map<String, String[]> whiteListedPackages = getWhitelistedCompatModePackages(); final int compatPackageCount = compatPackages.size(); for (int i = 0; i < compatPackageCount; i++) { final String packageName = compatPackages.keyAt(i); if (whiteListedPackages == null || !whiteListedPackages.contains(packageName)) { if (whiteListedPackages == null || !whiteListedPackages.containsKey(packageName)) { Slog.w(TAG, "Ignoring not whitelisted compat package " + packageName); continue; } final Long maxVersionCode = compatPackages.valueAt(i).first; final Long maxVersionCode = compatPackages.valueAt(i); if (maxVersionCode != null) { mAutofillCompatState.addCompatibilityModeRequest(packageName, maxVersionCode, userId); maxVersionCode, whiteListedPackages.get(packageName), userId); } } } Loading @@ -571,16 +574,60 @@ public final class AutofillManagerService extends SystemService { Settings.Global.AUTOFILL_COMPAT_ALLOWED_PACKAGES); } private @Nullable Set<String> getWhitelistedCompatModePackages() { final String compatPackagesSetting = getWhitelistedCompatModePackagesFromSettings(); if (TextUtils.isEmpty(compatPackagesSetting)) { @Nullable private Map<String, String[]> getWhitelistedCompatModePackages() { return getWhitelistedCompatModePackages(getWhitelistedCompatModePackagesFromSettings()); } @Nullable @VisibleForTesting static Map<String, String[]> getWhitelistedCompatModePackages(String setting) { if (TextUtils.isEmpty(setting)) { return null; } final Set<String> compatPackages = new ArraySet<>(); final ArrayMap<String, String[]> compatPackages = new ArrayMap<>(); final SimpleStringSplitter splitter = new SimpleStringSplitter(COMPAT_PACKAGE_DELIMITER); splitter.setString(compatPackagesSetting); splitter.setString(setting); while (splitter.hasNext()) { compatPackages.add(splitter.next()); final String packageBlock = splitter.next(); final int urlBlockIndex = packageBlock.indexOf(COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN); final String packageName; final List<String> urlBarIds; if (urlBlockIndex == -1) { packageName = packageBlock; urlBarIds = null; } else { if (packageBlock.charAt(packageBlock.length() - 1) != COMPAT_PACKAGE_URL_IDS_BLOCK_END) { Slog.w(TAG, "Ignoring entry '" + packageBlock + "' on '" + setting + "'because it does not end on '" + COMPAT_PACKAGE_URL_IDS_BLOCK_END + "'"); continue; } packageName = packageBlock.substring(0, urlBlockIndex); urlBarIds = new ArrayList<>(); final String urlBarIdsBlock = packageBlock.substring(urlBlockIndex + 1, packageBlock.length() - 1); if (sVerbose) { Slog.v(TAG, "pkg:" + packageName + ": block:" + packageBlock + ": urls:" + urlBarIds + ": block:" + urlBarIdsBlock + ":"); } final SimpleStringSplitter splitter2 = new SimpleStringSplitter(COMPAT_PACKAGE_URL_IDS_DELIMITER); splitter2.setString(urlBarIdsBlock); while (splitter2.hasNext()) { final String urlBarId = splitter2.next(); urlBarIds.add(urlBarId); } } if (urlBarIds == null) { compatPackages.put(packageName, null); } else { final String[] urlBarIdsArray = new String[urlBarIds.size()]; urlBarIds.toArray(urlBarIdsArray); compatPackages.put(packageName, urlBarIdsArray); } } return compatPackages; } Loading @@ -598,13 +645,41 @@ public final class AutofillManagerService extends SystemService { return mAutofillCompatState.isCompatibilityModeRequested( packageName, versionCode, userId); } } /** * Compatibility mode metadata per package. */ private static final class PackageCompatState { private final long maxVersionCode; private final String[] urlBarResourceIds; PackageCompatState(long maxVersionCode, String[] urlBarResourceIds) { this.maxVersionCode = maxVersionCode; this.urlBarResourceIds = urlBarResourceIds; } @Override public String toString() { return "PackageCompatState: [maxVersionCode=" + maxVersionCode + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds) + "]"; } } private static final class AutofillCompatState { /** * Compatibility mode metadata associated with all services. * * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because * it cannot hold a lock on the main lock when * {@link AutofillCompatState#isCompatibilityModeRequested(String, long, int)} is called by * external services. */ static final class AutofillCompatState { private final Object mLock = new Object(); @GuardedBy("mLock") private SparseArray<ArrayMap<String, Long>> mUserSpecs; private SparseArray<ArrayMap<String, PackageCompatState>> mUserSpecs; boolean isCompatibilityModeRequested(@NonNull String packageName, long versionCode, @UserIdInt int userId) { Loading @@ -612,30 +687,49 @@ public final class AutofillManagerService extends SystemService { if (mUserSpecs == null) { return false; } final ArrayMap<String, Long> userSpec = mUserSpecs.get(userId); final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { return false; } final Long maxVersionCode = userSpec.get(packageName); if (maxVersionCode == null) { final PackageCompatState metadata = userSpec.get(packageName); if (metadata == null) { return false; } return versionCode <= maxVersionCode; return versionCode <= metadata.maxVersionCode; } } @Nullable String[] getUrlBarResourceIds(@NonNull String packageName, @UserIdInt int userId) { synchronized (mLock) { if (mUserSpecs == null) { return null; } final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { return null; } final PackageCompatState metadata = userSpec.get(packageName); if (metadata == null) { return null; } return metadata.urlBarResourceIds; } } void addCompatibilityModeRequest(@NonNull String packageName, long versionCode, @UserIdInt int userId) { long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId) { synchronized (mLock) { if (mUserSpecs == null) { mUserSpecs = new SparseArray<>(); } ArrayMap<String, Long> userSpec = mUserSpecs.get(userId); ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { userSpec = new ArrayMap<>(); mUserSpecs.put(userId, userSpec); } userSpec.put(packageName, versionCode); userSpec.put(packageName, new PackageCompatState(versionCode, urlBarResourceIds)); } } Loading Loading
core/java/android/provider/Settings.java +8 −1 Original line number Diff line number Diff line Loading @@ -11510,7 +11510,14 @@ public final class Settings { /** * The packages whitelisted to be run in autofill compatibility mode. The list * of packages is ":" colon delimited. * of packages is {@code ":"} colon delimited, and each entry has the name of the * package and an optional list of url bar resource ids (the list is delimited by * brackets&mdash{@code [} and {@code ]}&mdash and is also comma delimited). * * <p>For example, a list with 3 packages {@code p1}, {@code p2}, and {@code p3}, where * package {@code p1} have one id ({@code url_bar}, {@code p2} has none, and {@code p3 } * have 2 ids {@code url_foo} and {@code url_bas}) would be * {@code p1[url_bar]:p2:p3[url_foo,url_bas]} * * @hide */ Loading
core/java/android/service/autofill/AutofillServiceInfo.java +14 −24 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; import android.util.Xml; import com.android.internal.R; Loading Loading @@ -79,7 +78,7 @@ public final class AutofillServiceInfo { private final String mSettingsActivity; @Nullable private final ArrayMap<String, Pair<Long, String>> mCompatibilityPackages; private final ArrayMap<String, Long> mCompatibilityPackages; public AutofillServiceInfo(Context context, ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { Loading Loading @@ -117,7 +116,7 @@ public final class AutofillServiceInfo { } String settingsActivity = null; ArrayMap<String, Pair<Long, String>> compatibilityPackages = null; ArrayMap<String, Long> compatibilityPackages = null; try { final Resources resources = context.getPackageManager().getResourcesForApplication( Loading Loading @@ -153,10 +152,9 @@ public final class AutofillServiceInfo { mCompatibilityPackages = compatibilityPackages; } private ArrayMap<String, Pair<Long, String>> parseCompatibilityPackages(XmlPullParser parser, Resources resources) throws IOException, XmlPullParserException { ArrayMap<String, Pair<Long, String>> compatibilityPackages = null; private ArrayMap<String, Long> parseCompatibilityPackages(XmlPullParser parser, Resources resources) throws IOException, XmlPullParserException { ArrayMap<String, Long> compatibilityPackages = null; final int outerDepth = parser.getDepth(); int type; Loading Loading @@ -200,13 +198,18 @@ public final class AutofillServiceInfo { } else { maxVersionCode = Long.MAX_VALUE; } if (true) { // TODO(b/74445943): remove block after P DP2 is branched final String urlBarResourceId = cpAttributes.getString( R.styleable.AutofillService_CompatibilityPackage_urlBarResourceId); if (urlBarResourceId != null) { Log.e(TAG, "Service is using deprecated attribute 'urlBarResourceId'"); } } if (compatibilityPackages == null) { compatibilityPackages = new ArrayMap<>(); } compatibilityPackages.put(name, new Pair<>(maxVersionCode, urlBarResourceId)); compatibilityPackages.put(name, maxVersionCode); } finally { XmlUtils.skipCurrentTag(parser); if (cpAttributes != null) { Loading @@ -228,23 +231,10 @@ public final class AutofillServiceInfo { return mSettingsActivity; } public ArrayMap<String, Pair<Long, String>> getCompatibilityPackages() { public ArrayMap<String, Long> getCompatibilityPackages() { return mCompatibilityPackages; } /** * Gets the resource id of the URL bar for a package. Used in compat mode */ // TODO: return a list of strings instead @Nullable public String getUrlBarResourceId(String packageName) { if (mCompatibilityPackages == null) { return null; } final Pair<Long, String> pair = mCompatibilityPackages.get(packageName); return pair == null ? null : pair.second; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); Loading
core/res/res/values/attrs.xml +1 −3 Original line number Diff line number Diff line Loading @@ -7978,9 +7978,7 @@ android.content.pm.PackageInfo#getLongVersionCode()} for the target package. --> <attr name="maxLongVersionCode" format="string" /> <!-- The resource id of view that contains the URL bar of the HTML page being loaded. Typically used when compatibility mode is used in a browser. --> <!-- TODO(b/74445943): STOPSHIP (urlBarResourceId should be removed after P DP2 is branched)--> <attr name="urlBarResourceId" format="string" /> </declare-styleable> Loading
core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -2869,6 +2869,7 @@ <public name="outlineSpotShadowColor" /> <public name="outlineAmbientShadowColor" /> <public name="maxLongVersionCode" /> <!-- TODO(b/74445943): STOPSHIP (urlBarResourceId should be removed after P DP2 is branched)--> <public name="urlBarResourceId" /> <!-- @hide @SystemApi --> <public name="userRestriction" /> Loading
services/autofill/java/com/android/server/autofill/AutofillManagerService.java +118 −24 Original line number Diff line number Diff line Loading @@ -59,9 +59,7 @@ import android.service.autofill.UserData; import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LocalLog; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading @@ -73,6 +71,7 @@ import android.view.autofill.IAutoFillManager; import android.view.autofill.IAutoFillManagerClient; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.os.BackgroundThread; import com.android.internal.os.IResultReceiver; Loading @@ -88,8 +87,8 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * Entry point service for autofill management. Loading @@ -105,6 +104,9 @@ public final class AutofillManagerService extends SystemService { static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions"; private static final char COMPAT_PACKAGE_DELIMITER = ':'; private static final char COMPAT_PACKAGE_URL_IDS_DELIMITER = ','; private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN = '['; private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_END = ']'; private final Context mContext; private final AutoFillUI mUi; Loading Loading @@ -326,7 +328,7 @@ public final class AutofillManagerService extends SystemService { if (service == null) { service = new AutofillManagerServiceImpl(mContext, mLock, mRequestsHistory, mUiLatencyHistory, mWtfHistory, resolvedUserId, mUi, mDisabledUsers.get(resolvedUserId)); mAutofillCompatState, mDisabledUsers.get(resolvedUserId)); mServicesCache.put(userId, service); addCompatibilityModeRequestsLocked(service, userId); } Loading Loading @@ -544,23 +546,24 @@ public final class AutofillManagerService extends SystemService { private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service , int userId) { mAutofillCompatState.reset(); final ArrayMap<String, Pair<Long, String>> compatPackages = final ArrayMap<String, Long> compatPackages = service.getCompatibilityPackagesLocked(); if (compatPackages == null || compatPackages.isEmpty()) { return; } final Set<String> whiteListedPackages = getWhitelistedCompatModePackages(); final Map<String, String[]> whiteListedPackages = getWhitelistedCompatModePackages(); final int compatPackageCount = compatPackages.size(); for (int i = 0; i < compatPackageCount; i++) { final String packageName = compatPackages.keyAt(i); if (whiteListedPackages == null || !whiteListedPackages.contains(packageName)) { if (whiteListedPackages == null || !whiteListedPackages.containsKey(packageName)) { Slog.w(TAG, "Ignoring not whitelisted compat package " + packageName); continue; } final Long maxVersionCode = compatPackages.valueAt(i).first; final Long maxVersionCode = compatPackages.valueAt(i); if (maxVersionCode != null) { mAutofillCompatState.addCompatibilityModeRequest(packageName, maxVersionCode, userId); maxVersionCode, whiteListedPackages.get(packageName), userId); } } } Loading @@ -571,16 +574,60 @@ public final class AutofillManagerService extends SystemService { Settings.Global.AUTOFILL_COMPAT_ALLOWED_PACKAGES); } private @Nullable Set<String> getWhitelistedCompatModePackages() { final String compatPackagesSetting = getWhitelistedCompatModePackagesFromSettings(); if (TextUtils.isEmpty(compatPackagesSetting)) { @Nullable private Map<String, String[]> getWhitelistedCompatModePackages() { return getWhitelistedCompatModePackages(getWhitelistedCompatModePackagesFromSettings()); } @Nullable @VisibleForTesting static Map<String, String[]> getWhitelistedCompatModePackages(String setting) { if (TextUtils.isEmpty(setting)) { return null; } final Set<String> compatPackages = new ArraySet<>(); final ArrayMap<String, String[]> compatPackages = new ArrayMap<>(); final SimpleStringSplitter splitter = new SimpleStringSplitter(COMPAT_PACKAGE_DELIMITER); splitter.setString(compatPackagesSetting); splitter.setString(setting); while (splitter.hasNext()) { compatPackages.add(splitter.next()); final String packageBlock = splitter.next(); final int urlBlockIndex = packageBlock.indexOf(COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN); final String packageName; final List<String> urlBarIds; if (urlBlockIndex == -1) { packageName = packageBlock; urlBarIds = null; } else { if (packageBlock.charAt(packageBlock.length() - 1) != COMPAT_PACKAGE_URL_IDS_BLOCK_END) { Slog.w(TAG, "Ignoring entry '" + packageBlock + "' on '" + setting + "'because it does not end on '" + COMPAT_PACKAGE_URL_IDS_BLOCK_END + "'"); continue; } packageName = packageBlock.substring(0, urlBlockIndex); urlBarIds = new ArrayList<>(); final String urlBarIdsBlock = packageBlock.substring(urlBlockIndex + 1, packageBlock.length() - 1); if (sVerbose) { Slog.v(TAG, "pkg:" + packageName + ": block:" + packageBlock + ": urls:" + urlBarIds + ": block:" + urlBarIdsBlock + ":"); } final SimpleStringSplitter splitter2 = new SimpleStringSplitter(COMPAT_PACKAGE_URL_IDS_DELIMITER); splitter2.setString(urlBarIdsBlock); while (splitter2.hasNext()) { final String urlBarId = splitter2.next(); urlBarIds.add(urlBarId); } } if (urlBarIds == null) { compatPackages.put(packageName, null); } else { final String[] urlBarIdsArray = new String[urlBarIds.size()]; urlBarIds.toArray(urlBarIdsArray); compatPackages.put(packageName, urlBarIdsArray); } } return compatPackages; } Loading @@ -598,13 +645,41 @@ public final class AutofillManagerService extends SystemService { return mAutofillCompatState.isCompatibilityModeRequested( packageName, versionCode, userId); } } /** * Compatibility mode metadata per package. */ private static final class PackageCompatState { private final long maxVersionCode; private final String[] urlBarResourceIds; PackageCompatState(long maxVersionCode, String[] urlBarResourceIds) { this.maxVersionCode = maxVersionCode; this.urlBarResourceIds = urlBarResourceIds; } @Override public String toString() { return "PackageCompatState: [maxVersionCode=" + maxVersionCode + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds) + "]"; } } private static final class AutofillCompatState { /** * Compatibility mode metadata associated with all services. * * <p>This object is defined here instead of on each {@link AutofillManagerServiceImpl} because * it cannot hold a lock on the main lock when * {@link AutofillCompatState#isCompatibilityModeRequested(String, long, int)} is called by * external services. */ static final class AutofillCompatState { private final Object mLock = new Object(); @GuardedBy("mLock") private SparseArray<ArrayMap<String, Long>> mUserSpecs; private SparseArray<ArrayMap<String, PackageCompatState>> mUserSpecs; boolean isCompatibilityModeRequested(@NonNull String packageName, long versionCode, @UserIdInt int userId) { Loading @@ -612,30 +687,49 @@ public final class AutofillManagerService extends SystemService { if (mUserSpecs == null) { return false; } final ArrayMap<String, Long> userSpec = mUserSpecs.get(userId); final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { return false; } final Long maxVersionCode = userSpec.get(packageName); if (maxVersionCode == null) { final PackageCompatState metadata = userSpec.get(packageName); if (metadata == null) { return false; } return versionCode <= maxVersionCode; return versionCode <= metadata.maxVersionCode; } } @Nullable String[] getUrlBarResourceIds(@NonNull String packageName, @UserIdInt int userId) { synchronized (mLock) { if (mUserSpecs == null) { return null; } final ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { return null; } final PackageCompatState metadata = userSpec.get(packageName); if (metadata == null) { return null; } return metadata.urlBarResourceIds; } } void addCompatibilityModeRequest(@NonNull String packageName, long versionCode, @UserIdInt int userId) { long versionCode, @Nullable String[] urlBarResourceIds, @UserIdInt int userId) { synchronized (mLock) { if (mUserSpecs == null) { mUserSpecs = new SparseArray<>(); } ArrayMap<String, Long> userSpec = mUserSpecs.get(userId); ArrayMap<String, PackageCompatState> userSpec = mUserSpecs.get(userId); if (userSpec == null) { userSpec = new ArrayMap<>(); mUserSpecs.put(userId, userSpec); } userSpec.put(packageName, versionCode); userSpec.put(packageName, new PackageCompatState(versionCode, urlBarResourceIds)); } } Loading