转载请注明出处:http://blog.csdn.net/droyon/article/details/35558671
1、
- // Each defined user has their own settings
- private static final SparseArray<SettingsCache> sSystemCaches
- private static final SparseArray<SettingsCache> sSecureCaches
- private static final SettingsCache sGlobalCache = new SettingsCache(TABLE_GLOBAL);
- // The count of how many known (handled by SettingsProvider)
// database mutations are currently being handled for this user.
// Used by file observers to not reload the database when it's ourselves
// modifying it.
private static final SparseArray<AtomicInteger> sKnownMutationsInFlight
= new SparseArray<AtomicInteger>();//用户评判是否为用户操作
2、删除用户时,同步更新所有存储用户概念的变量
void onUserRemoved(int userHandle) {
synchronized (this) {
// the db file itself will be deleted automatically, but we need to tear down
// our caches and other internal bookkeeping.
FileObserver observer = sObserverInstances.get(userHandle);
if (observer != null) {
observer.stopWatching();
sObserverInstances.delete(userHandle);
}
mOpenHelpers.delete(userHandle);
sSystemCaches.delete(userHandle);
sSecureCaches.delete(userHandle);
sKnownMutationsInFlight.delete(userHandle);
}
}
synchronized (this) {
// the db file itself will be deleted automatically, but we need to tear down
// our caches and other internal bookkeeping.
FileObserver observer = sObserverInstances.get(userHandle);
if (observer != null) {
observer.stopWatching();
sObserverInstances.delete(userHandle);
}
mOpenHelpers.delete(userHandle);
sSystemCaches.delete(userHandle);
sSecureCaches.delete(userHandle);
sKnownMutationsInFlight.delete(userHandle);
}
}
3、establishDbTracking(UserHandle.USER_OWNER);
private void establishDbTracking(int userHandle) {
if (LOCAL_LOGV) {
Slog.i(TAG, "Installing settings db helper and caches for user " + userHandle);
}
DatabaseHelper dbhelper;
synchronized (this) {
dbhelper = mOpenHelpers.get(userHandle);//每个user有一个dbHelper,如果为null,重新创建一个
if (dbhelper == null) {
dbhelper = new DatabaseHelper(getContext(), userHandle);
mOpenHelpers.append(userHandle, dbhelper);
sSystemCaches.append(userHandle, new SettingsCache(TABLE_SYSTEM));
sSecureCaches.append(userHandle, new SettingsCache(TABLE_SECURE));
sKnownMutationsInFlight.append(userHandle, new AtomicInteger(0));
}
}
// Initialization of the db *outside* the locks. It's possible that racing
// threads might wind up here, the second having read the cache entries
// written by the first, but that's benign: the SQLite helper implementation
// manages concurrency itself, and it's important that we not run the db
// initialization with any of our own locks held, so we're fine.
SQLiteDatabase db = dbhelper.getWritableDatabase();
// Watch for external modifications to the database files,
// keeping our caches in sync. We synchronize the observer set
// separately, and of course it has to run after the db file
// itself was set up by the DatabaseHelper.
synchronized (sObserverInstances) {
if (sObserverInstances.get(userHandle) == null) {//FileObserver如果为null,创建一个。
SettingsFileObserver observer = new SettingsFileObserver(userHandle, db.getPath());
sObserverInstances.append(userHandle, observer);
observer.startWatching();
}
}
ensureAndroidIdIsSet(userHandle);
startAsyncCachePopulation(userHandle);
}
if (LOCAL_LOGV) {
Slog.i(TAG, "Installing settings db helper and caches for user " + userHandle);
}
DatabaseHelper dbhelper;
synchronized (this) {
dbhelper = mOpenHelpers.get(userHandle);//每个user有一个dbHelper,如果为null,重新创建一个
if (dbhelper == null) {
dbhelper = new DatabaseHelper(getContext(), userHandle);
mOpenHelpers.append(userHandle, dbhelper);
sSystemCaches.append(userHandle, new SettingsCache(TABLE_SYSTEM));
sSecureCaches.append(userHandle, new SettingsCache(TABLE_SECURE));
sKnownMutationsInFlight.append(userHandle, new AtomicInteger(0));
}
}
// Initialization of the db *outside* the locks. It's possible that racing
// threads might wind up here, the second having read the cache entries
// written by the first, but that's benign: the SQLite helper implementation
// manages concurrency itself, and it's important that we not run the db
// initialization with any of our own locks held, so we're fine.
SQLiteDatabase db = dbhelper.getWritableDatabase();
// Watch for external modifications to the database files,
// keeping our caches in sync. We synchronize the observer set
// separately, and of course it has to run after the db file
// itself was set up by the DatabaseHelper.
synchronized (sObserverInstances) {
if (sObserverInstances.get(userHandle) == null) {//FileObserver如果为null,创建一个。
SettingsFileObserver observer = new SettingsFileObserver(userHandle, db.getPath());
sObserverInstances.append(userHandle, observer);
observer.startWatching();
}
}
ensureAndroidIdIsSet(userHandle);
startAsyncCachePopulation(userHandle);
}
4、存储一个随机的AndroidId。
private boolean ensureAndroidIdIsSet(int userHandle) {
final Cursor c = queryForUser(Settings.Secure.CONTENT_URI,
new String[] { Settings.NameValueTable.VALUE },
Settings.NameValueTable.NAME + "=?",
new String[] { Settings.Secure.ANDROID_ID }, null,
userHandle);
try {
final String value = c.moveToNext() ? c.getString(0) : null;
if (value == null) {
// sanity-check the user before touching the db
final UserInfo user = mUserManager.getUserInfo(userHandle);
if (user == null) {
// can happen due to races when deleting users; treat as benign
return false;
}
final SecureRandom random = new SecureRandom();
final String newAndroidIdValue = Long.toHexString(random.nextLong());
final ContentValues values = new ContentValues();
values.put(Settings.NameValueTable.NAME, Settings.Secure.ANDROID_ID);
values.put(Settings.NameValueTable.VALUE, newAndroidIdValue);
final Uri uri = insertForUser(Settings.Secure.CONTENT_URI, values, userHandle);
if (uri == null) {
Slog.e(TAG, "Unable to generate new ANDROID_ID for user " + userHandle);
return false;
}
Slog.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue
+ "] for user " + userHandle);
// Write a dropbox entry if it's a restricted profile
if (user.isRestricted()) {
DropBoxManager dbm = (DropBoxManager)
getContext().getSystemService(Context.DROPBOX_SERVICE);
if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
+ ",restricted_profile_ssaid,"
+ newAndroidIdValue + "\n");
}
}
}
return true;
} finally {
c.close();
}
}
final Cursor c = queryForUser(Settings.Secure.CONTENT_URI,
new String[] { Settings.NameValueTable.VALUE },
Settings.NameValueTable.NAME + "=?",
new String[] { Settings.Secure.ANDROID_ID }, null,
userHandle);
try {
final String value = c.moveToNext() ? c.getString(0) : null;
if (value == null) {
// sanity-check the user before touching the db
final UserInfo user = mUserManager.getUserInfo(userHandle);
if (user == null) {
// can happen due to races when deleting users; treat as benign
return false;
}
final SecureRandom random = new SecureRandom();
final String newAndroidIdValue = Long.toHexString(random.nextLong());
final ContentValues values = new ContentValues();
values.put(Settings.NameValueTable.NAME, Settings.Secure.ANDROID_ID);
values.put(Settings.NameValueTable.VALUE, newAndroidIdValue);
final Uri uri = insertForUser(Settings.Secure.CONTENT_URI, values, userHandle);
if (uri == null) {
Slog.e(TAG, "Unable to generate new ANDROID_ID for user " + userHandle);
return false;
}
Slog.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue
+ "] for user " + userHandle);
// Write a dropbox entry if it's a restricted profile
if (user.isRestricted()) {
DropBoxManager dbm = (DropBoxManager)
getContext().getSystemService(Context.DROPBOX_SERVICE);
if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
+ ",restricted_profile_ssaid,"
+ newAndroidIdValue + "\n");
}
}
}
return true;
} finally {
c.close();
}
}
5、为用户将Settings中的内容,更新到SettingsCache中;
private void startAsyncCachePopulation(int userHandle) {
new CachePrefetchThread(userHandle).start();
}
new CachePrefetchThread(userHandle).start();
}