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

Commit 8f2748b4 authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-15.0.0_r14' into staging/lineage-22.1_merge-android-15.0.0_r14

Android 15.0.0 Release 14 (AP4A.250205.002)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZ6KK3QAKCRDorT+BmrEO
# eKZHAJ9CVe4M3wCFicuSSeSJaCARqBRgmACfYuImF5Ez31W/lG4PfEJAMxtYPE0=
# =YuXc
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Feb  4 23:47:09 2025 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

# By Alex Xu (1) and others
# Via Android Build Coastguard Worker
* tag 'android-15.0.0_r14':
  Reapply "[res] Duplicate AssetManager when changes are needed"
  Clear calling identity when getting global security state
  Remove the mediaProjectionRequestAttributionFix flag
  Check permissions of URI inside of Autofill Slices
  [CDM] Check for system calling UID when backing up and restoring data

Change-Id: Ia5def04b81ed71bed46f6f78c1179501a0e94bb4
parents 95950965 d41da232
Loading
Loading
Loading
Loading
+89 −35
Original line number Diff line number Diff line
@@ -174,22 +174,58 @@ public class ResourcesManager {
    }

    /**
     * Apply the registered library paths to the passed impl object
     * @return the hash code for the current version of the registered paths
     * Apply the registered library paths to the passed AssetManager. If may create a new
     * AssetManager if any changes are needed and it isn't allowed to reuse the old one.
     *
     * @return new AssetManager and the hash code for the current version of the registered paths
     */
    public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) {
    public @NonNull Pair<AssetManager, Integer> updateResourceImplAssetsWithRegisteredLibs(
            @NonNull AssetManager assets, boolean reuseAssets) {
        if (!Flags.registerResourcePaths()) {
            return 0;
            return new Pair<>(assets, 0);
        }

        final var collector = new PathCollector(null);
        final int size = mSharedLibAssetsMap.size();
        final int size;
        final PathCollector collector;

        synchronized (mLock) {
            size = mSharedLibAssetsMap.size();
            if (assets == AssetManager.getSystem()) {
                return new Pair<>(assets, size);
            }
            collector = new PathCollector(resourcesKeyFromAssets(assets));
            for (int i = 0; i < size; i++) {
                final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey();
                collector.appendKey(libraryKey);
            }
        impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey()));
        return size;
        }
        if (collector.isSameAsOriginal()) {
            return new Pair<>(assets, size);
        }
        if (reuseAssets) {
            assets.addPresetApkKeys(extractApkKeys(collector.collectedKey()));
            return new Pair<>(assets, size);
        }
        final var newAssetsBuilder = new AssetManager.Builder().setNoInit();
        for (final var asset : assets.getApkAssets()) {
            // Skip everything that's either default, or will get added by the collector (builder
            // doesn't check for duplicates at all).
            if (asset.isSystem() || asset.isForLoader() || asset.isOverlay()
                    || asset.isSharedLib()) {
                continue;
            }
            newAssetsBuilder.addApkAssets(asset);
        }
        for (final var key : extractApkKeys(collector.collectedKey())) {
            try {
                final var asset = loadApkAssets(key);
                newAssetsBuilder.addApkAssets(asset);
            } catch (IOException e) {
                Log.e(TAG, "Couldn't load assets for key " + key, e);
            }
        }
        assets.getLoaders().forEach(newAssetsBuilder::addLoader);
        return new Pair<>(newAssetsBuilder.build(), size);
    }

    public static class ApkKey {
@@ -621,6 +657,23 @@ public class ResourcesManager {
        return apkKeys;
    }

    private ResourcesKey resourcesKeyFromAssets(@NonNull AssetManager assets) {
        final var libs = new ArrayList<String>();
        final var overlays = new ArrayList<String>();
        for (final ApkAssets asset : assets.getApkAssets()) {
            if (asset.isSystem() || asset.isForLoader()) {
                continue;
            }
            if (asset.isOverlay()) {
                overlays.add(asset.getAssetPath());
            } else if (asset.isSharedLib()) {
                libs.add(asset.getAssetPath());
            }
        }
        return new ResourcesKey(null, null, overlays.toArray(new String[0]),
                libs.toArray(new String[0]), 0, null, null);
    }

    /**
     * Creates an AssetManager from the paths within the ResourcesKey.
     *
@@ -749,7 +802,7 @@ public class ResourcesManager {

        final Configuration config = generateConfig(key);
        final DisplayMetrics displayMetrics = getDisplayMetrics(generateDisplayId(key), daj);
        final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj);
        final ResourcesImpl impl = new ResourcesImpl(assets, displayMetrics, config, daj, true);

        if (DEBUG) {
            Slog.d(TAG, "- creating impl=" + impl + " with key: " + key);
@@ -1832,7 +1885,9 @@ public class ResourcesManager {
        for (int i = 0; i < resourcesCount; i++) {
            final WeakReference<Resources> ref = mAllResourceReferences.get(i);
            final Resources r = ref != null ? ref.get() : null;
            if (r != null) {
            if (r == null) {
                continue;
            }
            final ResourcesKey key = updatedResourceKeys.get(r.getImpl());
            if (key != null) {
                final ResourcesImpl impl = findOrCreateResourcesImplForKeyLocked(key);
@@ -1845,18 +1900,17 @@ public class ResourcesManager {
                // Resources created by application through Resources constructor and was not
                // managed by ResourcesManager, so the ResourcesImpl needs to be recreated to
                // have shared library asset paths appended if there are any.
                    if (r.getImpl() != null) {
                final ResourcesImpl oldImpl = r.getImpl();
                if (oldImpl != null) {
                    final AssetManager oldAssets = oldImpl.getAssets();
                    // ResourcesImpl constructor will help to append shared library asset paths.
                        if (oldAssets != AssetManager.getSystem() && oldAssets.isUpToDate()) {
                            final ResourcesImpl newImpl = new ResourcesImpl(oldAssets,
                                    oldImpl.getMetrics(), oldImpl.getConfiguration(),
                                    oldImpl.getDisplayAdjustments());
                    if (oldAssets != AssetManager.getSystem()) {
                        if (oldAssets.isUpToDate()) {
                            final ResourcesImpl newImpl = new ResourcesImpl(oldImpl);
                            r.setImpl(newImpl);
                        } else {
                            Slog.w(TAG, "Skip appending shared library asset paths for the "
                                    + "Resource as its assets are not up to date.");
                            Slog.w(TAG, "Skip appending shared library asset paths for "
                                    + "the Resources as its assets are not up to date.");
                        }
                    }
                }
+25 −8
Original line number Diff line number Diff line
@@ -124,11 +124,13 @@ public final class ApkAssets {

    @Nullable
    @GuardedBy("this")
    private final StringBlock mStringBlock;  // null or closed if mNativePtr = 0.
    private StringBlock mStringBlock;  // null or closed if mNativePtr = 0.

    @PropertyFlags
    private final int mFlags;

    private final boolean mIsOverlay;

    @Nullable
    private final AssetsProvider mAssets;

@@ -302,40 +304,43 @@ public final class ApkAssets {

    private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        this(format, flags, assets);
        Objects.requireNonNull(path, "path");
        mFlags = flags;
        mNativePtr = nativeLoad(format, path, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd,
            @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets)
            throws IOException {
        this(format, flags, assets);
        Objects.requireNonNull(fd, "fd");
        Objects.requireNonNull(friendlyName, "friendlyName");
        mFlags = flags;
        mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd,
            @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        this(format, flags, assets);
        Objects.requireNonNull(fd, "fd");
        Objects.requireNonNull(friendlyName, "friendlyName");
        mFlags = flags;
        mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) {
        mFlags = flags;
        this(FORMAT_APK, flags, assets);
        mNativePtr = nativeLoadEmpty(flags, assets);
        mStringBlock = null;
    }

    private ApkAssets(@FormatType int format, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) {
        mFlags = flags;
        mAssets = assets;
        mIsOverlay = format == FORMAT_IDMAP;
    }

    @UnsupportedAppUsage
@@ -425,6 +430,18 @@ public final class ApkAssets {
        }
    }

    public boolean isSystem() {
        return (mFlags & PROPERTY_SYSTEM) != 0;
    }

    public boolean isSharedLib() {
        return (mFlags & PROPERTY_DYNAMIC) != 0;
    }

    public boolean isOverlay() {
        return mIsOverlay;
    }

    @Override
    public String toString() {
        return "ApkAssets{path=" + getDebugName() + "}";
+19 −3
Original line number Diff line number Diff line
@@ -203,9 +203,25 @@ public class ResourcesImpl {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics,
            @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) {
        mAssets = assets;
        mAppliedSharedLibsHash =
                ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this);
        // Don't reuse assets by default as we have no control over whether they're already
        // inside some other ResourcesImpl.
        this(assets, metrics, config, displayAdjustments, false);
    }

    public ResourcesImpl(@NonNull ResourcesImpl orig) {
        // We know for sure that the other assets are in use, so can't reuse the object here.
        this(orig.getAssets(), orig.getMetrics(), orig.getConfiguration(),
                orig.getDisplayAdjustments(), false);
    }

    public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics,
            @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments,
            boolean reuseAssets) {
        final var assetsAndHash =
                ResourcesManager.getInstance().updateResourceImplAssetsWithRegisteredLibs(assets,
                        reuseAssets);
        mAssets = assetsAndHash.first;
        mAppliedSharedLibsHash = assetsAndHash.second;
        mMetrics.setToDefaults();
        mDisplayAdjustments = displayAdjustments;
        mConfiguration.setToDefaults();
+8 −5
Original line number Diff line number Diff line
@@ -123,11 +123,14 @@ public class MediaProjectionPermissionActivity extends Activity {
        mReviewGrantedConsentRequired = launchingIntent.getBooleanExtra(
                EXTRA_USER_REVIEW_GRANTED_CONSENT, false);

        mPackageName = getCallingPackage();

        // This activity is launched directly by an app, or system server. System server provides
        // the package name through the intent if so.
        if (mPackageName == null) {
        // The original requester of this activity start
        mPackageName = getLaunchedFromPackage();

        // This activity is launched directly by using startActivity(),
        // thus getCallingPackage() will be null.
        if (getCallingPackage() == null) {
            // System server provides the package name through the intent if so and is able to get
            // the result back. Other applications can't.
            if (launchingIntent.hasExtra(EXTRA_PACKAGE_REUSING_GRANTED_CONSENT)) {
                mPackageName = launchingIntent.getStringExtra(
                        EXTRA_PACKAGE_REUSING_GRANTED_CONSENT);
+50 −5
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@ import android.app.ActivityManager;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
import android.app.slice.Slice;
import android.app.slice.SliceItem;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.hardware.display.DisplayManager;
import android.metrics.LogMaker;
import android.os.UserHandle;
@@ -97,8 +100,9 @@ public final class Helper {
            @UserIdInt int userId, @NonNull RemoteViews rView) {
        final AtomicBoolean permissionsOk = new AtomicBoolean(true);

        rView.visitUris(uri -> {
            int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri);
        rView.visitUris(
                uri -> {
                    int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri, userId);
                    boolean allowed = uriOwnerId == userId;
                    permissionsOk.set(allowed & permissionsOk.get());
                });
@@ -150,6 +154,47 @@ public final class Helper {
        return (ok ? rView : null);
    }

    /**
     * Checks the URI permissions of the icon in the slice, to see if the current userId is able to
     * access it.
     *
     * <p>Returns null if slice contains user inaccessible icons
     *
     * <p>TODO: instead of returning a null Slice when the current userId cannot access an icon,
     * return a reconstructed Slice without the icons. This is currently non-trivial since there are
     * no public methods to generically add SliceItems to Slices
     */
    public static @Nullable Slice sanitizeSlice(Slice slice) {
        if (slice == null) {
            return null;
        }

        int userId = ActivityManager.getCurrentUser();

        // Recontruct the Slice, filtering out bad icons
        for (SliceItem sliceItem : slice.getItems()) {
            if (!sliceItem.getFormat().equals(SliceItem.FORMAT_IMAGE)) {
                // Not an image slice
                continue;
            }

            Icon icon = sliceItem.getIcon();
            if (icon.getType() != Icon.TYPE_URI
                    && icon.getType() != Icon.TYPE_URI_ADAPTIVE_BITMAP) {
                // No URIs to sanitize
                continue;
            }

            int iconUriId = android.content.ContentProvider.getUserIdFromUri(icon.getUri(), userId);

            if (iconUriId != userId) {
                Slog.w(TAG, "sanitizeSlice() user: " + userId + " cannot access icons in Slice");
                return null;
            }
        }

        return slice;
    }

    @Nullable
    static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) {
Loading