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

Commit d24351d5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "UsageStatsService: don't create stuff directly in /data/system_de"

parents 697b47b6 e25b77c1
Loading
Loading
Loading
Loading
+40 −32
Original line number Original line Diff line number Diff line
@@ -76,7 +76,6 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.AtomicFile;
@@ -140,13 +139,26 @@ public class UsageStatsService extends SystemService implements
    private static final boolean ENABLE_KERNEL_UPDATES = true;
    private static final boolean ENABLE_KERNEL_UPDATES = true;
    private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set");
    private static final File KERNEL_COUNTER_FILE = new File("/proc/uid_procstat/set");


    private static final File USAGE_STATS_LEGACY_DIR = new File(
    // /data/system/usagestats.  Now only used for globalcomponentusage.  Previously per-user stats
            Environment.getDataSystemDirectory(), "usagestats");
    // were stored here too, but they've been moved to /data/system_ce/$userId/usagestats.
    // For migration purposes, indicates whether to keep the legacy usage stats directory or not
    private static final File COMMON_USAGE_STATS_DIR =
    private static final boolean KEEP_LEGACY_DIR = false;
            new File(Environment.getDataSystemDirectory(), "usagestats");

    private static final File LEGACY_USER_USAGE_STATS_DIR = COMMON_USAGE_STATS_DIR;
    private static final File COMMON_USAGE_STATS_DE_DIR =

    // /data/system_de/usagestats.  When the globalcomponentusage file was added, it was incorrectly
    // added here instead of in /data/system/usagestats where it should be.  We lazily migrate this
    // file by reading it from here if needed, and always writing it to the new path.  We don't
    // delete the old directory, as system_server no longer has permission to do so.
    //
    // Note, this migration is *not* related to the migration of the per-user stats from
    // /data/system/usagestats/$userId to /data/system_ce/$userId/usagestats mentioned above.  Both
    // of these just happen to involve /data/system/usagestats.  /data/system is the right place for
    // system data not tied to a user, but the wrong place for per-user data.  So due to two
    // separate mistakes, we've unfortunately ended up with one case where we need to move files out
    // of /data/system, and one case where we need to move a different file *into* /data/system.
    private static final File LEGACY_COMMON_USAGE_STATS_DIR =
            new File(Environment.getDataSystemDeDirectory(), "usagestats");
            new File(Environment.getDataSystemDeDirectory(), "usagestats");

    private static final String GLOBAL_COMPONENT_USAGE_FILE_NAME = "globalcomponentusage";
    private static final String GLOBAL_COMPONENT_USAGE_FILE_NAME = "globalcomponentusage";


    private static final char TOKEN_DELIMITER = '/';
    private static final char TOKEN_DELIMITER = '/';
@@ -630,7 +642,7 @@ public class UsageStatsService extends SystemService implements
                final int previousVersion = Integer.parseInt(reader.readLine());
                final int previousVersion = Integer.parseInt(reader.readLine());
                // UsageStatsDatabase.BACKUP_VERSION was 4 when usage stats were migrated to CE.
                // UsageStatsDatabase.BACKUP_VERSION was 4 when usage stats were migrated to CE.
                if (previousVersion >= 4) {
                if (previousVersion >= 4) {
                    deleteLegacyDir(userId);
                    deleteLegacyUserDir(userId);
                    return;
                    return;
                }
                }
                // If migration logic needs to be changed in a future version, do it here.
                // If migration logic needs to be changed in a future version, do it here.
@@ -651,7 +663,7 @@ public class UsageStatsService extends SystemService implements
        }
        }


        Slog.i(TAG, "Starting migration to system CE for user " + userId);
        Slog.i(TAG, "Starting migration to system CE for user " + userId);
        final File legacyUserDir = new File(USAGE_STATS_LEGACY_DIR, Integer.toString(userId));
        final File legacyUserDir = new File(LEGACY_USER_USAGE_STATS_DIR, Integer.toString(userId));
        if (legacyUserDir.exists()) {
        if (legacyUserDir.exists()) {
            copyRecursively(usageStatsDir, legacyUserDir);
            copyRecursively(usageStatsDir, legacyUserDir);
        }
        }
