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

Commit 00166731 authored by Christopher Tate's avatar Christopher Tate Committed by Android (Google) Code Review
Browse files

Merge "Don't restore wildly wrong sized wallpapers"

parents a3ae4a06 3f64f8d8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ class FileBackupHelperBase {
        }
    }

    void writeFile(File f, BackupDataInputStream in) {
    boolean writeFile(File f, BackupDataInputStream in) {
        int result = -1;

        // Create the enclosing directory.
@@ -98,6 +98,7 @@ class FileBackupHelperBase {
                mExceptionLogged = true;
            }
        }
        return (result == 0);
    }

    public void writeNewStateDescription(ParcelFileDescriptor fd) {
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.backup;

import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.ParcelFileDescriptor;
import android.util.Slog;

import java.io.File;

/**
 * Helper for backing up / restoring wallpapers.  Basically an AbsoluteFileBackupHelper,
 * but with logic for deciding what to do with restored wallpaper images.
 *
 * @hide
 */
public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
    private static final String TAG = "WallpaperBackupHelper";
    private static final boolean DEBUG = false;

    // This path must match what the WallpaperManagerService uses
    private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";

    // Stage file - should be adjacent to the WALLPAPER_IMAGE location.  The wallpapers
    // will be saved to this file from the restore stream, then renamed to the proper
    // location if it's deemed suitable.
    private static final String STAGE_FILE = "/data/data/com.android.settings/files/wallpaper-tmp";

    Context mContext;
    String[] mFiles;
    double mDesiredMinWidth;
    double mDesiredMinHeight;

    /**
     * Construct a helper for backing up / restoring the files at the given absolute locations
     * within the file system.
     *
     * @param context
     * @param files
     */
    public WallpaperBackupHelper(Context context, String... files) {
        super(context);

        mContext = context;
        mFiles = files;

        WallpaperManager wpm;
        wpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
        mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth();
        mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
    }

    /**
     * Based on oldState, determine which of the files from the application's data directory
     * need to be backed up, write them to the data stream, and fill in newState with the
     * state as it exists now.
     */
    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
            ParcelFileDescriptor newState) {
        performBackup_checked(oldState, data, newState, mFiles, mFiles);
    }

    /**
     * Restore one absolute file entity from the restore stream.  If we're restoring the
     * magic wallpaper file, take specific action to determine whether it is suitable for
     * the current device.
     */
    public void restoreEntity(BackupDataInputStream data) {
        final String key = data.getKey();
        if (isKeyInList(key, mFiles)) {
            if (key.equals(WALLPAPER_IMAGE)) {
                // restore the file to the stage for inspection
                File f = new File(STAGE_FILE);
                if (writeFile(f, data)) {

                    // Preflight the restored image's dimensions without loading it
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(STAGE_FILE, options);

                    if (DEBUG) Slog.v(TAG, "Restoring wallpaper image w=" + options.outWidth
                            + " h=" + options.outHeight);

                    // how much does the image differ from our preference?
                    double widthRatio = mDesiredMinWidth / options.outWidth;
                    double heightRatio = mDesiredMinHeight / options.outHeight;
                    if (widthRatio > 0.8 && widthRatio < 1.25
                            && heightRatio > 0.8 && heightRatio < 1.25) {
                        // sufficiently close to our resolution; go ahead and use it
                        if (DEBUG) Slog.v(TAG, "wallpaper dimension match; using");
                        f.renameTo(new File(WALLPAPER_IMAGE));
                        // TODO: spin a service to copy the restored image to sd/usb storage,
                        // since it does not exist anywhere other than the private wallpaper
                        // file.
                    } else {
                        if (DEBUG) Slog.v(TAG, "dimensions too far off: wr=" + widthRatio
                                + " hr=" + heightRatio);
                        f.delete();
                    }
                }
            } else {
                // Some other normal file; just decode it to its destination
                File f = new File(key);
                writeFile(f, data);
            }
        }
    }
}
+6 −9
Original line number Diff line number Diff line
@@ -16,18 +16,16 @@

package com.android.server;

import android.app.backup.AbsoluteFileBackupHelper;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataInputStream;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupHelper;
import android.app.backup.BackupAgentHelper;
import android.app.backup.WallpaperBackupHelper;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.ServiceManager;
import android.os.SystemService;
import android.util.Slog;


import java.io.File;
import java.io.IOException;

@@ -54,7 +52,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
            // TODO: Send a delete for any stored wallpaper image in this case?
            files = new String[] { WALLPAPER_INFO };
        }
        addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this, files));
        addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files));
        super.onBackup(oldState, data, newState);
    }

@@ -62,12 +60,11 @@ public class SystemBackupAgent extends BackupAgentHelper {
    public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
            throws IOException {
        // On restore, we also support a previous data schema "system_files"
        addHelper("wallpaper", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
        addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this,
                new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }));
        addHelper("system_files", new AbsoluteFileBackupHelper(SystemBackupAgent.this,
        addHelper("system_files", new WallpaperBackupHelper(SystemBackupAgent.this,
                new String[] { WALLPAPER_IMAGE }));

        boolean success = false;
        try {
            super.onRestore(data, appVersionCode, newState);

@@ -75,7 +72,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
                    Context.WALLPAPER_SERVICE);
            wallpaper.settingsRestored();
        } catch (IOException ex) {
            // If there was a failure, delete everything for the wallpaper, this is too aggresive,
            // If there was a failure, delete everything for the wallpaper, this is too aggressive,
            // but this is hopefully a rare failure.
            Slog.d(TAG, "restore failed", ex);
            (new File(WALLPAPER_IMAGE)).delete();