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

Commit 212f61cf authored by felkachang's avatar felkachang Committed by Felka Chang
Browse files

Add a new function in ResourcesProvider for SelfTargeting

This patch adds a new function to load a SelfTargeting overlay to be
a ResourcesProvider instance. If the app wants to overlay itself’s
resources, the first step is to call this new function to get a
ResourcesProvider instance and then add the ResourcesProvider in a
ResourcesLoader instance.
* ResourcesProvider#loadOverlay

Test: atest \
          OverlayHostTests \
          OverlayDeviceTests \
          SelfTargetingOverlayDeviceTests \
          OverlayRemountedTest \
          FrameworksServicesTests:com.android.server.om \
          CtsContentTestCases:android.content.om.cts \
          CtsContentTestCases:android.content.res.loader.cts \
          idmap2_tests

Bug: 205919743
Change-Id: Id54da44a54ee6cbc685ad486d1bf69ef388c33ae
parent d743e023
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -18,7 +18,10 @@ package android.content.res.loader;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
import android.content.pm.ApplicationInfo;
import android.content.res.ApkAssets;
import android.content.res.AssetFileDescriptor;
@@ -27,11 +30,17 @@ import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.om.OverlayManagerImpl;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

/**
 * Provides methods to load resources data from APKs ({@code .apk}) and resources tables
@@ -62,6 +71,48 @@ public class ResourcesProvider implements AutoCloseable, Closeable {
                assetsProvider));
    }

    /**
     * Creates a ResourcesProvider instance from the specified overlay information.
     *
     * <p>In order to enable the registered overlays, an application can create a {@link
     * ResourcesProvider} instance according to the specified {@link OverlayInfo} instance and put
     * them into a {@link ResourcesLoader} instance. The application calls {@link
     * android.content.res.Resources#addLoaders(ResourcesLoader...)} to load the overlays.
     *
     * @param overlayInfo is the information about the specified overlay
     * @return the resources provider instance for the {@code overlayInfo}
     * @throws IOException when the files can't be loaded.
     * @see OverlayManager#getOverlayInfosForTarget(String) to get the list of overlay info.
     * @hide
     */
    @SuppressLint("WrongConstant") // TODO(b/238713267): ApkAssets blocks PROPERTY_LOADER
    @NonNull
    public static ResourcesProvider loadOverlay(@NonNull OverlayInfo overlayInfo)
            throws IOException {
        Objects.requireNonNull(overlayInfo);
        Preconditions.checkArgument(overlayInfo.isFabricated(), "Not accepted overlay");
        Preconditions.checkStringNotEmpty(
                overlayInfo.getTargetOverlayableName(), "Without overlayable name");
        final String overlayName =
                OverlayManagerImpl.checkOverlayNameValid(overlayInfo.getOverlayName());
        final String path =
                Preconditions.checkStringNotEmpty(
                        overlayInfo.getBaseCodePath(), "Invalid base path");

        final Path frroPath = Path.of(path);
        if (!Files.isRegularFile(frroPath)) {
            throw new FileNotFoundException("The frro file not found");
        }
        final Path idmapPath = frroPath.getParent().resolve(overlayName + ".idmap");
        if (!Files.isRegularFile(idmapPath)) {
            throw new FileNotFoundException("The idmap file not found");
        }

        return new ResourcesProvider(
                ApkAssets.loadOverlayFromPath(
                        idmapPath.toString(), 0 /* flags: self targeting overlay */));
    }

    /**
     * Creates a ResourcesProvider from an APK ({@code .apk}) file descriptor.
     *