@@ -666,8 +678,8 @@ public class UsageStatsService extends SystemService implements
        }
        }
        Slog.i(TAG, "Finished migration to system CE for user " + userId);
        Slog.i(TAG, "Finished migration to system CE for user " + userId);


        // Migration was successful - delete the legacy directory
        // Migration was successful - delete the legacy user directory
        deleteLegacyDir(userId);
        deleteLegacyUserDir(userId);
    }
    }


    private static void copyRecursively(final File parent, File f) {
    private static void copyRecursively(final File parent, File f) {
@@ -698,21 +710,14 @@ public class UsageStatsService extends SystemService implements
        }
        }
    }
    }


    private void deleteLegacyDir(int userId) {
    private void deleteLegacyUserDir(int userId) {
        final File legacyUserDir = new File(USAGE_STATS_LEGACY_DIR, Integer.toString(userId));
        final File legacyUserDir = new File(LEGACY_USER_USAGE_STATS_DIR, Integer.toString(userId));
        if (!KEEP_LEGACY_DIR && legacyUserDir.exists()) {
        if (legacyUserDir.exists()) {
            deleteRecursively(legacyUserDir);
            deleteRecursively(legacyUserDir);
            if (legacyUserDir.exists()) {
            if (legacyUserDir.exists()) {
                Slog.w(TAG, "Error occurred while attempting to delete legacy usage stats "
                Slog.w(TAG, "Error occurred while attempting to delete legacy usage stats "
                        + "dir for user " + userId);
                        + "dir for user " + userId);
            }
            }
            // If all users have been migrated, delete the parent legacy usage stats directory
            if (USAGE_STATS_LEGACY_DIR.list() != null
                    && USAGE_STATS_LEGACY_DIR.list().length == 0) {
                if (!USAGE_STATS_LEGACY_DIR.delete()) {
                    Slog.w(TAG, "Error occurred while attempting to delete legacy usage stats dir");
                }
            }
        }
        }
    }
    }


@@ -807,13 +812,16 @@ public class UsageStatsService extends SystemService implements
    }
    }


    private void loadGlobalComponentUsageLocked() {
    private void loadGlobalComponentUsageLocked() {
        final File[] packageUsageFile = COMMON_USAGE_STATS_DE_DIR.listFiles(
        AtomicFile af = new AtomicFile(new File(COMMON_USAGE_STATS_DIR,
                (dir, name) -> TextUtils.equals(name, GLOBAL_COMPONENT_USAGE_FILE_NAME));
                    GLOBAL_COMPONENT_USAGE_FILE_NAME));
        if (packageUsageFile == null || packageUsageFile.length == 0) {
        if (!af.exists()) {
            af = new AtomicFile(new File(LEGACY_COMMON_USAGE_STATS_DIR,
                        GLOBAL_COMPONENT_USAGE_FILE_NAME));
            if (!af.exists()) {
                return;
                return;
            }
            }

            Slog.i(TAG, "Reading " + GLOBAL_COMPONENT_USAGE_FILE_NAME + " file from old location");
        final AtomicFile af = new AtomicFile(packageUsageFile[0]);
        }
        final Map<String, Long> tmpUsage = new ArrayMap<>();
        final Map<String, Long> tmpUsage = new ArrayMap<>();
        try {
        try {
            try (FileInputStream in = af.openRead()) {
            try (FileInputStream in = af.openRead()) {
@@ -831,7 +839,7 @@ public class UsageStatsService extends SystemService implements
            }
            }
        } catch (Exception e) {
        } catch (Exception e) {
            // Most likely trying to read a corrupted file - log the failure
            // Most likely trying to read a corrupted file - log the failure
            Slog.e(TAG, "Could not read " + packageUsageFile[0]);
            Slog.e(TAG, "Could not read " + af.getBaseFile());
        }
        }
    }
    }


@@ -840,11 +848,11 @@ public class UsageStatsService extends SystemService implements
            return;
            return;
        }
        }


        if (!COMMON_USAGE_STATS_DE_DIR.mkdirs() && !COMMON_USAGE_STATS_DE_DIR.exists()) {
        if (!COMMON_USAGE_STATS_DIR.mkdirs() && !COMMON_USAGE_STATS_DIR.exists()) {
            throw new IllegalStateException("Common usage stats DE directory does not exist: "
            throw new IllegalStateException("Common usage stats directory does not exist: "
                    + COMMON_USAGE_STATS_DE_DIR.getAbsolutePath());
                    + COMMON_USAGE_STATS_DIR.getAbsolutePath());
        }
        }
        final File lastTimePackageFile = new File(COMMON_USAGE_STATS_DE_DIR,
        final File lastTimePackageFile = new File(COMMON_USAGE_STATS_DIR,
                GLOBAL_COMPONENT_USAGE_FILE_NAME);
                GLOBAL_COMPONENT_USAGE_FILE_NAME);
        final AtomicFile af = new AtomicFile(lastTimePackageFile);
        final AtomicFile af = new AtomicFile(lastTimePackageFile);
        FileOutputStream fos = null;
        FileOutputStream fos = null;