Loading core/java/android/os/BaseBundle.java +5 −5 Original line number Diff line number Diff line Loading @@ -475,10 +475,10 @@ public class BaseBundle { map.erase(); map.ensureCapacity(count); } int numLazyValues = 0; int[] numLazyValues = new int[]{0}; try { numLazyValues = parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ ownsParcel, mClassLoader); parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ ownsParcel, mClassLoader, numLazyValues); } catch (BadParcelableException e) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Loading @@ -489,14 +489,14 @@ public class BaseBundle { } finally { mWeakParcelledData = null; if (ownsParcel) { if (numLazyValues == 0) { if (numLazyValues[0] == 0) { recycleParcel(parcelledData); } else { mWeakParcelledData = new WeakReference<>(parcelledData); } } mLazyValues = numLazyValues; mLazyValues = numLazyValues[0]; mParcelledByNative = false; mMap = map; // Set field last as it is volatile Loading core/java/android/os/Parcel.java +5 −7 Original line number Diff line number Diff line Loading @@ -5538,7 +5538,7 @@ public final class Parcel { private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal, int size, @Nullable ClassLoader loader) { readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader); readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader, null); } /** Loading @@ -5548,17 +5548,16 @@ public final class Parcel { * @param lazy Whether to populate the map with lazy {@link Function} objects for * length-prefixed values. See {@link Parcel#readLazyValue(ClassLoader)} for more * details. * @return a count of the lazy values in the map * @param lazyValueCount number of lazy values added here * @hide */ int readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader) { int lazyValues = 0; void readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader, int[] lazyValueCount) { while (size > 0) { String key = readString(); Object value = (lazy) ? readLazyValue(loader) : readValue(loader); if (value instanceof LazyValue) { lazyValues++; lazyValueCount[0]++; } if (sorted) { map.append(key, value); Loading @@ -5570,7 +5569,6 @@ public final class Parcel { if (sorted) { map.validate(); } return lazyValues; } /** Loading core/java/com/android/internal/app/ChooserActivity.java +49 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; import static android.content.ContentProvider.getUriWithoutUserId; import static android.content.ContentProvider.getUserIdFromUri; import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; Loading @@ -40,7 +41,9 @@ import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.IUriGrantsManager; import android.app.SharedElementCallback; import android.app.UriGrantsManager; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionManager; import android.app.prediction.AppPredictor; Loading Loading @@ -77,6 +80,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.metrics.LogMaker; import android.net.Uri; import android.os.AsyncTask; Loading @@ -86,6 +90,7 @@ import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.os.PatternMatcher; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -692,7 +697,11 @@ public class ChooserActivity extends ResolverActivity implements targets = null; break; } targets[i] = (ChooserTarget) pa[i]; ChooserTarget chooserTarget = (ChooserTarget) pa[i]; if (!hasValidIcon(chooserTarget)) { chooserTarget = removeIcon(chooserTarget); } targets[i] = chooserTarget; } mCallerChooserTargets = targets; } Loading Loading @@ -4217,4 +4226,43 @@ public class ChooserActivity extends ResolverActivity implements private boolean shouldNearbyShareBeIncludedAsActionButton() { return !shouldNearbyShareBeFirstInRankedRow(); } private boolean hasValidIcon(ChooserTarget target) { Icon icon = target.getIcon(); if (icon == null) { return true; } if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { Uri uri = icon.getUri(); try { getUriGrantsManager().checkGrantUriPermission_ignoreNonSystem( getLaunchedFromUid(), getPackageName(), getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, getUserIdFromUri(uri) ); } catch (SecurityException | RemoteException e) { Log.e(TAG, "Failed to get URI permission for: " + uri, e); return false; } } return true; } private IUriGrantsManager getUriGrantsManager() { return UriGrantsManager.getService(); } private static ChooserTarget removeIcon(ChooserTarget target) { if (target == null) { return null; } return new ChooserTarget( target.getTitle(), null, target.getScore(), target.getComponentName(), target.getIntentExtras()); } } core/java/com/android/internal/app/IntentForwarderActivity.java +19 −8 Original line number Diff line number Diff line Loading @@ -599,24 +599,35 @@ public class IntentForwarderActivity extends Activity { Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); sanitizeIntent(forwardIntent); Intent intentToCheck = forwardIntent; if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) { if (!canForwardInner(forwardIntent, sourceUserId, targetUserId, packageManager, contentResolver)) { return null; } if (forwardIntent.getSelector() != null) { intentToCheck = forwardIntent.getSelector(); sanitizeIntent(forwardIntent.getSelector()); if (!canForwardInner(forwardIntent.getSelector(), sourceUserId, targetUserId, packageManager, contentResolver)) { return null; } } return forwardIntent; } private static boolean canForwardInner(Intent intent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { if (Intent.ACTION_CHOOSER.equals(intent.getAction())) { return false; } String resolvedType = intentToCheck.resolveTypeIfNeeded(contentResolver); sanitizeIntent(intentToCheck); String resolvedType = intent.resolveTypeIfNeeded(contentResolver); try { if (packageManager.canForwardTo( intentToCheck, resolvedType, sourceUserId, targetUserId)) { return forwardIntent; intent, resolvedType, sourceUserId, targetUserId)) { return true; } } catch (RemoteException e) { Slog.e(TAG, "PackageManagerService is dead?"); } return null; return false; } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +24 −23 Original line number Diff line number Diff line Loading @@ -2951,9 +2951,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, final int transitType = info.getType(); TransitionInfo.Change pipChange = null; int closingSplitTaskId = -1; // This array tracks if we are sending stages TO_BACK in this transition. // TODO (b/349828130): Update for n apps boolean[] stagesSentToBack = new boolean[2]; // This array tracks where we are sending stages (TO_BACK/TO_FRONT) in this transition. // TODO (b/349828130): Update for n apps (needs to handle different indices than 0/1). // Also make sure having multiple changes per stage (2+ tasks in one stage) is being // handled properly. int[] stageChanges = new int[2]; for (int iC = 0; iC < info.getChanges().size(); ++iC) { final TransitionInfo.Change change = info.getChanges().get(iC); Loading Loading @@ -3016,18 +3018,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, + " with " + taskId + " before startAnimation()."); } } if (isClosingType(change.getMode()) && getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED) { // Record which stages are getting sent to back if (change.getMode() == TRANSIT_TO_BACK) { stagesSentToBack[getStageOfTask(taskId)] = true; final int stageOfTaskId = getStageOfTask(taskId); if (stageOfTaskId == STAGE_TYPE_UNDEFINED) { continue; } if (isClosingType(change.getMode())) { // (For PiP transitions) If either one of the 2 stages is closing we're assuming // we'll break split closingSplitTaskId = taskId; } if (transitType == WindowManager.TRANSIT_WAKE) { // Record which stages are receiving which changes if ((change.getMode() == TRANSIT_TO_BACK || change.getMode() == TRANSIT_TO_FRONT) && (stageOfTaskId == STAGE_TYPE_MAIN || stageOfTaskId == STAGE_TYPE_SIDE)) { stageChanges[stageOfTaskId] = change.getMode(); } } } if (pipChange != null) { Loading @@ -3052,19 +3061,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return true; } // If keyguard is active, check to see if we have our TO_BACK transitions in order. // This array should either be all false (no split stages sent to back) or all true // (all stages sent to back). In any other case (which can happen with SHOW_ABOVE_LOCKED // apps) we should break split. if (mKeyguardActive) { boolean isFirstStageSentToBack = stagesSentToBack[0]; for (boolean b : stagesSentToBack) { // Compare each boolean to the first one. If any are different, break split. if (b != isFirstStageSentToBack) { // If keyguard is active, check to see if we have all our stages showing. If one stage // was moved but not the other (which can happen with SHOW_ABOVE_LOCKED apps), we should // break split. if (mKeyguardActive && stageChanges[STAGE_TYPE_MAIN] != stageChanges[STAGE_TYPE_SIDE]) { dismissSplitKeepingLastActiveStage(EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP); break; } } } final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage(); Loading Loading
core/java/android/os/BaseBundle.java +5 −5 Original line number Diff line number Diff line Loading @@ -475,10 +475,10 @@ public class BaseBundle { map.erase(); map.ensureCapacity(count); } int numLazyValues = 0; int[] numLazyValues = new int[]{0}; try { numLazyValues = parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ ownsParcel, mClassLoader); parcelledData.readArrayMap(map, count, !parcelledByNative, /* lazy */ ownsParcel, mClassLoader, numLazyValues); } catch (BadParcelableException e) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e); Loading @@ -489,14 +489,14 @@ public class BaseBundle { } finally { mWeakParcelledData = null; if (ownsParcel) { if (numLazyValues == 0) { if (numLazyValues[0] == 0) { recycleParcel(parcelledData); } else { mWeakParcelledData = new WeakReference<>(parcelledData); } } mLazyValues = numLazyValues; mLazyValues = numLazyValues[0]; mParcelledByNative = false; mMap = map; // Set field last as it is volatile Loading
core/java/android/os/Parcel.java +5 −7 Original line number Diff line number Diff line Loading @@ -5538,7 +5538,7 @@ public final class Parcel { private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal, int size, @Nullable ClassLoader loader) { readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader); readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader, null); } /** Loading @@ -5548,17 +5548,16 @@ public final class Parcel { * @param lazy Whether to populate the map with lazy {@link Function} objects for * length-prefixed values. See {@link Parcel#readLazyValue(ClassLoader)} for more * details. * @return a count of the lazy values in the map * @param lazyValueCount number of lazy values added here * @hide */ int readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader) { int lazyValues = 0; void readArrayMap(ArrayMap<? super String, Object> map, int size, boolean sorted, boolean lazy, @Nullable ClassLoader loader, int[] lazyValueCount) { while (size > 0) { String key = readString(); Object value = (lazy) ? readLazyValue(loader) : readValue(loader); if (value instanceof LazyValue) { lazyValues++; lazyValueCount[0]++; } if (sorted) { map.append(key, value); Loading @@ -5570,7 +5569,6 @@ public final class Parcel { if (sorted) { map.validate(); } return lazyValues; } /** Loading
core/java/com/android/internal/app/ChooserActivity.java +49 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK; import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE; import static android.content.ContentProvider.getUriWithoutUserId; import static android.content.ContentProvider.getUserIdFromUri; import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL; import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK; Loading @@ -40,7 +41,9 @@ import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.IUriGrantsManager; import android.app.SharedElementCallback; import android.app.UriGrantsManager; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionManager; import android.app.prediction.AppPredictor; Loading Loading @@ -77,6 +80,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.metrics.LogMaker; import android.net.Uri; import android.os.AsyncTask; Loading @@ -86,6 +90,7 @@ import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.os.PatternMatcher; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.UserHandle; import android.os.UserManager; Loading Loading @@ -692,7 +697,11 @@ public class ChooserActivity extends ResolverActivity implements targets = null; break; } targets[i] = (ChooserTarget) pa[i]; ChooserTarget chooserTarget = (ChooserTarget) pa[i]; if (!hasValidIcon(chooserTarget)) { chooserTarget = removeIcon(chooserTarget); } targets[i] = chooserTarget; } mCallerChooserTargets = targets; } Loading Loading @@ -4217,4 +4226,43 @@ public class ChooserActivity extends ResolverActivity implements private boolean shouldNearbyShareBeIncludedAsActionButton() { return !shouldNearbyShareBeFirstInRankedRow(); } private boolean hasValidIcon(ChooserTarget target) { Icon icon = target.getIcon(); if (icon == null) { return true; } if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { Uri uri = icon.getUri(); try { getUriGrantsManager().checkGrantUriPermission_ignoreNonSystem( getLaunchedFromUid(), getPackageName(), getUriWithoutUserId(uri), Intent.FLAG_GRANT_READ_URI_PERMISSION, getUserIdFromUri(uri) ); } catch (SecurityException | RemoteException e) { Log.e(TAG, "Failed to get URI permission for: " + uri, e); return false; } } return true; } private IUriGrantsManager getUriGrantsManager() { return UriGrantsManager.getService(); } private static ChooserTarget removeIcon(ChooserTarget target) { if (target == null) { return null; } return new ChooserTarget( target.getTitle(), null, target.getScore(), target.getComponentName(), target.getIntentExtras()); } }
core/java/com/android/internal/app/IntentForwarderActivity.java +19 −8 Original line number Diff line number Diff line Loading @@ -599,24 +599,35 @@ public class IntentForwarderActivity extends Activity { Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); sanitizeIntent(forwardIntent); Intent intentToCheck = forwardIntent; if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) { if (!canForwardInner(forwardIntent, sourceUserId, targetUserId, packageManager, contentResolver)) { return null; } if (forwardIntent.getSelector() != null) { intentToCheck = forwardIntent.getSelector(); sanitizeIntent(forwardIntent.getSelector()); if (!canForwardInner(forwardIntent.getSelector(), sourceUserId, targetUserId, packageManager, contentResolver)) { return null; } } return forwardIntent; } private static boolean canForwardInner(Intent intent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { if (Intent.ACTION_CHOOSER.equals(intent.getAction())) { return false; } String resolvedType = intentToCheck.resolveTypeIfNeeded(contentResolver); sanitizeIntent(intentToCheck); String resolvedType = intent.resolveTypeIfNeeded(contentResolver); try { if (packageManager.canForwardTo( intentToCheck, resolvedType, sourceUserId, targetUserId)) { return forwardIntent; intent, resolvedType, sourceUserId, targetUserId)) { return true; } } catch (RemoteException e) { Slog.e(TAG, "PackageManagerService is dead?"); } return null; return false; } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +24 −23 Original line number Diff line number Diff line Loading @@ -2951,9 +2951,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, final int transitType = info.getType(); TransitionInfo.Change pipChange = null; int closingSplitTaskId = -1; // This array tracks if we are sending stages TO_BACK in this transition. // TODO (b/349828130): Update for n apps boolean[] stagesSentToBack = new boolean[2]; // This array tracks where we are sending stages (TO_BACK/TO_FRONT) in this transition. // TODO (b/349828130): Update for n apps (needs to handle different indices than 0/1). // Also make sure having multiple changes per stage (2+ tasks in one stage) is being // handled properly. int[] stageChanges = new int[2]; for (int iC = 0; iC < info.getChanges().size(); ++iC) { final TransitionInfo.Change change = info.getChanges().get(iC); Loading Loading @@ -3016,18 +3018,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, + " with " + taskId + " before startAnimation()."); } } if (isClosingType(change.getMode()) && getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED) { // Record which stages are getting sent to back if (change.getMode() == TRANSIT_TO_BACK) { stagesSentToBack[getStageOfTask(taskId)] = true; final int stageOfTaskId = getStageOfTask(taskId); if (stageOfTaskId == STAGE_TYPE_UNDEFINED) { continue; } if (isClosingType(change.getMode())) { // (For PiP transitions) If either one of the 2 stages is closing we're assuming // we'll break split closingSplitTaskId = taskId; } if (transitType == WindowManager.TRANSIT_WAKE) { // Record which stages are receiving which changes if ((change.getMode() == TRANSIT_TO_BACK || change.getMode() == TRANSIT_TO_FRONT) && (stageOfTaskId == STAGE_TYPE_MAIN || stageOfTaskId == STAGE_TYPE_SIDE)) { stageChanges[stageOfTaskId] = change.getMode(); } } } if (pipChange != null) { Loading @@ -3052,19 +3061,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return true; } // If keyguard is active, check to see if we have our TO_BACK transitions in order. // This array should either be all false (no split stages sent to back) or all true // (all stages sent to back). In any other case (which can happen with SHOW_ABOVE_LOCKED // apps) we should break split. if (mKeyguardActive) { boolean isFirstStageSentToBack = stagesSentToBack[0]; for (boolean b : stagesSentToBack) { // Compare each boolean to the first one. If any are different, break split. if (b != isFirstStageSentToBack) { // If keyguard is active, check to see if we have all our stages showing. If one stage // was moved but not the other (which can happen with SHOW_ABOVE_LOCKED apps), we should // break split. if (mKeyguardActive && stageChanges[STAGE_TYPE_MAIN] != stageChanges[STAGE_TYPE_SIDE]) { dismissSplitKeepingLastActiveStage(EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP); break; } } } final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage(); Loading