[DO NOT MERGE] Handle config override via settings correctly
am: aa5ba4f75f
Change-Id: I690b9d81b1d3c72c9df3134d7ad92153cf3c9c5c
This commit is contained in:
@@ -108,6 +108,12 @@ import java.util.concurrent.TimeUnit;
|
||||
* must be called with the mInMemoryLock, xxxDMLocked suffix means the method
|
||||
* must be called with the mOnDiskLock and mInMemoryLock locks acquired in that
|
||||
* exact order.
|
||||
* <p>
|
||||
* INITIALIZATION: We can initialize persistence only after the system is ready
|
||||
* as we need to check the optional configuration override from the settings
|
||||
* database which is not initialized at the time the app ops service is created.
|
||||
* This means that all entry points that touch persistence should be short
|
||||
* circuited via isPersistenceInitialized() check.
|
||||
*/
|
||||
// TODO (bug:122218838): Make sure we handle start of epoch time
|
||||
// TODO (bug:122218838): Validate changed time is handled correctly
|
||||
@@ -177,14 +183,33 @@ final class HistoricalRegistry {
|
||||
|
||||
// Object managing persistence (read/write)
|
||||
@GuardedBy("mOnDiskLock")
|
||||
private Persistence mPersistence = new Persistence(mBaseSnapshotInterval,
|
||||
mIntervalCompressionMultiplier);
|
||||
private Persistence mPersistence;
|
||||
|
||||
HistoricalRegistry(@NonNull Object lock) {
|
||||
mInMemoryLock = lock;
|
||||
if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
}
|
||||
|
||||
void systemReady(@NonNull ContentResolver resolver) {
|
||||
final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
|
||||
resolver.registerContentObserver(uri, false, new ContentObserver(
|
||||
FgThread.getHandler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateParametersFromSetting(resolver);
|
||||
}
|
||||
});
|
||||
|
||||
updateParametersFromSetting(resolver);
|
||||
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
|
||||
// Can be uninitialized if there is no config in the settings table.
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
mPersistence = new Persistence(mBaseSnapshotInterval,
|
||||
mIntervalCompressionMultiplier);
|
||||
}
|
||||
|
||||
// When starting always adjust history to now.
|
||||
final long lastPersistTimeMills =
|
||||
mPersistence.getLastPersistTimeMillisDLocked();
|
||||
@@ -197,16 +222,8 @@ final class HistoricalRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
void systemReady(@NonNull ContentResolver resolver) {
|
||||
updateParametersFromSetting(resolver);
|
||||
final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
|
||||
resolver.registerContentObserver(uri, false, new ContentObserver(
|
||||
FgThread.getHandler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateParametersFromSetting(resolver);
|
||||
}
|
||||
});
|
||||
private boolean isPersistenceInitializedMLocked() {
|
||||
return mPersistence != null;
|
||||
}
|
||||
|
||||
private void updateParametersFromSetting(@NonNull ContentResolver resolver) {
|
||||
@@ -274,6 +291,11 @@ final class HistoricalRegistry {
|
||||
makeRelativeToEpochStart(currentOps, nowMillis);
|
||||
currentOps.accept(visitor);
|
||||
|
||||
if(isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
final List<HistoricalOps> ops = mPersistence.readHistoryDLocked();
|
||||
if (ops != null) {
|
||||
// TODO (bug:122218838): Make sure this is properly dumped
|
||||
@@ -302,12 +324,21 @@ final class HistoricalRegistry {
|
||||
void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
|
||||
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
|
||||
@OpFlags int flags, @NonNull RemoteCallback callback) {
|
||||
final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
|
||||
mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
|
||||
beginTimeMillis, endTimeMillis, flags);
|
||||
final Bundle payload = new Bundle();
|
||||
payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
|
||||
callback.sendResult(payload);
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
callback.sendResult(new Bundle());
|
||||
return;
|
||||
}
|
||||
final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
|
||||
mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
|
||||
beginTimeMillis, endTimeMillis, flags);
|
||||
final Bundle payload = new Bundle();
|
||||
payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
|
||||
callback.sendResult(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getHistoricalOps(int uid, @NonNull String packageName,
|
||||
@@ -331,6 +362,12 @@ final class HistoricalRegistry {
|
||||
boolean collectOpsFromDisk;
|
||||
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
callback.sendResult(new Bundle());
|
||||
return;
|
||||
}
|
||||
|
||||
currentOps = getUpdatedPendingHistoricalOpsMLocked(currentTimeMillis);
|
||||
if (!(inMemoryAdjBeginTimeMillis >= currentOps.getEndTimeMillis()
|
||||
|| inMemoryAdjEndTimeMillis <= currentOps.getBeginTimeMillis())) {
|
||||
@@ -374,6 +411,10 @@ final class HistoricalRegistry {
|
||||
@UidState int uidState, @OpFlags int flags) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
|
||||
.increaseAccessCount(op, uid, packageName, uidState, flags, 1);
|
||||
}
|
||||
@@ -384,6 +425,10 @@ final class HistoricalRegistry {
|
||||
@UidState int uidState, @OpFlags int flags) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
|
||||
.increaseRejectCount(op, uid, packageName, uidState, flags, 1);
|
||||
}
|
||||
@@ -394,6 +439,10 @@ final class HistoricalRegistry {
|
||||
@UidState int uidState, @OpFlags int flags, long increment) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
|
||||
.increaseAccessDuration(op, uid, packageName, uidState, flags, increment);
|
||||
}
|
||||
@@ -404,6 +453,8 @@ final class HistoricalRegistry {
|
||||
long baseSnapshotInterval, long intervalCompressionMultiplier) {
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
// NOTE: We allow this call if persistence is not initialized as
|
||||
// it is a part of the persistence initialization process.
|
||||
boolean resampleHistory = false;
|
||||
Slog.i(LOG_TAG, "New history parameters: mode:"
|
||||
+ AppOpsManager.historicalModeToString(mMode) + " baseSnapshotInterval:"
|
||||
@@ -412,7 +463,7 @@ final class HistoricalRegistry {
|
||||
if (mMode != mode) {
|
||||
mMode = mode;
|
||||
if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
|
||||
clearHistoryOnDiskLocked();
|
||||
clearHistoryOnDiskDLocked();
|
||||
}
|
||||
}
|
||||
if (mBaseSnapshotInterval != baseSnapshotInterval) {
|
||||
@@ -433,6 +484,10 @@ final class HistoricalRegistry {
|
||||
void offsetHistory(long offsetMillis) {
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
|
||||
clearHistory();
|
||||
if (history != null) {
|
||||
@@ -453,6 +508,10 @@ final class HistoricalRegistry {
|
||||
void addHistoricalOps(HistoricalOps ops) {
|
||||
final List<HistoricalOps> pendingWrites;
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
// The history files start from mBaseSnapshotInterval - take this into account.
|
||||
ops.offsetBeginAndEndTime(mBaseSnapshotInterval);
|
||||
mPendingWrites.offerFirst(ops);
|
||||
@@ -468,6 +527,10 @@ final class HistoricalRegistry {
|
||||
}
|
||||
|
||||
void resetHistoryParameters() {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
setHistoryParameters(DEFAULT_MODE, DEFAULT_SNAPSHOT_INTERVAL_MILLIS,
|
||||
DEFAULT_COMPRESSION_STEP);
|
||||
}
|
||||
@@ -475,6 +538,10 @@ final class HistoricalRegistry {
|
||||
void clearHistory(int uid, String packageName) {
|
||||
synchronized (mOnDiskLock) {
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
if (mMode != AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
@@ -493,11 +560,17 @@ final class HistoricalRegistry {
|
||||
|
||||
void clearHistory() {
|
||||
synchronized (mOnDiskLock) {
|
||||
clearHistoryOnDiskLocked();
|
||||
synchronized (mInMemoryLock) {
|
||||
if (!isPersistenceInitializedMLocked()) {
|
||||
Slog.e(LOG_TAG, "Interaction before persistence initialized");
|
||||
return;
|
||||
}
|
||||
clearHistoryOnDiskDLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearHistoryOnDiskLocked() {
|
||||
private void clearHistoryOnDiskDLocked() {
|
||||
BackgroundThread.getHandler().removeMessages(MSG_WRITE_PENDING_HISTORY);
|
||||
synchronized (mInMemoryLock) {
|
||||
mCurrentHistoricalOps = null;
|
||||
@@ -718,13 +791,27 @@ final class HistoricalRegistry {
|
||||
baseDir = mHistoricalAppOpsDir.startRead();
|
||||
final File[] files = baseDir.listFiles();
|
||||
if (files != null && files.length > 0) {
|
||||
final Set<File> historyFiles = new ArraySet<>();
|
||||
Collections.addAll(historyFiles, files);
|
||||
for (int i = 0;; i++) {
|
||||
final File file = generateFile(baseDir, i);
|
||||
if (historyFiles.contains(file)) {
|
||||
return file.lastModified();
|
||||
File shortestFile = null;
|
||||
for (File candidate : files) {
|
||||
final String candidateName = candidate.getName();
|
||||
if (!candidateName.endsWith(HISTORY_FILE_SUFFIX)) {
|
||||
continue;
|
||||
}
|
||||
if (shortestFile == null) {
|
||||
shortestFile = candidate;
|
||||
} else if (candidateName.length() < shortestFile.getName().length()) {
|
||||
shortestFile = candidate;
|
||||
}
|
||||
}
|
||||
if (shortestFile == null) {
|
||||
return 0;
|
||||
}
|
||||
final String shortestNameNoExtension = shortestFile.getName()
|
||||
.replace(HISTORY_FILE_SUFFIX, "");
|
||||
try {
|
||||
return Long.parseLong(shortestNameNoExtension);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
mHistoricalAppOpsDir.finishRead();
|
||||
|
||||
Reference in New Issue
Block a user