use of android.util.AtomicFile in project android_frameworks_base by DirtyUnicorns.
the class PackageUsage method writeInternal.
@Override
protected void writeInternal(Map<String, PackageParser.Package> packages) {
AtomicFile file = getFile();
FileOutputStream f = null;
try {
f = file.startWrite();
BufferedOutputStream out = new BufferedOutputStream(f);
FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
StringBuilder sb = new StringBuilder();
sb.append(USAGE_FILE_MAGIC_VERSION_1);
sb.append('\n');
out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
for (PackageParser.Package pkg : packages.values()) {
if (pkg.getLatestPackageUseTimeInMills() == 0L) {
continue;
}
sb.setLength(0);
sb.append(pkg.packageName);
for (long usageTimeInMillis : pkg.mLastPackageUsageTimeInMills) {
sb.append(' ');
sb.append(usageTimeInMillis);
}
sb.append('\n');
out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
}
out.flush();
file.finishWrite(f);
} catch (IOException e) {
if (f != null) {
file.failWrite(f);
}
Log.e(PackageManagerService.TAG, "Failed to write package usage times", e);
}
}
use of android.util.AtomicFile in project android_frameworks_base by DirtyUnicorns.
the class UsageStatsDatabase method checkinDailyFiles.
/**
* Calls {@link CheckinAction#checkin(IntervalStats)} on the given {@link CheckinAction}
* for all {@link IntervalStats} that haven't been checked-in.
* If any of the calls to {@link CheckinAction#checkin(IntervalStats)} returns false or throws
* an exception, the check-in will be aborted.
*
* @param checkinAction The callback to run when checking-in {@link IntervalStats}.
* @return true if the check-in succeeded.
*/
public boolean checkinDailyFiles(CheckinAction checkinAction) {
synchronized (mLock) {
final TimeSparseArray<AtomicFile> files = mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY];
final int fileCount = files.size();
// We may have holes in the checkin (if there was an error)
// so find the last checked-in file and go from there.
int lastCheckin = -1;
for (int i = 0; i < fileCount - 1; i++) {
if (files.valueAt(i).getBaseFile().getPath().endsWith(CHECKED_IN_SUFFIX)) {
lastCheckin = i;
}
}
final int start = lastCheckin + 1;
if (start == fileCount - 1) {
return true;
}
try {
IntervalStats stats = new IntervalStats();
for (int i = start; i < fileCount - 1; i++) {
UsageStatsXml.read(files.valueAt(i), stats, QUERY_FLAG_FETCH_EVERYTHING);
if (!checkinAction.checkin(stats)) {
return false;
}
}
} catch (IOException e) {
Slog.e(TAG, "Failed to check-in", e);
return false;
}
// are marked as checked-in.
for (int i = start; i < fileCount - 1; i++) {
final AtomicFile file = files.valueAt(i);
final File checkedInFile = new File(file.getBaseFile().getPath() + CHECKED_IN_SUFFIX);
if (!file.getBaseFile().renameTo(checkedInFile)) {
// We must return success, as we've already marked some files as checked-in.
// It's better to repeat ourselves than to lose data.
Slog.e(TAG, "Failed to mark file " + file.getBaseFile().getPath() + " as checked-in");
return true;
}
// AtomicFile needs to set a new backup path with the same -c extension, so
// we replace the old AtomicFile with the updated one.
files.setValueAt(i, new AtomicFile(checkedInFile));
}
}
return true;
}
use of android.util.AtomicFile in project android_frameworks_base by DirtyUnicorns.
the class AppIdleHistory method writeAppIdleTimesLocked.
public void writeAppIdleTimesLocked(int userId) {
FileOutputStream fos = null;
AtomicFile appIdleFile = new AtomicFile(getUserFile(userId));
try {
fos = appIdleFile.startWrite();
final BufferedOutputStream bos = new BufferedOutputStream(fos);
FastXmlSerializer xml = new FastXmlSerializer();
xml.setOutput(bos, StandardCharsets.UTF_8.name());
xml.startDocument(null, true);
xml.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
xml.startTag(null, TAG_PACKAGES);
ArrayMap<String, PackageHistory> userHistory = getUserHistoryLocked(userId);
final int N = userHistory.size();
for (int i = 0; i < N; i++) {
String packageName = userHistory.keyAt(i);
PackageHistory history = userHistory.valueAt(i);
xml.startTag(null, TAG_PACKAGE);
xml.attribute(null, ATTR_NAME, packageName);
xml.attribute(null, ATTR_ELAPSED_IDLE, Long.toString(history.lastUsedElapsedTime));
xml.attribute(null, ATTR_SCREEN_IDLE, Long.toString(history.lastUsedScreenTime));
xml.endTag(null, TAG_PACKAGE);
}
xml.endTag(null, TAG_PACKAGES);
xml.endDocument();
appIdleFile.finishWrite(fos);
} catch (Exception e) {
appIdleFile.failWrite(fos);
Slog.e(TAG, "Error writing app idle file for user " + userId);
}
}
use of android.util.AtomicFile in project android_frameworks_base by DirtyUnicorns.
the class UsageStatsDatabase method getLatestUsageStats.
/**
* Get the latest stats that exist for this interval type.
*/
public IntervalStats getLatestUsageStats(int intervalType) {
synchronized (mLock) {
if (intervalType < 0 || intervalType >= mIntervalDirs.length) {
throw new IllegalArgumentException("Bad interval type " + intervalType);
}
final int fileCount = mSortedStatFiles[intervalType].size();
if (fileCount == 0) {
return null;
}
try {
final AtomicFile f = mSortedStatFiles[intervalType].valueAt(fileCount - 1);
IntervalStats stats = new IntervalStats();
UsageStatsXml.read(f, stats, QUERY_FLAG_FETCH_EVERYTHING);
return stats;
} catch (IOException e) {
Slog.e(TAG, "Failed to read usage stats file", e);
}
}
return null;
}
use of android.util.AtomicFile in project android_frameworks_base by DirtyUnicorns.
the class UserManagerService method removeUserState.
private void removeUserState(final int userHandle) {
try {
mContext.getSystemService(StorageManager.class).destroyUserKey(userHandle);
} catch (IllegalStateException e) {
// This may be simply because the user was partially created.
Slog.i(LOG_TAG, "Destroying key for user " + userHandle + " failed, continuing anyway", e);
}
// Cleanup gatekeeper secure user id
try {
final IGateKeeperService gk = GateKeeper.getService();
if (gk != null) {
gk.clearSecureUserId(userHandle);
}
} catch (Exception ex) {
Slog.w(LOG_TAG, "unable to clear GK secure user id");
}
// Cleanup package manager settings
mPm.cleanUpUser(this, userHandle);
// Clean up all data before removing metadata
mPm.destroyUserData(userHandle, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
// Remove this user from the list
synchronized (mUsersLock) {
mUsers.remove(userHandle);
mIsUserManaged.delete(userHandle);
}
synchronized (mUserStates) {
mUserStates.delete(userHandle);
}
synchronized (mRestrictionsLock) {
mBaseUserRestrictions.remove(userHandle);
mAppliedUserRestrictions.remove(userHandle);
mCachedEffectiveUserRestrictions.remove(userHandle);
mDevicePolicyLocalUserRestrictions.remove(userHandle);
}
// Update the user list
synchronized (mPackagesLock) {
writeUserListLP();
}
// Remove user file
AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + XML_SUFFIX));
userFile.delete();
updateUserIds();
}
Aggregations