diff options
author | Justin Klaassen <justinklaassen@google.com> | 2017-10-24 19:50:40 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2017-10-24 19:50:40 -0400 |
commit | 47ed54e5d312f899507d28d6e95ccc18a0de19fe (patch) | |
tree | 7a2d435c55c36fbc1d07e895bd0c68b18f84e12c /android/content | |
parent | 07f9f65561c2b81bcd189b895b31bb2ad0438d74 (diff) | |
download | android-28-47ed54e5d312f899507d28d6e95ccc18a0de19fe.tar.gz |
Import Android SDK Platform P [4413397]
/google/data/ro/projects/android/fetch_artifact \
--bid 4413397 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4413397.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: I3cf1f7c36e61c090dcc7de7bcfa812ef2bf96c00
Diffstat (limited to 'android/content')
-rw-r--r-- | android/content/ContentProvider.java | 3 | ||||
-rw-r--r-- | android/content/ContentResolver.java | 36 | ||||
-rw-r--r-- | android/content/Context.java | 1 | ||||
-rw-r--r-- | android/content/Intent.java | 52 | ||||
-rw-r--r-- | android/content/IntentFilter.java | 63 | ||||
-rw-r--r-- | android/content/pm/FeatureInfo.java | 13 | ||||
-rw-r--r-- | android/content/pm/LauncherApps.java | 51 | ||||
-rw-r--r-- | android/content/pm/PackageManagerInternal.java | 5 | ||||
-rw-r--r-- | android/content/pm/PackageParser.java | 23 | ||||
-rw-r--r-- | android/content/pm/PermissionInfo.java | 5 | ||||
-rw-r--r-- | android/content/pm/ResolveInfo.java | 34 | ||||
-rw-r--r-- | android/content/pm/ShortcutInfo.java | 207 | ||||
-rw-r--r-- | android/content/pm/ShortcutServiceInternal.java | 7 | ||||
-rw-r--r-- | android/content/res/FontResourcesParser.java | 15 | ||||
-rw-r--r-- | android/content/res/ResourcesImpl.java | 2 |
15 files changed, 448 insertions, 69 deletions
diff --git a/android/content/ContentProvider.java b/android/content/ContentProvider.java index 5b2bf456..cdeaea3e 100644 --- a/android/content/ContentProvider.java +++ b/android/content/ContentProvider.java @@ -2099,8 +2099,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public static Uri maybeAddUserId(Uri uri, int userId) { if (uri == null) return null; if (userId != UserHandle.USER_CURRENT - && (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) - || ContentResolver.SCHEME_SLICE.equals(uri.getScheme()))) { + && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { if (!uriHasUserId(uri)) { //We don't add the user Id if there's already one Uri.Builder builder = uri.buildUpon(); diff --git a/android/content/ContentResolver.java b/android/content/ContentResolver.java index 02e70f55..9ccc552f 100644 --- a/android/content/ContentResolver.java +++ b/android/content/ContentResolver.java @@ -47,8 +47,6 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; -import android.slice.Slice; -import android.slice.SliceProvider; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; @@ -180,8 +178,6 @@ public abstract class ContentResolver { public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); - /** @hide */ - public static final String SCHEME_SLICE = "slice"; public static final String SCHEME_CONTENT = "content"; public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; public static final String SCHEME_FILE = "file"; @@ -1722,36 +1718,6 @@ public abstract class ContentResolver { } /** - * Turns a slice Uri into slice content. - * - * @param uri The URI to a slice provider - * @return The Slice provided by the app or null if none is given. - * @see Slice - * @hide - */ - public final @Nullable Slice bindSlice(@NonNull Uri uri) { - Preconditions.checkNotNull(uri, "uri"); - IContentProvider provider = acquireProvider(uri); - if (provider == null) { - throw new IllegalArgumentException("Unknown URI " + uri); - } - try { - Bundle extras = new Bundle(); - extras.putParcelable(SliceProvider.EXTRA_BIND_URI, uri); - final Bundle res = provider.call(mPackageName, SliceProvider.METHOD_SLICE, null, - extras); - Bundle.setDefusable(res, true); - return res.getParcelable(SliceProvider.EXTRA_SLICE); - } catch (RemoteException e) { - // Arbitrary and not worth documenting, as Activity - // Manager will kill this process shortly anyway. - return null; - } finally { - releaseProvider(provider); - } - } - - /** * Returns the content provider for the given content URI. * * @param uri The URI to a content provider @@ -1759,7 +1725,7 @@ public abstract class ContentResolver { * @hide */ public final IContentProvider acquireProvider(Uri uri) { - if (!SCHEME_CONTENT.equals(uri.getScheme()) && !SCHEME_SLICE.equals(uri.getScheme())) { + if (!SCHEME_CONTENT.equals(uri.getScheme())) { return null; } final String auth = uri.getAuthority(); diff --git a/android/content/Context.java b/android/content/Context.java index 20fbf046..c165fb3e 100644 --- a/android/content/Context.java +++ b/android/content/Context.java @@ -3604,7 +3604,6 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a - * {@link android.text.ClipboardManager} for accessing and modifying * {@link android.content.ClipboardManager} for accessing and modifying * the contents of the global clipboard. * diff --git a/android/content/Intent.java b/android/content/Intent.java index c9ad9519..e47de752 100644 --- a/android/content/Intent.java +++ b/android/content/Intent.java @@ -53,6 +53,7 @@ import android.provider.OpenableColumns; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; +import android.util.proto.ProtoOutputStream; import com.android.internal.util.XmlUtils; @@ -9371,6 +9372,57 @@ public class Intent implements Parcelable, Cloneable { } } + /** @hide */ + public void writeToProto(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp, + boolean extras, boolean clip) { + long token = proto.start(fieldId); + if (mAction != null) { + proto.write(IntentProto.ACTION, mAction); + } + if (mCategories != null) { + for (String category : mCategories) { + proto.write(IntentProto.CATEGORIES, category); + } + } + if (mData != null) { + proto.write(IntentProto.DATA, secure ? mData.toSafeString() : mData.toString()); + } + if (mType != null) { + proto.write(IntentProto.TYPE, mType); + } + if (mFlags != 0) { + proto.write(IntentProto.FLAG, "0x" + Integer.toHexString(mFlags)); + } + if (mPackage != null) { + proto.write(IntentProto.PACKAGE, mPackage); + } + if (comp && mComponent != null) { + proto.write(IntentProto.COMPONENT, mComponent.flattenToShortString()); + } + if (mSourceBounds != null) { + proto.write(IntentProto.SOURCE_BOUNDS, mSourceBounds.toShortString()); + } + if (mClipData != null) { + StringBuilder b = new StringBuilder(); + if (clip) { + mClipData.toShortString(b); + } else { + mClipData.toShortStringShortItems(b, false); + } + proto.write(IntentProto.CLIP_DATA, b.toString()); + } + if (extras && mExtras != null) { + proto.write(IntentProto.EXTRAS, mExtras.toShortString()); + } + if (mContentUserHint != 0) { + proto.write(IntentProto.CONTENT_USER_HINT, mContentUserHint); + } + if (mSelector != null) { + proto.write(IntentProto.SELECTOR, mSelector.toShortString(secure, comp, extras, clip)); + } + proto.end(token); + } + /** * Call {@link #toUri} with 0 flags. * @deprecated Use {@link #toUri} instead. diff --git a/android/content/IntentFilter.java b/android/content/IntentFilter.java index c9bce530..a957aed8 100644 --- a/android/content/IntentFilter.java +++ b/android/content/IntentFilter.java @@ -26,6 +26,7 @@ import android.text.TextUtils; import android.util.AndroidException; import android.util.Log; import android.util.Printer; +import android.util.proto.ProtoOutputStream; import com.android.internal.util.XmlUtils; @@ -918,6 +919,15 @@ public class IntentFilter implements Parcelable { dest.writeInt(mPort); } + void writeToProto(ProtoOutputStream proto, long fieldId) { + long token = proto.start(fieldId); + // The original host information is already contained in host and wild, no output now. + proto.write(AuthorityEntryProto.HOST, mHost); + proto.write(AuthorityEntryProto.WILD, mWild); + proto.write(AuthorityEntryProto.PORT, mPort); + proto.end(token); + } + public String getHost() { return mOrigHost; } @@ -1739,6 +1749,59 @@ public class IntentFilter implements Parcelable { } } + /** @hide */ + public void writeToProto(ProtoOutputStream proto, long fieldId) { + long token = proto.start(fieldId); + if (mActions.size() > 0) { + Iterator<String> it = mActions.iterator(); + while (it.hasNext()) { + proto.write(IntentFilterProto.ACTIONS, it.next()); + } + } + if (mCategories != null) { + Iterator<String> it = mCategories.iterator(); + while (it.hasNext()) { + proto.write(IntentFilterProto.CATEGORIES, it.next()); + } + } + if (mDataSchemes != null) { + Iterator<String> it = mDataSchemes.iterator(); + while (it.hasNext()) { + proto.write(IntentFilterProto.DATA_SCHEMES, it.next()); + } + } + if (mDataSchemeSpecificParts != null) { + Iterator<PatternMatcher> it = mDataSchemeSpecificParts.iterator(); + while (it.hasNext()) { + it.next().writeToProto(proto, IntentFilterProto.DATA_SCHEME_SPECS); + } + } + if (mDataAuthorities != null) { + Iterator<AuthorityEntry> it = mDataAuthorities.iterator(); + while (it.hasNext()) { + it.next().writeToProto(proto, IntentFilterProto.DATA_AUTHORITIES); + } + } + if (mDataPaths != null) { + Iterator<PatternMatcher> it = mDataPaths.iterator(); + while (it.hasNext()) { + it.next().writeToProto(proto, IntentFilterProto.DATA_PATHS); + } + } + if (mDataTypes != null) { + Iterator<String> it = mDataTypes.iterator(); + while (it.hasNext()) { + proto.write(IntentFilterProto.DATA_TYPES, it.next()); + } + } + if (mPriority != 0 || mHasPartialTypes) { + proto.write(IntentFilterProto.PRIORITY, mPriority); + proto.write(IntentFilterProto.HAS_PARTIAL_TYPES, mHasPartialTypes); + } + proto.write(IntentFilterProto.GET_AUTO_VERIFY, getAutoVerify()); + proto.end(token); + } + public void dump(Printer du, String prefix) { StringBuilder sb = new StringBuilder(256); if (mActions.size() > 0) { diff --git a/android/content/pm/FeatureInfo.java b/android/content/pm/FeatureInfo.java index 9ee6fa24..ff9fd8ec 100644 --- a/android/content/pm/FeatureInfo.java +++ b/android/content/pm/FeatureInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; +import android.util.proto.ProtoOutputStream; /** * Definition of a single optional hardware or software feature of an Android @@ -113,6 +114,18 @@ public class FeatureInfo implements Parcelable { dest.writeInt(flags); } + /** @hide */ + public void writeToProto(ProtoOutputStream proto, long fieldId) { + long token = proto.start(fieldId); + if (name != null) { + proto.write(FeatureInfoProto.NAME, name); + } + proto.write(FeatureInfoProto.VERSION, version); + proto.write(FeatureInfoProto.GLES_VERSION, getGlEsVersion()); + proto.write(FeatureInfoProto.FLAGS, flags); + proto.end(token); + } + public static final Creator<FeatureInfo> CREATOR = new Creator<FeatureInfo>() { @Override public FeatureInfo createFromParcel(Parcel source) { diff --git a/android/content/pm/LauncherApps.java b/android/content/pm/LauncherApps.java index aa9562ff..b94a410b 100644 --- a/android/content/pm/LauncherApps.java +++ b/android/content/pm/LauncherApps.java @@ -20,8 +20,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; -import android.annotation.SystemService; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemService; import android.annotation.TestApi; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; @@ -37,10 +37,10 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Rect; +import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; -import android.graphics.drawable.AdaptiveIconDrawable; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -282,12 +282,27 @@ public class LauncherApps { public static final int FLAG_GET_MANIFEST = FLAG_MATCH_MANIFEST; /** - * Does not retrieve CHOOSER only shortcuts. - * TODO: Add another flag for MATCH_ALL_PINNED + * @hide include all pinned shortcuts by any launchers, not just by the caller, + * in the result. + * If the caller doesn't havve the {@link android.Manifest.permission#ACCESS_SHORTCUTS} + * permission, this flag will be ignored. + */ + @TestApi + public static final int FLAG_MATCH_ALL_PINNED = 1 << 10; + + /** + * FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST * @hide */ public static final int FLAG_MATCH_ALL_KINDS = - FLAG_GET_DYNAMIC | FLAG_GET_PINNED | FLAG_GET_MANIFEST; + FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST; + + /** + * FLAG_MATCH_DYNAMIC | FLAG_MATCH_PINNED | FLAG_MATCH_MANIFEST | FLAG_MATCH_ALL_PINNED + * @hide + */ + public static final int FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED = + FLAG_MATCH_ALL_KINDS | FLAG_MATCH_ALL_PINNED; /** @hide kept for unit tests */ @Deprecated @@ -319,6 +334,7 @@ public class LauncherApps { FLAG_MATCH_PINNED, FLAG_MATCH_MANIFEST, FLAG_GET_KEY_FIELDS_ONLY, + FLAG_MATCH_MANIFEST, }) @Retention(RetentionPolicy.SOURCE) public @interface QueryFlags {} @@ -678,6 +694,21 @@ public class LauncherApps { } } + private List<ShortcutInfo> maybeUpdateDisabledMessage(List<ShortcutInfo> shortcuts) { + if (shortcuts == null) { + return null; + } + for (int i = shortcuts.size() - 1; i >= 0; i--) { + final ShortcutInfo si = shortcuts.get(i); + final String message = ShortcutInfo.getDisabledReasonForRestoreIssue(mContext, + si.getDisabledReason()); + if (message != null) { + si.setDisabledMessage(message); + } + } + return shortcuts; + } + /** * Returns {@link ShortcutInfo}s that match {@code query}. * @@ -698,10 +729,16 @@ public class LauncherApps { @NonNull UserHandle user) { logErrorForInvalidProfileAccess(user); try { - return mService.getShortcuts(mContext.getPackageName(), + // Note this is the only case we need to update the disabled message for shortcuts + // that weren't restored. + // The restore problem messages are only shown by the user, and publishers will never + // see them. The only other API that the launcher gets shortcuts is the shortcut + // changed callback, but that only returns shortcuts with the "key" information, so + // that won't return disabled message. + return maybeUpdateDisabledMessage(mService.getShortcuts(mContext.getPackageName(), query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity, query.mQueryFlags, user) - .getList(); + .getList()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/android/content/pm/PackageManagerInternal.java b/android/content/pm/PackageManagerInternal.java index be7f921e..143c51da 100644 --- a/android/content/pm/PackageManagerInternal.java +++ b/android/content/pm/PackageManagerInternal.java @@ -467,6 +467,7 @@ public abstract class PackageManagerInternal { /** Updates the flags for the given permission. */ public abstract void updatePermissionFlagsTEMP(@NonNull String permName, @NonNull String packageName, int flagMask, int flagValues, int userId); - /** temporary until mPermissionTrees is moved to PermissionManager */ - public abstract Object enforcePermissionTreeTEMP(@NonNull String permName, int callingUid); + /** Returns a PermissionGroup. */ + public abstract @Nullable PackageParser.PermissionGroup getPermissionGroupTEMP( + @NonNull String groupName); } diff --git a/android/content/pm/PackageParser.java b/android/content/pm/PackageParser.java index 6c7c8a07..ad36139a 100644 --- a/android/content/pm/PackageParser.java +++ b/android/content/pm/PackageParser.java @@ -3711,17 +3711,15 @@ public class PackageParser { ai.flags |= ApplicationInfo.FLAG_IS_GAME; } - if (false) { - if (sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState, - false)) { - ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE; + if (sa.getBoolean( + com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState, + false)) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE; - // A heavy-weight application can not be in a custom process. - // We can do direct compare because we intern all strings. - if (ai.processName != null && ai.processName != ai.packageName) { - outError[0] = "cantSaveState applications can not use custom processes"; - } + // A heavy-weight application can not be in a custom process. + // We can do direct compare because we intern all strings. + if (ai.processName != null && !ai.processName.equals(ai.packageName)) { + outError[0] = "cantSaveState applications can not use custom processes"; } } } @@ -6849,6 +6847,11 @@ public class PackageParser { dest.writeParcelable(group, flags); } + /** @hide */ + public boolean isAppOp() { + return info.isAppOp(); + } + private Permission(Parcel in) { super(in); final ClassLoader boot = Object.class.getClassLoader(); diff --git a/android/content/pm/PermissionInfo.java b/android/content/pm/PermissionInfo.java index b45c26ce..5dd7aeda 100644 --- a/android/content/pm/PermissionInfo.java +++ b/android/content/pm/PermissionInfo.java @@ -353,6 +353,11 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { return size; } + /** @hide */ + public boolean isAppOp() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; + } + public static final Creator<PermissionInfo> CREATOR = new Creator<PermissionInfo>() { @Override diff --git a/android/content/pm/ResolveInfo.java b/android/content/pm/ResolveInfo.java index 79931670..3f63d80f 100644 --- a/android/content/pm/ResolveInfo.java +++ b/android/content/pm/ResolveInfo.java @@ -222,6 +222,40 @@ public class ResolveInfo implements Parcelable { } /** + * @return The resource that would be used when loading + * the label for this resolve info. + * + * @hide + */ + public int resolveLabelResId() { + if (labelRes != 0) { + return labelRes; + } + final ComponentInfo componentInfo = getComponentInfo(); + if (componentInfo.labelRes != 0) { + return componentInfo.labelRes; + } + return componentInfo.applicationInfo.labelRes; + } + + /** + * @return The resource that would be used when loading + * the icon for this resolve info. + * + * @hide + */ + public int resolveIconResId() { + if (icon != 0) { + return icon; + } + final ComponentInfo componentInfo = getComponentInfo(); + if (componentInfo.icon != 0) { + return componentInfo.icon; + } + return componentInfo.applicationInfo.icon; + } + + /** * Retrieve the current graphical icon associated with this resolution. This * will call back on the given PackageManager to load the icon from * the application. diff --git a/android/content/pm/ShortcutInfo.java b/android/content/pm/ShortcutInfo.java index 6b9c7537..9ff07757 100644 --- a/android/content/pm/ShortcutInfo.java +++ b/android/content/pm/ShortcutInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UserIdInt; import android.app.TaskStackBuilder; import android.content.ComponentName; @@ -100,6 +101,13 @@ public final class ShortcutInfo implements Parcelable { /** @hide When this is set, the bitmap icon is waiting to be saved. */ public static final int FLAG_ICON_FILE_PENDING_SAVE = 1 << 11; + /** + * "Shadow" shortcuts are the ones that are restored, but the owner package hasn't been + * installed yet. + * @hide + */ + public static final int FLAG_SHADOW = 1 << 12; + /** @hide */ @IntDef(flag = true, value = { @@ -158,6 +166,124 @@ public final class ShortcutInfo implements Parcelable { public @interface CloneFlags {} /** + * Shortcut is not disabled. + */ + public static final int DISABLED_REASON_NOT_DISABLED = 0; + + /** + * Shortcut has been disabled by the publisher app with the + * {@link ShortcutManager#disableShortcuts(List)} API. + */ + public static final int DISABLED_REASON_BY_APP = 1; + + /** + * Shortcut has been disabled due to changes to the publisher app. (e.g. a manifest shortcut + * no longer exists.) + */ + public static final int DISABLED_REASON_APP_CHANGED = 2; + + /** + * A disabled reason that's equal to or bigger than this is due to backup and restore issue. + * A shortcut with such a reason wil be visible to the launcher, but not to the publisher. + * ({@link #isVisibleToPublisher()} will be false.) + */ + private static final int DISABLED_REASON_RESTORE_ISSUE_START = 100; + + /** + * Shortcut has been restored from the previous device, but the publisher app on the current + * device is of a lower version. The shortcut will not be usable until the app is upgraded to + * the same version or higher. + */ + public static final int DISABLED_REASON_VERSION_LOWER = 100; + + /** + * Shortcut has not been restored because the publisher app does not support backup and restore. + */ + public static final int DISABLED_REASON_BACKUP_NOT_SUPPORTED = 101; + + /** + * Shortcut has not been restored because the publisher app's signature has changed. + */ + public static final int DISABLED_REASON_SIGNATURE_MISMATCH = 102; + + /** + * Shortcut has not been restored for unknown reason. + */ + public static final int DISABLED_REASON_OTHER_RESTORE_ISSUE = 103; + + /** @hide */ + @IntDef(value = { + DISABLED_REASON_NOT_DISABLED, + DISABLED_REASON_BY_APP, + DISABLED_REASON_APP_CHANGED, + DISABLED_REASON_VERSION_LOWER, + DISABLED_REASON_BACKUP_NOT_SUPPORTED, + DISABLED_REASON_SIGNATURE_MISMATCH, + DISABLED_REASON_OTHER_RESTORE_ISSUE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DisabledReason{} + + /** + * Return a label for disabled reasons, which are *not* supposed to be shown to the user. + * @hide + */ + public static String getDisabledReasonDebugString(@DisabledReason int disabledReason) { + switch (disabledReason) { + case DISABLED_REASON_NOT_DISABLED: + return "[Not disabled]"; + case DISABLED_REASON_BY_APP: + return "[Disabled: by app]"; + case DISABLED_REASON_APP_CHANGED: + return "[Disabled: app changed]"; + case DISABLED_REASON_VERSION_LOWER: + return "[Disabled: lower version]"; + case DISABLED_REASON_BACKUP_NOT_SUPPORTED: + return "[Disabled: backup not supported]"; + case DISABLED_REASON_SIGNATURE_MISMATCH: + return "[Disabled: signature mismatch]"; + case DISABLED_REASON_OTHER_RESTORE_ISSUE: + return "[Disabled: unknown restore issue]"; + } + return "[Disabled: unknown reason:" + disabledReason + "]"; + } + + /** + * Return a label for a disabled reason for shortcuts that are disabled due to a backup and + * restore issue. If the reason is not due to backup & restore, then it'll return null. + * + * This method returns localized, user-facing strings, which will be returned by + * {@link #getDisabledMessage()}. + * + * @hide + */ + public static String getDisabledReasonForRestoreIssue(Context context, + @DisabledReason int disabledReason) { + final Resources res = context.getResources(); + + switch (disabledReason) { + case DISABLED_REASON_VERSION_LOWER: + return res.getString( + com.android.internal.R.string.shortcut_restored_on_lower_version); + case DISABLED_REASON_BACKUP_NOT_SUPPORTED: + return res.getString( + com.android.internal.R.string.shortcut_restore_not_supported); + case DISABLED_REASON_SIGNATURE_MISMATCH: + return res.getString( + com.android.internal.R.string.shortcut_restore_signature_mismatch); + case DISABLED_REASON_OTHER_RESTORE_ISSUE: + return res.getString( + com.android.internal.R.string.shortcut_restore_unknown_issue); + } + return null; + } + + /** @hide */ + public static boolean isDisabledForRestoreIssue(@DisabledReason int disabledReason) { + return disabledReason >= DISABLED_REASON_RESTORE_ISSUE_START; + } + + /** * Shortcut category for messaging related actions, such as chat. */ public static final String SHORTCUT_CATEGORY_CONVERSATION = "android.shortcut.conversation"; @@ -240,6 +366,11 @@ public final class ShortcutInfo implements Parcelable { private final int mUserId; + /** @hide */ + public static final int VERSION_CODE_UNKNOWN = -1; + + private int mDisabledReason; + private ShortcutInfo(Builder b) { mUserId = b.mContext.getUserId(); @@ -352,6 +483,7 @@ public final class ShortcutInfo implements Parcelable { mActivity = source.mActivity; mFlags = source.mFlags; mLastChangedTimestamp = source.mLastChangedTimestamp; + mDisabledReason = source.mDisabledReason; // Just always keep it since it's cheep. mIconResId = source.mIconResId; @@ -615,13 +747,23 @@ public final class ShortcutInfo implements Parcelable { /** * @hide + * + * @isUpdating set true if it's "update", as opposed to "replace". */ - public void ensureUpdatableWith(ShortcutInfo source) { + public void ensureUpdatableWith(ShortcutInfo source, boolean isUpdating) { + if (isUpdating) { + Preconditions.checkState(isVisibleToPublisher(), + "[Framework BUG] Invisible shortcuts can't be updated"); + } Preconditions.checkState(mUserId == source.mUserId, "Owner User ID must match"); Preconditions.checkState(mId.equals(source.mId), "ID must match"); Preconditions.checkState(mPackageName.equals(source.mPackageName), "Package name must match"); - Preconditions.checkState(!isImmutable(), "Target ShortcutInfo is immutable"); + + if (isVisibleToPublisher()) { + // Don't do this check for restore-blocked shortcuts. + Preconditions.checkState(!isImmutable(), "Target ShortcutInfo is immutable"); + } } /** @@ -638,7 +780,7 @@ public final class ShortcutInfo implements Parcelable { * @hide */ public void copyNonNullFieldsFrom(ShortcutInfo source) { - ensureUpdatableWith(source); + ensureUpdatableWith(source, /*isUpdating=*/ true); if (source.mActivity != null) { mActivity = source.mActivity; @@ -1169,6 +1311,19 @@ public final class ShortcutInfo implements Parcelable { return mDisabledMessageResId; } + /** @hide */ + public void setDisabledReason(@DisabledReason int reason) { + mDisabledReason = reason; + } + + /** + * Returns why a shortcut has been disabled. + */ + @DisabledReason + public int getDisabledReason() { + return mDisabledReason; + } + /** * Return the shortcut's categories. * @@ -1403,6 +1558,21 @@ public final class ShortcutInfo implements Parcelable { return hasFlags(FLAG_IMMUTABLE); } + /** @hide */ + public boolean isDynamicVisible() { + return isDynamic() && isVisibleToPublisher(); + } + + /** @hide */ + public boolean isPinnedVisible() { + return isPinned() && isVisibleToPublisher(); + } + + /** @hide */ + public boolean isManifestVisible() { + return isDeclaredInManifest() && isVisibleToPublisher(); + } + /** * Return if a shortcut is immutable, in which case it cannot be modified with any of * {@link ShortcutManager} APIs. @@ -1491,6 +1661,18 @@ public final class ShortcutInfo implements Parcelable { } /** + * When the system wasn't able to restore a shortcut, it'll still be registered to the system + * but disabled, and such shortcuts will not be visible to the publisher. They're still visible + * to launchers though. + * + * @hide + */ + @TestApi + public boolean isVisibleToPublisher() { + return !isDisabledForRestoreIssue(mDisabledReason); + } + + /** * Return whether a shortcut only contains "key" information only or not. If true, only the * following fields are available. * <ul> @@ -1668,6 +1850,7 @@ public final class ShortcutInfo implements Parcelable { mFlags = source.readInt(); mIconResId = source.readInt(); mLastChangedTimestamp = source.readLong(); + mDisabledReason = source.readInt(); if (source.readInt() == 0) { return; // key information only. @@ -1711,6 +1894,7 @@ public final class ShortcutInfo implements Parcelable { dest.writeInt(mFlags); dest.writeInt(mIconResId); dest.writeLong(mLastChangedTimestamp); + dest.writeInt(mDisabledReason); if (hasKeyFieldsOnly()) { dest.writeInt(0); @@ -1808,6 +1992,11 @@ public final class ShortcutInfo implements Parcelable { sb.append(", flags=0x"); sb.append(Integer.toHexString(mFlags)); sb.append(" ["); + if ((mFlags & FLAG_SHADOW) != 0) { + // Note the shadow flag isn't actually used anywhere and it's just for dumpsys, so + // we don't have an isXxx for this. + sb.append("Sdw"); + } if (!isEnabled()) { sb.append("Dis"); } @@ -1848,7 +2037,9 @@ public final class ShortcutInfo implements Parcelable { sb.append("packageName="); sb.append(mPackageName); - sb.append(", activity="); + addIndentOrComma(sb, indent); + + sb.append("activity="); sb.append(mActivity); addIndentOrComma(sb, indent); @@ -1883,6 +2074,11 @@ public final class ShortcutInfo implements Parcelable { addIndentOrComma(sb, indent); + sb.append("disabledReason="); + sb.append(getDisabledReasonDebugString(mDisabledReason)); + + addIndentOrComma(sb, indent); + sb.append("categories="); sb.append(mCategories); @@ -1953,7 +2149,7 @@ public final class ShortcutInfo implements Parcelable { CharSequence disabledMessage, int disabledMessageResId, String disabledMessageResName, Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras, long lastChangedTimestamp, - int flags, int iconResId, String iconResName, String bitmapPath) { + int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason) { mUserId = userId; mId = id; mPackageName = packageName; @@ -1978,5 +2174,6 @@ public final class ShortcutInfo implements Parcelable { mIconResId = iconResId; mIconResName = iconResName; mBitmapPath = bitmapPath; + mDisabledReason = disabledReason; } } diff --git a/android/content/pm/ShortcutServiceInternal.java b/android/content/pm/ShortcutServiceInternal.java index 7b7d8ae4..7fc25d82 100644 --- a/android/content/pm/ShortcutServiceInternal.java +++ b/android/content/pm/ShortcutServiceInternal.java @@ -46,7 +46,7 @@ public abstract class ShortcutServiceInternal { @NonNull String callingPackage, long changedSince, @Nullable String packageName, @Nullable List<String> shortcutIds, @Nullable ComponentName componentName, @ShortcutQuery.QueryFlags int flags, - int userId); + int userId, int callingPid, int callingUid); public abstract boolean isPinnedByCaller(int launcherUserId, @NonNull String callingPackage, @@ -58,7 +58,8 @@ public abstract class ShortcutServiceInternal { public abstract Intent[] createShortcutIntents( int launcherUserId, @NonNull String callingPackage, - @NonNull String packageName, @NonNull String shortcutId, int userId); + @NonNull String packageName, @NonNull String shortcutId, int userId, + int callingPid, int callingUid); public abstract void addListener(@NonNull ShortcutChangeListener listener); @@ -70,7 +71,7 @@ public abstract class ShortcutServiceInternal { @NonNull String packageName, @NonNull String shortcutId, int userId); public abstract boolean hasShortcutHostPermission(int launcherUserId, - @NonNull String callingPackage); + @NonNull String callingPackage, int callingPid, int callingUid); public abstract boolean requestPinAppWidget(@NonNull String callingPackage, @NonNull AppWidgetProviderInfo appWidget, @Nullable Bundle extras, diff --git a/android/content/res/FontResourcesParser.java b/android/content/res/FontResourcesParser.java index 042eb87f..28e9fce3 100644 --- a/android/content/res/FontResourcesParser.java +++ b/android/content/res/FontResourcesParser.java @@ -15,7 +15,6 @@ */ package android.content.res; -import com.android.internal.R; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Typeface; @@ -23,6 +22,8 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Xml; +import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -78,12 +79,15 @@ public class FontResourcesParser { private final @NonNull String mFileName; private int mWeight; private int mItalic; + private int mTtcIndex; private int mResourceId; - public FontFileResourceEntry(@NonNull String fileName, int weight, int italic) { + public FontFileResourceEntry(@NonNull String fileName, int weight, int italic, + int ttcIndex) { mFileName = fileName; mWeight = weight; mItalic = italic; + mTtcIndex = ttcIndex; } public @NonNull String getFileName() { @@ -97,6 +101,10 @@ public class FontResourcesParser { public int getItalic() { return mItalic; } + + public int getTtcIndex() { + return mTtcIndex; + } } // A class represents file based font-family element in xml file. @@ -203,6 +211,7 @@ public class FontResourcesParser { Typeface.RESOLVE_BY_FONT_TABLE); int italic = array.getInt(R.styleable.FontFamilyFont_fontStyle, Typeface.RESOLVE_BY_FONT_TABLE); + int ttcIndex = array.getInt(R.styleable.FontFamilyFont_ttcIndex, 0); String filename = array.getString(R.styleable.FontFamilyFont_font); array.recycle(); while (parser.next() != XmlPullParser.END_TAG) { @@ -211,7 +220,7 @@ public class FontResourcesParser { if (filename == null) { return null; } - return new FontFileResourceEntry(filename, weight, italic); + return new FontFileResourceEntry(filename, weight, italic, ttcIndex); } private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException { diff --git a/android/content/res/ResourcesImpl.java b/android/content/res/ResourcesImpl.java index a8b8c4b5..386239cf 100644 --- a/android/content/res/ResourcesImpl.java +++ b/android/content/res/ResourcesImpl.java @@ -796,7 +796,7 @@ public class ResourcesImpl { dr = Drawable.createFromResourceStream(wrapper, value, is, file, null); is.close(); } - } catch (Exception e) { + } catch (Exception | StackOverflowError e) { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); final NotFoundException rnf = new NotFoundException( "File " + file + " from drawable resource ID #0x" + Integer.toHexString(id)); |