Loading core/java/com/android/internal/os/BatteryUsageStatsStore.java +46 −21 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Handler; import android.util.AtomicFile; import android.util.Log; import android.util.LongArray; import android.util.Slog; import android.util.TypedXmlPullParser; Loading @@ -47,6 +48,7 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import java.util.concurrent.locks.ReentrantLock; /** * A storage mechanism for BatteryUsageStats snapshots. Loading @@ -73,6 +75,8 @@ public class BatteryUsageStatsStore { private boolean mSystemReady; private final File mStoreDir; private final File mLockFile; private final ReentrantLock mFileLock = new ReentrantLock(); private FileLock mJvmLock; private final AtomicFile mConfigFile; private final long mMaxStorageBytes; private final Handler mHandler; Loading Loading @@ -120,11 +124,11 @@ public class BatteryUsageStatsStore { } private void storeBatteryUsageStats(BatteryUsageStats stats) { try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { if (!mStoreDir.exists()) { if (!mStoreDir.mkdirs()) { Slog.e(TAG, "Could not create a directory for battery usage stats snapshots"); Slog.e(TAG, "Could not create a directory for battery usage stats snapshots"); return; } } Loading @@ -136,8 +140,8 @@ public class BatteryUsageStatsStore { } removeOldSnapshotsLocked(); } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } } Loading @@ -147,7 +151,8 @@ public class BatteryUsageStatsStore { */ public long[] listBatteryUsageStatsTimestamps() { LongArray timestamps = new LongArray(100); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { for (File file : mStoreDir.listFiles()) { String fileName = file.getName(); if (fileName.endsWith(SNAPSHOT_FILE_EXTENSION)) { Loading @@ -161,8 +166,8 @@ public class BatteryUsageStatsStore { } } } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return timestamps.toArray(); } Loading @@ -173,15 +178,16 @@ public class BatteryUsageStatsStore { */ @Nullable public BatteryUsageStats loadBatteryUsageStats(long timestamp) { try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { File file = makeSnapshotFilename(timestamp); try { return readXmlFileLocked(file); } catch (Exception e) { Slog.e(TAG, "Cannot read battery usage stats", e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return null; } Loading @@ -192,7 +198,8 @@ public class BatteryUsageStatsStore { */ public void setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(long timestamp) { Properties props = new Properties(); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { try (InputStream in = mConfigFile.openRead()) { props.load(in); } catch (IOException e) { Loading @@ -209,8 +216,8 @@ public class BatteryUsageStatsStore { mConfigFile.failWrite(out); Slog.e(TAG, "Cannot save config file " + mConfigFile, e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } } Loading @@ -220,23 +227,41 @@ public class BatteryUsageStatsStore { */ public long getLastBatteryUsageStatsBeforeResetAtomPullTimestamp() { Properties props = new Properties(); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { try (InputStream in = mConfigFile.openRead()) { props.load(in); } catch (IOException e) { Slog.e(TAG, "Cannot load config file " + mConfigFile, e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return Long.parseLong( props.getProperty(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, "0")); } private FileLock lockSnapshotDirectory() throws IOException { private void lockSnapshotDirectory() { mFileLock.lock(); // Lock the directory from access by other JVMs try { mLockFile.getParentFile().mkdirs(); mLockFile.createNewFile(); return FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock(); mJvmLock = FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock(); } catch (IOException e) { Log.e(TAG, "Cannot lock snapshot directory", e); } } private void unlockSnapshotDirectory() { try { mJvmLock.close(); } catch (IOException e) { Log.e(TAG, "Cannot unlock snapshot directory", e); } finally { mFileLock.unlock(); } } /** Loading Loading
core/java/com/android/internal/os/BatteryUsageStatsStore.java +46 −21 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Handler; import android.util.AtomicFile; import android.util.Log; import android.util.LongArray; import android.util.Slog; import android.util.TypedXmlPullParser; Loading @@ -47,6 +48,7 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import java.util.concurrent.locks.ReentrantLock; /** * A storage mechanism for BatteryUsageStats snapshots. Loading @@ -73,6 +75,8 @@ public class BatteryUsageStatsStore { private boolean mSystemReady; private final File mStoreDir; private final File mLockFile; private final ReentrantLock mFileLock = new ReentrantLock(); private FileLock mJvmLock; private final AtomicFile mConfigFile; private final long mMaxStorageBytes; private final Handler mHandler; Loading Loading @@ -120,11 +124,11 @@ public class BatteryUsageStatsStore { } private void storeBatteryUsageStats(BatteryUsageStats stats) { try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { if (!mStoreDir.exists()) { if (!mStoreDir.mkdirs()) { Slog.e(TAG, "Could not create a directory for battery usage stats snapshots"); Slog.e(TAG, "Could not create a directory for battery usage stats snapshots"); return; } } Loading @@ -136,8 +140,8 @@ public class BatteryUsageStatsStore { } removeOldSnapshotsLocked(); } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } } Loading @@ -147,7 +151,8 @@ public class BatteryUsageStatsStore { */ public long[] listBatteryUsageStatsTimestamps() { LongArray timestamps = new LongArray(100); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { for (File file : mStoreDir.listFiles()) { String fileName = file.getName(); if (fileName.endsWith(SNAPSHOT_FILE_EXTENSION)) { Loading @@ -161,8 +166,8 @@ public class BatteryUsageStatsStore { } } } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return timestamps.toArray(); } Loading @@ -173,15 +178,16 @@ public class BatteryUsageStatsStore { */ @Nullable public BatteryUsageStats loadBatteryUsageStats(long timestamp) { try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { File file = makeSnapshotFilename(timestamp); try { return readXmlFileLocked(file); } catch (Exception e) { Slog.e(TAG, "Cannot read battery usage stats", e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return null; } Loading @@ -192,7 +198,8 @@ public class BatteryUsageStatsStore { */ public void setLastBatteryUsageStatsBeforeResetAtomPullTimestamp(long timestamp) { Properties props = new Properties(); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { try (InputStream in = mConfigFile.openRead()) { props.load(in); } catch (IOException e) { Loading @@ -209,8 +216,8 @@ public class BatteryUsageStatsStore { mConfigFile.failWrite(out); Slog.e(TAG, "Cannot save config file " + mConfigFile, e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } } Loading @@ -220,23 +227,41 @@ public class BatteryUsageStatsStore { */ public long getLastBatteryUsageStatsBeforeResetAtomPullTimestamp() { Properties props = new Properties(); try (FileLock lock = lockSnapshotDirectory()) { lockSnapshotDirectory(); try { try (InputStream in = mConfigFile.openRead()) { props.load(in); } catch (IOException e) { Slog.e(TAG, "Cannot load config file " + mConfigFile, e); } } catch (IOException e) { Slog.e(TAG, "Cannot lock battery usage stats directory", e); } finally { unlockSnapshotDirectory(); } return Long.parseLong( props.getProperty(BATTERY_USAGE_STATS_BEFORE_RESET_TIMESTAMP_PROPERTY, "0")); } private FileLock lockSnapshotDirectory() throws IOException { private void lockSnapshotDirectory() { mFileLock.lock(); // Lock the directory from access by other JVMs try { mLockFile.getParentFile().mkdirs(); mLockFile.createNewFile(); return FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock(); mJvmLock = FileChannel.open(mLockFile.toPath(), StandardOpenOption.WRITE).lock(); } catch (IOException e) { Log.e(TAG, "Cannot lock snapshot directory", e); } } private void unlockSnapshotDirectory() { try { mJvmLock.close(); } catch (IOException e) { Log.e(TAG, "Cannot unlock snapshot directory", e); } finally { mFileLock.unlock(); } } /** Loading