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

Commit c1702045 authored by Ritesh Reddy's avatar Ritesh Reddy Committed by Android (Google) Code Review
Browse files

Merge "UsageStatsBackup Bug Fix"

parents 25222f55 e35ae5cc
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -2,11 +2,8 @@ package com.android.server.backup;


import android.app.backup.BlobBackupHelper;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;

@@ -26,7 +23,7 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
    static final int BLOB_VERSION = 1;

    // Key under which the payload blob is stored
    // same as UsageStatsBackupHelperAssistant.KEY_USAGE_STATS
    // same as UsageStatsDatabase.KEY_USAGE_STATS
    static final String KEY_USAGE_STATS = "usage_stats";

    public UsageStatsBackupHelper(Context context) {
@@ -36,7 +33,8 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
    @Override
    protected byte[] getBackupPayload(String key) {
        if (KEY_USAGE_STATS.equals(key)) {
            UsageStatsManagerInternal localUsageStatsManager = LocalServices.getService(UsageStatsManagerInternal.class);
            UsageStatsManagerInternal localUsageStatsManager =
                    LocalServices.getService(UsageStatsManagerInternal.class);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream out  = new DataOutputStream(baos);
            try {
@@ -55,12 +53,13 @@ public class UsageStatsBackupHelper extends BlobBackupHelper {
    @Override
    protected void applyRestoredPayload(String key, byte[] payload)  {
        if (KEY_USAGE_STATS.equals(key)) {
            UsageStatsManagerInternal localUsageStatsManager = LocalServices.getService(UsageStatsManagerInternal.class);
            UsageStatsManagerInternal localUsageStatsManager =
                    LocalServices.getService(UsageStatsManagerInternal.class);
            DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
            try {
                int user = in.readInt();
                byte[] restoreData = new byte[payload.length - 4];
                in.read(restoreData, 0, payload.length-4);
                in.read(restoreData, 0, restoreData.length);
                localUsageStatsManager.applyRestoredPayload(user, key, restoreData);
            } catch (IOException ioe) {
                if (DEBUG) Log.e(TAG, "Failed to restore Usage Stats", ioe);
+60 −39
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.usage;

import android.app.usage.TimeSparseArray;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.os.Build;
import android.util.AtomicFile;
@@ -45,7 +44,7 @@ class UsageStatsDatabase {
    private static final int CURRENT_VERSION = 3;

    // Current version of the backup schema
    static final int BACKUP_STATE_VERSION = 1;
    static final int BACKUP_VERSION = 1;

    // Key under which the payload blob is stored
    // same as UsageStatsBackupHelper.KEY_USAGE_STATS
@@ -536,6 +535,7 @@ class UsageStatsDatabase {
     * Update the stats in the database. They may not be written to disk immediately.
     */
    public void putUsageStats(int intervalType, IntervalStats stats) throws IOException {
        if (stats == null) return;
        synchronized (mLock) {
            if (intervalType < 0 || intervalType >= mIntervalDirs.length) {
                throw new IllegalArgumentException("Bad interval type " + intervalType);
@@ -555,33 +555,41 @@ class UsageStatsDatabase {


    /* Backup/Restore Code */
    protected byte[] getBackupPayload(String key){
    byte[] getBackupPayload(String key) {
        synchronized (mLock) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            if (KEY_USAGE_STATS.equals(key)) {
                prune(System.currentTimeMillis());
                DataOutputStream out = new DataOutputStream(baos);
                try {
                    out.writeInt(BACKUP_STATE_VERSION);
                    out.writeInt(BACKUP_VERSION);

                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size());
                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size(); i++){
                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].valueAt(i));
                    for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size();
                            i++) {
                        writeIntervalStatsToStream(out,
                                mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].valueAt(i));
                    }

                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size());
                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size(); i++){
                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].valueAt(i));
                    for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size();
                            i++) {
                        writeIntervalStatsToStream(out,
                                mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].valueAt(i));
                    }

                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size());
                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size(); i++){
                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].valueAt(i));
                    for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size();
                            i++) {
                        writeIntervalStatsToStream(out,
                                mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].valueAt(i));
                    }

                    out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size());
                    for(int i = 0; i<mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size(); i++){
                        writeIntervalStatsToStream(out, mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].valueAt(i));
                    for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size();
                            i++) {
                        writeIntervalStatsToStream(out,
                                mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].valueAt(i));
                    }
                    if (DEBUG) Slog.i(TAG, "Written " + baos.size() + " bytes of data");
                } catch (IOException ioe) {
@@ -594,22 +602,31 @@ class UsageStatsDatabase {

    }

    protected void applyRestoredPayload(String key, byte[] payload){
    void applyRestoredPayload(String key, byte[] payload) {
        synchronized (mLock) {
            if (KEY_USAGE_STATS.equals(key)) {
                // Read stats files for the current device configs
                IntervalStats dailyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_DAILY);
                IntervalStats weeklyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_WEEKLY);
                IntervalStats monthlyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_MONTHLY);
                IntervalStats yearlyConfigSource = getLatestUsageStats(UsageStatsManager.INTERVAL_YEARLY);
                IntervalStats dailyConfigSource =
                        getLatestUsageStats(UsageStatsManager.INTERVAL_DAILY);
                IntervalStats weeklyConfigSource =
                        getLatestUsageStats(UsageStatsManager.INTERVAL_WEEKLY);
                IntervalStats monthlyConfigSource =
                        getLatestUsageStats(UsageStatsManager.INTERVAL_MONTHLY);
                IntervalStats yearlyConfigSource =
                        getLatestUsageStats(UsageStatsManager.INTERVAL_YEARLY);

                try {
                    DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
                    int backupDataVersion = in.readInt();

                    // Can't handle this backup set
                    if (backupDataVersion < 1 || backupDataVersion > BACKUP_VERSION) return;

                    // Delete all stats files
                    // Do this after reading version and before actually restoring
                    for (int i = 0; i < mIntervalDirs.length; i++) {
                        deleteDirectoryContents(mIntervalDirs[i]);
                    }
                try {
                    DataInputStream in = new DataInputStream(new ByteArrayInputStream(payload));
                    int stateVersion = in.readInt();

                    int fileCount = in.readInt();
                    for (int i = 0; i < fileCount; i++) {
@@ -641,8 +658,7 @@ class UsageStatsDatabase {
                    if (DEBUG) Slog.i(TAG, "Completed Restoring UsageStats");
                } catch (IOException ioe) {
                    Slog.d(TAG, "Failed to read data from input stream", ioe);
                }
                finally {
                } finally {
                    indexFilesLocked();
                }
            }
@@ -654,13 +670,16 @@ class UsageStatsDatabase {
     * with the backed up usage statistics.
     */
    private IntervalStats mergeStats(IntervalStats beingRestored, IntervalStats onDevice) {
        if (onDevice == null) return beingRestored;
        if (beingRestored == null) return null;
        beingRestored.activeConfiguration = onDevice.activeConfiguration;
        beingRestored.configurations.putAll(onDevice.configurations);
        beingRestored.events = onDevice.events;
        return beingRestored;
    }

    private void writeIntervalStatsToStream(DataOutputStream out, AtomicFile statsFile) throws IOException{
    private void writeIntervalStatsToStream(DataOutputStream out, AtomicFile statsFile)
            throws IOException {
        IntervalStats stats = new IntervalStats();
        try {
            UsageStatsXml.read(statsFile, stats);
@@ -725,6 +744,7 @@ class UsageStatsDatabase {

    private static void deleteDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (!file.isDirectory()) {
                    file.delete();
@@ -732,6 +752,7 @@ class UsageStatsDatabase {
                    deleteDirectory(file);
                }
            }
        }
        directory.delete();
    }
}
 No newline at end of file