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

Commit 99ca2b79 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/26436890'] into 24Q2-release.

Change-Id: Idc1c033ed43c9804584587772d958cb7392f74d5
parents 2775f170 62d842f5
Loading
Loading
Loading
Loading
+1 −229
Original line number Diff line number Diff line
@@ -39,9 +39,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -51,22 +49,16 @@ import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Xml;
import android.view.Display;
import android.view.DisplayInfo;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
@@ -110,9 +102,6 @@ public class WallpaperBackupAgent extends BackupAgent {
    @VisibleForTesting
    static final String WALLPAPER_INFO_STAGE = "wallpaper-info-stage";

    @VisibleForTesting
    static final String WALLPAPER_BACKUP_DEVICE_INFO_STAGE = "wallpaper-backup-device-info-stage";

    static final String EMPTY_SENTINEL = "empty";
    static final String QUOTA_SENTINEL = "quota";

@@ -121,11 +110,6 @@ public class WallpaperBackupAgent extends BackupAgent {
    static final String SYSTEM_GENERATION = "system_gen";
    static final String LOCK_GENERATION = "lock_gen";

    /**
     * An approximate area threshold to compare device dimension similarity
     */
    static final int AREA_THRESHOLD = 50; // TODO: determine appropriate threshold

    // If this file exists, it means we exceeded our quota last time
    private File mQuotaFile;
    private boolean mQuotaExceeded;
@@ -137,8 +121,6 @@ public class WallpaperBackupAgent extends BackupAgent {
    private boolean mSystemHasLiveComponent;
    private boolean mLockHasLiveComponent;

    private DisplayManager mDisplayManager;

    @Override
    public void onCreate() {
        if (DEBUG) {
@@ -155,8 +137,6 @@ public class WallpaperBackupAgent extends BackupAgent {

        mBackupManager = new BackupManager(getBaseContext());
        mEventLogger = new WallpaperEventLogger(mBackupManager, /* wallpaperAgent */ this);

        mDisplayManager = getSystemService(DisplayManager.class);
    }

    @Override
@@ -195,7 +175,6 @@ public class WallpaperBackupAgent extends BackupAgent {
            mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null;
            mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null;

            backupDeviceInfoFile(data);
            backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data);
            backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data);
            backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data);
@@ -212,50 +191,6 @@ public class WallpaperBackupAgent extends BackupAgent {
        }
    }

    /**
     * This method backs up the device dimension information. The device data will always get
     * overwritten when triggering a backup
     */
    private void backupDeviceInfoFile(FullBackupDataOutput data)
            throws IOException {
        final File deviceInfoStage = new File(getFilesDir(), WALLPAPER_BACKUP_DEVICE_INFO_STAGE);

        // save the dimensions of the device with xml formatting
        Point dimensions = getScreenDimensions();
        Point secondaryDimensions = getRealSize(getSmallerDisplay());

        deviceInfoStage.createNewFile();
        FileOutputStream fstream = new FileOutputStream(deviceInfoStage, false);
        TypedXmlSerializer out = Xml.resolveSerializer(fstream);
        out.startDocument(null, true);
        out.startTag(null, "dimensions");

        out.startTag(null, "width");
        out.text(String.valueOf(dimensions.x));
        out.endTag(null, "width");

        out.startTag(null, "height");
        out.text(String.valueOf(dimensions.y));
        out.endTag(null, "height");

        out.startTag(null, "secondarywidth");
        out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.x : 0));
        out.endTag(null, "secondarywidth");

        out.startTag(null, "secondaryheight");
        out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.y : 0));
        out.endTag(null, "secondaryheight");

        out.endTag(null, "dimensions");
        out.endDocument();
        fstream.flush();
        FileUtils.sync(fstream);
        fstream.close();

        if (DEBUG) Slog.v(TAG, "Storing device dimension data");
        backupFile(deviceInfoStage, data);
    }

    private void backupWallpaperInfoFile(boolean sysOrLockChanged, FullBackupDataOutput data)
            throws IOException {
        final ParcelFileDescriptor wallpaperInfoFd = mWallpaperManager.getWallpaperInfoFile();
@@ -429,22 +364,9 @@ public class WallpaperBackupAgent extends BackupAgent {
        final File infoStage = new File(filesDir, WALLPAPER_INFO_STAGE);
        final File imageStage = new File(filesDir, SYSTEM_WALLPAPER_STAGE);
        final File lockImageStage = new File(filesDir, LOCK_WALLPAPER_STAGE);
        final File deviceDimensionsStage = new File(filesDir, WALLPAPER_BACKUP_DEVICE_INFO_STAGE);
        boolean lockImageStageExists = lockImageStage.exists();

        try {
            // Parse the device dimensions of the source device and compare with target to
            // to identify whether we need to skip the remainder of the restore process
            Pair<Point, Point> sourceDeviceDimensions = parseDeviceDimensions(
                    deviceDimensionsStage);

            Point targetDeviceDimensions = getScreenDimensions();
            if (sourceDeviceDimensions != null
                    && isSourceDeviceSignificantlySmallerThanTarget(sourceDeviceDimensions.first,
                    targetDeviceDimensions)) {
                Slog.d(TAG, "The source device is significantly smaller than target");
            }

            // First parse the live component name so that we know for logging if we care about
            // logging errors with the image restore.
            ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
@@ -478,7 +400,6 @@ public class WallpaperBackupAgent extends BackupAgent {
            infoStage.delete();
            imageStage.delete();
            lockImageStage.delete();
            deviceDimensionsStage.delete();

            SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
            prefs.edit()
@@ -488,66 +409,6 @@ public class WallpaperBackupAgent extends BackupAgent {
        }
    }

    /**
     * This method parses the given file for the backed up device dimensions
     *
     * @param deviceDimensions the file which holds the device dimensions
     * @return the backed up device dimensions
     */
    private Pair<Point, Point> parseDeviceDimensions(File deviceDimensions) {
        int width = 0, height = 0, secondaryHeight = 0, secondaryWidth = 0;
        try {
            TypedXmlPullParser parser = Xml.resolvePullParser(
                    new FileInputStream(deviceDimensions));

            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }

                String name = parser.getName();

                switch (name) {
                    case "width":
                        String widthText = readText(parser);
                        width = Integer.valueOf(widthText);
                        break;

                    case "height":
                        String textHeight = readText(parser);
                        height = Integer.valueOf(textHeight);
                        break;

                    case "secondarywidth":
                        String secondaryWidthText = readText(parser);
                        secondaryWidth = Integer.valueOf(secondaryWidthText);
                        break;

                    case "secondaryheight":
                        String secondaryHeightText = readText(parser);
                        secondaryHeight = Integer.valueOf(secondaryHeightText);
                        break;
                    default:
                        break;
                }
            }
            return new Pair<>(new Point(width, height), new Point(secondaryWidth, secondaryHeight));

        } catch (Exception e) {
            return null;
        }
    }

    private static String readText(TypedXmlPullParser parser)
            throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }

    @VisibleForTesting
    void updateWallpaperComponent(ComponentName wpService, int which)
            throws IOException {
@@ -639,7 +500,6 @@ public class WallpaperBackupAgent extends BackupAgent {
            mEventLogger.onLockImageWallpaperRestoreFailed(error);
        }
    }

    private Rect parseCropHint(File wallpaperInfo, String sectionTag) {
        Rect cropHint = new Rect();
        try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
@@ -831,94 +691,6 @@ public class WallpaperBackupAgent extends BackupAgent {
        };
    }

    /**
     * This method retrieves the dimensions of the largest display of the device
     *
     * @return a @{Point} object that contains the dimensions of the largest display on the device
     */
    private Point getScreenDimensions() {
        Point largetDimensions = null;
        int maxArea = 0;

        for (Display display : getInternalDisplays()) {
            Point displaySize = getRealSize(display);

            int width = displaySize.x;
            int height = displaySize.y;
            int area = width * height;

            if (area > maxArea) {
                maxArea = area;
                largetDimensions = displaySize;
            }
        }

        return largetDimensions;
    }

    private Point getRealSize(Display display) {
        DisplayInfo displayInfo = new DisplayInfo();
        display.getDisplayInfo(displayInfo);
        return new Point(displayInfo.logicalWidth, displayInfo.logicalHeight);
    }

    /**
     * This method returns the smaller display on a multi-display device
     *
     * @return Display that corresponds to the smaller display on a device or null if ther is only
     * one Display on a device
     */
    private Display getSmallerDisplay() {
        List<Display> internalDisplays = getInternalDisplays();
        Point largestDisplaySize = getScreenDimensions();

        // Find the first non-matching internal display
        for (Display display : internalDisplays) {
            Point displaySize = getRealSize(display);
            if (displaySize.x != largestDisplaySize.x || displaySize.y != largestDisplaySize.y) {
                return display;
            }
        }

        // If no smaller display found, return null, as there is only a single display
        return null;
    }

    /**
     * This method retrieves the collection of Display objects available in the device.
     * i.e. non-external displays are ignored
     *
     * @return list of displays corresponding to each display in the device
     */
    private List<Display> getInternalDisplays() {
        Display[] allDisplays = mDisplayManager.getDisplays(
                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);

        List<Display> internalDisplays = new ArrayList<>();
        for (Display display : allDisplays) {
            if (display.getType() == Display.TYPE_INTERNAL) {
                internalDisplays.add(display);
            }
        }
        return internalDisplays;
    }

    /**
     * This method compares the source and target dimensions, and returns true if there is a
     * significant difference in area between them and the source dimensions are smaller than the
     * target dimensions.
     *
     * @param sourceDimensions is the dimensions of the source device
     * @param targetDimensions is the dimensions of the target device
     */
    @VisibleForTesting
    boolean isSourceDeviceSignificantlySmallerThanTarget(Point sourceDimensions,
            Point targetDimensions) {
        int rawAreaDelta = (targetDimensions.x * targetDimensions.y)
                - (sourceDimensions.x * sourceDimensions.y);
        return rawAreaDelta > AREA_THRESHOLD;
    }

    @VisibleForTesting
    boolean isDeviceInRestore() {
        try {
+2 −23
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
@@ -841,26 +840,6 @@ public class WallpaperBackupAgentTest {
        testParseCropHints(testMap);
    }

    @Test
    public void test_sourceDimensionsAreLargerThanTarget() {
        // source device is larger than target, expecting to get false
        Point sourceDimensions = new Point(2208, 1840);
        Point targetDimensions = new Point(1080, 2092);
        boolean isSourceSmaller = mWallpaperBackupAgent
                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
        assertThat(isSourceSmaller).isEqualTo(false);
    }

    @Test
    public void test_sourceDimensionsMuchSmallerThanTarget() {
        // source device is smaller than target, expecting to get true
        Point sourceDimensions = new Point(1080, 2092);
        Point targetDimensions = new Point(2208, 1840);
        boolean isSourceSmaller = mWallpaperBackupAgent
                .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions);
        assertThat(isSourceSmaller).isEqualTo(true);
    }

    private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception {
        assumeTrue(multiCrop());
        mockRestoredStaticWallpaperFile(testMap);