下面列出了怎么用android.util.AtomicFile的API类实例代码及写法,或者点击链接到github查看源代码。
private void readEvents() {
synchronized (mEventsLock) {
// Read might prune events so mark as dirty.
mEventsDirty = true;
mEvents.clear();
final AtomicFile readFrom = mInjector.getFile(EVENTS_FILE);
if (readFrom != null && readFrom.exists()) {
FileInputStream input = null;
try {
input = readFrom.openRead();
readEventsLocked(input);
} catch (IOException e) {
readFrom.delete();
Slog.e(TAG, "Failed to read change mEvents.", e);
} finally {
IoUtils.closeQuietly(input);
}
}
}
}
private void readAmbientBrightnessStats() {
mAmbientBrightnessStatsTracker = new AmbientBrightnessStatsTracker(mUserManager, null);
final AtomicFile readFrom = mInjector.getFile(AMBIENT_BRIGHTNESS_STATS_FILE);
if (readFrom != null && readFrom.exists()) {
FileInputStream input = null;
try {
input = readFrom.openRead();
mAmbientBrightnessStatsTracker.readStats(input);
} catch (IOException e) {
readFrom.delete();
Slog.e(TAG, "Failed to read ambient brightness stats.", e);
} finally {
IoUtils.closeQuietly(input);
}
}
}
@Override
protected void writeInternal(Void data) {
AtomicFile file = getFile();
FileOutputStream f = null;
try {
f = file.startWrite();
OutputStreamWriter osw = new OutputStreamWriter(f);
write(osw);
osw.flush();
file.finishWrite(f);
} catch (IOException e) {
if (f != null) {
file.failWrite(f);
}
Slog.e(TAG, "Failed to write usage for dex files", e);
}
}
private void writeUserLP(UserData userData) {
if (DBG) {
debug("writeUserLP " + userData);
}
FileOutputStream fos = null;
AtomicFile userFile = new AtomicFile(new File(mUsersDir, userData.info.id + XML_SUFFIX));
try {
fos = userFile.startWrite();
final BufferedOutputStream bos = new BufferedOutputStream(fos);
writeUserLP(userData, bos);
userFile.finishWrite(fos);
} catch (Exception ioe) {
Slog.e(LOG_TAG, "Error writing user info " + userData.info.id, ioe);
userFile.failWrite(fos);
}
}
private UserData readUserLP(int id) {
FileInputStream fis = null;
try {
AtomicFile userFile =
new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
fis = userFile.openRead();
return readUserLP(id, fis);
} catch (IOException ioe) {
Slog.e(LOG_TAG, "Error reading user list");
} catch (XmlPullParserException pe) {
Slog.e(LOG_TAG, "Error reading user list");
} finally {
IoUtils.closeQuietly(fis);
}
return null;
}
@VisibleForTesting
@GuardedBy("mAppRestrictionsLock")
static void writeApplicationRestrictionsLAr(Bundle restrictions, AtomicFile restrictionsFile) {
FileOutputStream fos = null;
try {
fos = restrictionsFile.startWrite();
final BufferedOutputStream bos = new BufferedOutputStream(fos);
final XmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, TAG_RESTRICTIONS);
writeBundle(restrictions, serializer);
serializer.endTag(null, TAG_RESTRICTIONS);
serializer.endDocument();
restrictionsFile.finishWrite(fos);
} catch (Exception e) {
restrictionsFile.failWrite(fos);
Slog.e(LOG_TAG, "Error writing application restrictions list", e);
}
}
@Override
protected void writeInternal(Void data) {
AtomicFile file = getFile();
FileOutputStream f = null;
try {
f = file.startWrite();
OutputStreamWriter osw = new OutputStreamWriter(f);
write(osw);
osw.flush();
file.finishWrite(f);
} catch (IOException e) {
if (f != null) {
file.failWrite(f);
}
Log.e(PackageManagerService.TAG, "Failed to write compiler stats", e);
}
}
public PackageInstallerService(Context context, PackageManagerService pm) {
mContext = context;
mPm = pm;
mPermissionManager = LocalServices.getService(PermissionManagerInternal.class);
mInstallThread = new HandlerThread(TAG);
mInstallThread.start();
mInstallHandler = new Handler(mInstallThread.getLooper());
mCallbacks = new Callbacks(mInstallThread.getLooper());
mSessionsFile = new AtomicFile(
new File(Environment.getDataSystemDirectory(), "install_sessions.xml"),
"package-session");
mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions");
mSessionsDir.mkdirs();
}
@GuardedBy("mLock")
private void saveUserLocked(@UserIdInt int userId) {
final File path = getUserFile(userId);
if (DEBUG) {
Slog.d(TAG, "Saving to " + path);
}
mShortcutBitmapSaver.waitForAllSavesLocked();
path.getParentFile().mkdirs();
final AtomicFile file = new AtomicFile(path);
FileOutputStream os = null;
try {
os = file.startWrite();
saveUserInternalLocked(userId, os, /* forBackup= */ false);
file.finishWrite(os);
// Remove all dangling bitmap files.
cleanupDanglingBitmapDirectoriesLocked(userId);
} catch (XmlPullParserException | IOException e) {
Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
file.failWrite(os);
}
}
public InputMethodFileManager(HashMap<String, InputMethodInfo> methodMap, int userId) {
if (methodMap == null) {
throw new NullPointerException("methodMap is null");
}
mMethodMap = methodMap;
final File systemDir = userId == UserHandle.USER_OWNER
? new File(Environment.getDataDirectory(), SYSTEM_PATH)
: Environment.getUserSystemDirectory(userId);
final File inputMethodDir = new File(systemDir, INPUT_METHOD_PATH);
if (!inputMethodDir.mkdirs()) {
Slog.w(TAG, "Couldn't create dir.: " + inputMethodDir.getAbsolutePath());
}
final File subtypeFile = new File(inputMethodDir, ADDITIONAL_SUBTYPES_FILE_NAME);
mAdditionalInputMethodSubtypeFile = new AtomicFile(subtypeFile);
if (!subtypeFile.exists()) {
// If "subtypes.xml" doesn't exist, create a blank file.
writeAdditionalInputMethodSubtypes(
mAdditionalSubtypesMap, mAdditionalInputMethodSubtypeFile, methodMap);
} else {
readAdditionalInputMethodSubtypes(
mAdditionalSubtypesMap, mAdditionalInputMethodSubtypeFile);
}
}
private void writeEvents() {
synchronized (mEventsLock) {
if (!mEventsDirty) {
// Nothing to write
return;
}
final AtomicFile writeTo = mInjector.getFile(EVENTS_FILE);
if (writeTo == null) {
return;
}
if (mEvents.isEmpty()) {
if (writeTo.exists()) {
writeTo.delete();
}
mEventsDirty = false;
} else {
FileOutputStream output = null;
try {
output = writeTo.startWrite();
writeEventsLocked(output);
writeTo.finishWrite(output);
mEventsDirty = false;
} catch (IOException e) {
writeTo.failWrite(output);
Slog.e(TAG, "Failed to write change mEvents.", e);
}
}
}
}
private void writeAmbientBrightnessStats() {
final AtomicFile writeTo = mInjector.getFile(AMBIENT_BRIGHTNESS_STATS_FILE);
if (writeTo == null) {
return;
}
FileOutputStream output = null;
try {
output = writeTo.startWrite();
mAmbientBrightnessStatsTracker.writeStats(output);
writeTo.finishWrite(output);
} catch (IOException e) {
writeTo.failWrite(output);
Slog.e(TAG, "Failed to write ambient brightness stats.", e);
}
}
public PersistentDataStore(Context context, int userId) {
mContext = context;
File userDir = Environment.getUserSystemDirectory(userId);
if (!userDir.exists()) {
if (!userDir.mkdirs()) {
throw new IllegalStateException("User dir cannot be created: " + userDir);
}
}
mAtomicFile = new AtomicFile(new File(userDir, "tv-input-manager-state.xml"), "tv-input-state");
}
public SystemUpdateManagerService(Context context) {
mContext = context;
mFile = new AtomicFile(new File(Environment.getDataSystemDirectory(), INFO_FILE));
// Populate mLastUid and mLastStatus.
synchronized (mLock) {
loadSystemUpdateInfoLocked();
}
}
/**
* Construct the instance of the job store. This results in a blocking read from disk.
*/
private JobStore(Context context, Object lock, File dataDir) {
mLock = lock;
mContext = context;
mDirtyOperations = 0;
File systemDir = new File(dataDir, "system");
File jobDir = new File(systemDir, "job");
jobDir.mkdirs();
mJobsFile = new AtomicFile(new File(jobDir, "jobs.xml"), "jobs");
mJobSet = new JobSet();
// If the current RTC is earlier than the timestamp on our persisted jobs file,
// we suspect that the RTC is uninitialized and so we cannot draw conclusions
// about persisted job scheduling.
//
// Note that if the persisted jobs file does not exist, we proceed with the
// assumption that the RTC is good. This is less work and is safe: if the
// clock updates to sanity then we'll be saving the persisted jobs file in that
// correct state, which is normal; or we'll wind up writing the jobs file with
// an incorrect historical timestamp. That's fine; at worst we'll reboot with
// a *correct* timestamp, see a bunch of overdue jobs, and run them; then
// settle into normal operation.
mXmlTimestamp = mJobsFile.getLastModifiedTime();
mRtcGood = (sSystemClock.millis() > mXmlTimestamp);
readJobMapFromDisk(mJobSet, mRtcGood);
}
@GuardedBy("mLock")
private void saveDefaultValuesLocked() {
final AtomicFile file = new AtomicFile(injectDefaultValuesFilename());
FileOutputStream outs = null;
try {
file.getBaseFile().getParentFile().mkdirs();
outs = file.startWrite();
// Write to XML
XmlSerializer out = new FastXmlSerializer();
out.setOutput(outs, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_DEFAULT_ROOT);
XmlUtils.writeMapXml(mDefaultValues, out, null);
// Epilogue.
out.endTag(null, TAG_DEFAULT_ROOT);
out.endDocument();
// Close.
file.finishWrite(outs);
} catch (IOException | XmlPullParserException | RuntimeException e) {
Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
file.failWrite(outs);
}
}
private ParserHolder getParser(String fileName)
throws FileNotFoundException, XmlPullParserException {
AtomicFile file = getFile(fileName);
ParserHolder holder = new ParserHolder();
holder.input = file.openRead();
holder.parser = XmlPullParserFactory.newInstance().newPullParser();
holder.parser.setInput(holder.input, Encoding.UTF_8.name());
return holder;
}
private SyncStorageEngine(Context context, File dataDir, Looper looper) {
mHandler = new MyHandler(looper);
mContext = context;
sSyncStorageEngine = this;
mLogger = SyncLogger.getInstance();
mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
mDefaultMasterSyncAutomatically = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_syncstorageengine_masterSyncAutomatically);
File systemDir = new File(dataDir, "system");
File syncDir = new File(systemDir, "sync");
syncDir.mkdirs();
maybeDeleteLegacyPendingInfoLocked(syncDir);
mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"), "sync-accounts");
mStatusFile = new AtomicFile(new File(syncDir, "status.bin"), "sync-status");
mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"), "sync-stats");
readAccountInfoLocked();
readStatusLocked();
readStatisticsLocked();
readAndDeleteLegacyAccountInfoLocked();
writeAccountInfoLocked();
writeStatusLocked();
writeStatisticsLocked();
if (mLogger.enabled()) {
final int size = mAuthorities.size();
mLogger.log("Loaded ", size, " items");
for (int i = 0; i < size; i++) {
mLogger.log(mAuthorities.valueAt(i));
}
}
}
@GuardedBy("mAppRestrictionsLock")
private static Bundle readApplicationRestrictionsLAr(String packageName, int userId) {
AtomicFile restrictionsFile =
new AtomicFile(new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
return readApplicationRestrictionsLAr(restrictionsFile);
}
@GuardedBy("mAppRestrictionsLock")
private static void writeApplicationRestrictionsLAr(String packageName,
Bundle restrictions, int userId) {
AtomicFile restrictionsFile = new AtomicFile(
new File(Environment.getUserSystemDirectory(userId),
packageToRestrictionsFileName(packageName)));
writeApplicationRestrictionsLAr(restrictions, restrictionsFile);
}
@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);
}
}
private static @Nullable UninstalledInstantAppState parseMetadataFile(
@NonNull File metadataFile) {
if (!metadataFile.exists()) {
return null;
}
FileInputStream in;
try {
in = new AtomicFile(metadataFile).openRead();
} catch (FileNotFoundException fnfe) {
Slog.i(LOG_TAG, "No instant metadata file");
return null;
}
final File instantDir = metadataFile.getParentFile();
final long timestamp = metadataFile.lastModified();
final String packageName = instantDir.getName();
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, StandardCharsets.UTF_8.name());
return new UninstalledInstantAppState(
parseMetadata(parser, packageName), timestamp);
} catch (XmlPullParserException | IOException e) {
throw new IllegalStateException("Failed parsing instant"
+ " metadata file: " + metadataFile, e);
} finally {
IoUtils.closeQuietly(in);
}
}
@GuardedBy("mLock")
@VisibleForTesting
void saveBaseStateLocked() {
final AtomicFile file = getBaseStateFile();
if (DEBUG) {
Slog.d(TAG, "Saving to " + file.getBaseFile());
}
FileOutputStream outs = null;
try {
outs = file.startWrite();
// Write to XML
XmlSerializer out = new FastXmlSerializer();
out.setOutput(outs, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_ROOT);
// Body.
writeTagValue(out, TAG_LAST_RESET_TIME, mRawLastResetTime);
// Epilogue.
out.endTag(null, TAG_ROOT);
out.endDocument();
// Close.
file.finishWrite(outs);
} catch (IOException e) {
Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
file.failWrite(outs);
}
}
public OverlayManagerService(@NonNull final Context context,
@NonNull final Installer installer) {
super(context);
mSettingsFile =
new AtomicFile(new File(Environment.getDataSystemDirectory(), "overlays.xml"), "overlays");
mPackageManager = new PackageManagerHelper();
mUserManager = UserManagerService.getInstance();
IdmapManager im = new IdmapManager(installer);
mSettings = new OverlayManagerSettings();
mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
getDefaultOverlayPackages(), new OverlayChangeListener());
mInitCompleteSignal = SystemServerInitThreadPool.get().submit(() -> {
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(ACTION_PACKAGE_ADDED);
packageFilter.addAction(ACTION_PACKAGE_CHANGED);
packageFilter.addAction(ACTION_PACKAGE_REMOVED);
packageFilter.addDataScheme("package");
getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL,
packageFilter, null, null);
final IntentFilter userFilter = new IntentFilter();
userFilter.addAction(ACTION_USER_ADDED);
userFilter.addAction(ACTION_USER_REMOVED);
getContext().registerReceiverAsUser(new UserReceiver(), UserHandle.ALL,
userFilter, null, null);
restoreSettings();
initIfNeeded();
onSwitchUser(UserHandle.USER_SYSTEM);
publishBinderService(Context.OVERLAY_SERVICE, mService);
publishLocalService(OverlayManagerService.class, this);
}, "Init OverlayManagerService");
}
@VisibleForTesting
protected WatchlistSettings(File xmlFile) {
mXmlFile = new AtomicFile(xmlFile, "net-watchlist");
reloadSettings();
if (mPrivacySecretKey == null) {
// Generate a new secret key and save settings
mPrivacySecretKey = generatePrivacySecretKey();
saveSettings();
}
}
public AppOpsService(File storagePath, Handler handler) {
LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
mFile = new AtomicFile(storagePath, "appops");
mHandler = handler;
mConstants = new Constants(mHandler);
readState();
}
public void writeStateLocked(boolean sync, final boolean commit) {
final long totalTime;
synchronized (mPendingWriteLock) {
final long now = SystemClock.uptimeMillis();
if (mPendingWrite == null || !mPendingWriteCommitted) {
mPendingWrite = Parcel.obtain();
mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
mProcessStats.mTimePeriodEndUptime = now;
if (commit) {
mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
}
mProcessStats.writeToParcel(mPendingWrite, 0);
mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
mPendingWriteCommitted = commit;
}
if (commit) {
mProcessStats.resetSafely();
updateFile();
mAm.requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
}
mLastWriteTime = SystemClock.uptimeMillis();
totalTime = SystemClock.uptimeMillis() - now;
if (DEBUG) Slog.d(TAG, "Prepared write state in " + now + "ms");
if (!sync) {
BackgroundThread.getHandler().post(new Runnable() {
@Override public void run() {
performWriteState(totalTime);
}
});
return;
}
}
performWriteState(totalTime);
}
void performWriteState(long initialTime) {
if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
Parcel data;
AtomicFile file;
synchronized (mPendingWriteLock) {
data = mPendingWrite;
file = mPendingWriteFile;
mPendingWriteCommitted = false;
if (data == null) {
return;
}
mPendingWrite = null;
mPendingWriteFile = null;
mWriteLock.lock();
}
final long startTime = SystemClock.uptimeMillis();
FileOutputStream stream = null;
try {
stream = file.startWrite();
stream.write(data.marshall());
stream.flush();
file.finishWrite(stream);
com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
"procstats", SystemClock.uptimeMillis() - startTime + initialTime);
if (DEBUG) Slog.d(TAG, "Write completed successfully!");
} catch (IOException e) {
Slog.w(TAG, "Error writing process statistics", e);
file.failWrite(stream);
} finally {
data.recycle();
trimHistoricStatesWriteLocked();
mWriteLock.unlock();
}
}
@GuardedBy("mServicesLock")
private UserServices<V> findOrCreateUserLocked(int userId, boolean loadFromFileIfNew) {
UserServices<V> services = mUserServices.get(userId);
if (services == null) {
services = new UserServices<V>();
mUserServices.put(userId, services);
if (loadFromFileIfNew && mSerializerAndParser != null) {
// Check if user exists and try loading data from file
// clear existing data if there was an error during migration
UserInfo user = getUser(userId);
if (user != null) {
AtomicFile file = createFileForUser(user.id);
if (file.getBaseFile().exists()) {
if (DEBUG) {
Slog.i(TAG, String.format("Loading u%s data from %s", user.id, file));
}
InputStream is = null;
try {
is = file.openRead();
readPersistentServicesLocked(is);
} catch (Exception e) {
Log.w(TAG, "Error reading persistent services for user " + user.id, e);
} finally {
IoUtils.closeQuietly(is);
}
}
}
}
}
return services;
}
/**
* Writes services of a specified user to the file.
*/
private void writePersistentServicesLocked(UserServices<V> user, int userId) {
if (mSerializerAndParser == null) {
return;
}
AtomicFile atomicFile = createFileForUser(userId);
FileOutputStream fos = null;
try {
fos = atomicFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "services");
for (Map.Entry<V, Integer> service : user.persistentServices.entrySet()) {
out.startTag(null, "service");
out.attribute(null, "uid", Integer.toString(service.getValue()));
mSerializerAndParser.writeAsXml(service.getKey(), out);
out.endTag(null, "service");
}
out.endTag(null, "services");
out.endDocument();
atomicFile.finishWrite(fos);
} catch (IOException e1) {
Log.w(TAG, "Error writing accounts", e1);
if (fos != null) {
atomicFile.failWrite(fos);
}
}
}