Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 5f1e902f authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-15.0.0_r26' into staging/lineage-22.2_merge-android-15.0.0_r26

Android 15.0.0 release 26

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZ/gLKgAKCRDorT+BmrEO
# ePy+AJ41aybrLxUYmS6N+fq9uMcMvWV7OwCdEwXfM/8LtceV5/3nQCchfeeFGoQ=
# =f/vh
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu Apr 10 21:17:14 2025 EEST
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

* tag 'android-15.0.0_r26':
  Fix the race in per display brightness overrides.
  Revert "Check sound Uri permission when creating a notification channel"
  Revert "Cleanup flag for notification sound Uri permission check"
  Revert "Check sound Uri permission when creating a notification channel"
  Revert "Cleanup flag for notification sound Uri permission check"
  Revert "Check sound Uri permission when creating a notification channel"
  Revert "Cleanup flag for notification sound Uri permission check"
  [OOBE] Add corruptionHandler to handle file corruption
  Update smartspace visibility to correct target during clock size transition
  Wait for TIS cleanup after unbind before binding again
  Fix SHOW_WHEN_LOCKED splitscreen bug
  [Contextual Edu] Add corruptionHandler to handle file corruption
  Disable "Developer options" by default for managed profiles.
  Check underlying intent as well as intent selector
  Update ActivityRecordInputSink using the pending transaction
  Do not allow non-system apps to provide unverified attributions
  BaseBundle: fix unparcel error logic
  Cleanup flag for notification sound Uri permission check
  Verify that the caller has permissions for the icons it provided.
  Fix: Block opening any apps on keyguard without user auth

 Conflicts:
	services/core/java/com/android/server/wm/RootWindowContainer.java

Change-Id: Ib80c4c6dc9f48c067fa91bbb8cb6a07b8d3fdee1
parents ead9375f 54642d14
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -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);
@@ -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
+5 −7
Original line number Diff line number Diff line
@@ -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);
    }

    /**
@@ -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);
@@ -5570,7 +5569,6 @@ public final class Parcel {
        if (sorted) {
            map.validate();
        }
        return lazyValues;
    }

    /**
+49 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
        }
@@ -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());
    }
}
+19 −8
Original line number Diff line number Diff line
@@ -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;
    }

    /**
+24 −23
Original line number Diff line number Diff line
@@ -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);
@@ -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) {
@@ -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