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