android_id 的生成原理是由系统生成的随机数,并与应用 app 签名,经过 HmacSHA256 算法生成的;
从 android 8 以后开始就是随机的了,每个应用获取到的简要步骤;
下面是追踪代码:
2423 public Setting generateSsaidLocked(PackageInfo callingPkg, int userId) {
2424 // Read the user's key from the ssaid table.
2425 Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2426 if (userKeySetting == null || userKeySetting.isNull()
2427 || userKeySetting.getValue() == null) {
2428 // Lazy initialize and store the user key.
2429 generateUserKeyLocked(userId);
2430 userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
2431 if (userKeySetting == null || userKeySetting.isNull()
2432 || userKeySetting.getValue() == null) {
2433 throw new IllegalStateException("User key not accessible");
2434 }
2435 }
2436 final String userKey = userKeySetting.getValue();
2437
2438 // Convert the user's key back to a byte array.
2439 final byte[] keyBytes = ByteStringUtils.fromHexToByteArray(userKey);
2440
2441 // Validate that the key is of expected length.
2442 // Keys are currently 32 bytes, but were once 16 bytes during Android O development.
2443 if (keyBytes == null || (keyBytes.length != 16 && keyBytes.length != 32)) {
2444 throw new IllegalStateException("User key invalid");
2445 }
2446
2447 final Mac m;
2448 try {
2449 m = Mac.getInstance("HmacSHA256");
2450 m.init(new SecretKeySpec(keyBytes, m.getAlgorithm()));
2451 } catch (NoSuchAlgorithmException e) {
2452 throw new IllegalStateException("HmacSHA256 is not available", e);
2453 } catch (InvalidKeyException e) {
2454 throw new IllegalStateException("Key is corrupted", e);
2455 }
2456
2457 // Mac each of the developer signatures.
2458 for (int i = 0; i < callingPkg.signatures.length; i++) {
2459 byte[] sig = callingPkg.signatures[i].toByteArray();
2460 m.update(getLengthPrefix(sig), 0, 4);
2461 m.update(sig);
2462 }
2463
2464 // Convert result to a string for storage in settings table. Only want first 64 bits.
2465 final String ssaid = ByteStringUtils.toHexString(m.doFinal()).substring(0, 16)
2466 .toLowerCase(Locale.US);
追踪看写入代码:
2724 public Setting getSettingLocked(int type, int userId, String name) {
2725 final int key = makeKey(type, userId);
2726
2727 SettingsState settingsState = peekSettingsStateLocked(key);
2728 if (settingsState == null) {
2729 return null;
2730 }
2731
2732 // getSettingLocked will return non-null result
2733 return settingsState.getSettingLocked(name);
2734 }
2860 @Nullable
2861 private SettingsState peekSettingsStateLocked(int key) {
2862 SettingsState settingsState = mSettingsStates.get(key);
2863 if (settingsState != null) {
2864 return settingsState;
2865 }
2866
2867 if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
2868 return null;
2869 }
2870 return mSettingsStates.get(key);
2871 }
2585 private void ensureSettingsStateLocked(int key) {
2586 if (mSettingsStates.get(key) == null) {
2587 final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
2588 SettingsState settingsState = new SettingsState(getContext(), mLock,
2589 getSettingsFile(key), key, maxBytesPerPackage, mHandlerThread.getLooper());
2590 mSettingsStates.put(key, settingsState);
2591 }
2592 }
252 public SettingsState(Context context, Object lock, File file, int key,
253 int maxBytesPerAppPackage, Looper looper) {
254 // It is important that we use the same lock as the settings provider
255 // to ensure multiple mutations on this state are atomicaly persisted
256 // as the async persistence should be blocked while we make changes.
257 mContext = context;
258 mLock = lock;
259 mStatePersistFile = file;
260 mStatePersistTag = "settings-" + getTypeFromKey(key) + "-" + getUserIdFromKey(key);
261 mKey = key;
262 mHandler = new MyHandler(looper);
263 if (maxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_LIMITED) {
264 mMaxBytesPerAppPackage = maxBytesPerAppPackage;
265 mPackageToMemoryUsage = new ArrayMap<>();
266 } else {
267 mMaxBytesPerAppPackage = maxBytesPerAppPackage;
268 mPackageToMemoryUsage = null;
269 }
270
271 mHistoricalOperations = Build.IS_DEBUGGABLE
272 ? new ArrayList<>(HISTORICAL_OPERATION_COUNT) : null;
273
274 synchronized (mLock) {
275 readStateSyncLocked();
276 }
277 }
跳到创建成功时,获取代码
337 // The settings provider must hold its lock when calling here.
338 @GuardedBy("mLock")
339 public Setting getSettingLocked(String name) {
340 if (TextUtils.isEmpty(name)) {
341 return mNullSetting;
342 }
343 Setting setting = mSettings.get(name);
344 if (setting != null) {
345 return new Setting(setting);
346 }
347 return mNullSetting;
348 }
157 @GuardedBy("mLock")
158 private final ArrayMap<String, Setting> mSettings = new ArrayMap<>();
新 setting 元素来自于新的插入;
384 // The settings provider must hold its lock when calling here.
385 @GuardedBy("mLock")
386 public boolean insertSettingLocked(String name, String value, String tag,
387 boolean makeDefault, boolean forceNonSystemPackage, String packageName) {
388 if (TextUtils.isEmpty(name)) {
389 return false;
390 }
391
392 Setting oldState = mSettings.get(name);
393 String oldValue = (oldState != null) ? oldState.value : null;
394 String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null;
395 Setting newState;
396
397 if (oldState != null) {
398 if (!oldState.update(value, makeDefault, packageName, tag, forceNonSystemPackage)) {
399 return false;
400 }
401 newState = oldState;
402 } else {
403 newState = new Setting(name, value, makeDefault, packageName, tag);
404 mSettings.put(name, newState);
3602 if (currentVersion == 136) {
3603 // Version 136: Store legacy SSAID for all apps currently installed on the
3604 // device as first step in migrating SSAID to be unique per application.
3605
3606 final boolean isUpgrade;
3607 try {
3608 isUpgrade = mPackageManager.isDeviceUpgrading();
3609 } catch (RemoteException e) {
3610 throw new IllegalStateException("Package manager not available");
3611 }
3612 // Only retain legacy ssaid if the device is performing an OTA. After wiping
3613 // user data or first boot on a new device should use new ssaid generation.
3614 if (isUpgrade) {
3615 // Retrieve the legacy ssaid from the secure settings table.
3616 final Setting legacySsaidSetting = getSettingLocked(SETTINGS_TYPE_SECURE,
3617 userId, Settings.Secure.ANDROID_ID);
3618 if (legacySsaidSetting == null || legacySsaidSetting.isNull()
3619 || legacySsaidSetting.getValue() == null) {
3620 throw new IllegalStateException("Legacy ssaid not accessible");
3621 }
3622 final String legacySsaid = legacySsaidSetting.getValue();
3623
3624 // Fill each uid with the legacy ssaid to be backwards compatible.
3625 final List<PackageInfo> packages;
3626 try {
3627 packages = mPackageManager.getInstalledPackages(
3628 PackageManager.MATCH_UNINSTALLED_PACKAGES,
3629 userId).getList();
3630 } catch (RemoteException e) {
3631 throw new IllegalStateException("Package manager not available");
3632 }
3633
3634 final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
3635 for (PackageInfo info : packages) {
3636 // Check if the UID already has an entry in the table.
3637 final String uid = Integer.toString(info.applicationInfo.uid);
3638 final Setting ssaid = ssaidSettings.getSettingLocked(uid); // 这里呢?
3639
3640 if (ssaid.isNull() || ssaid.getValue() == null) {
3641 // Android Id doesn't exist for this package so create it.
3642 ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
3643 info.packageName);
3644 if (DEBUG) {
3645 Slog.d(LOG_TAG, "Keep the legacy ssaid for uid=" + uid);
3646 }
3647 }
3648 }
3649 }
3650
3651 currentVersion = 137;
这个插入代码?
http://www.aospxref.com/android-10.0.0_r2/xref/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java#2400
3002 @GuardedBy("secureSettings.mLock")
3003 private void ensureSecureSettingAndroidIdSetLocked(SettingsState secureSettings) {
3004 Setting value = secureSettings.getSettingLocked(Settings.Secure.ANDROID_ID);
3005
3006 if (!value.isNull()) {
3007 return;
3008 }
3009
3010 final int userId = getUserIdFromKey(secureSettings.mKey);
3011
3012 final UserInfo user;
3013 final long identity = Binder.clearCallingIdentity();
3014 try {
3015 user = mUserManager.getUserInfo(userId);
3016 } finally {
3017 Binder.restoreCallingIdentity(identity);
3018 }
3019 if (user == null) {
3020 // Can happen due to races when deleting users - treat as benign.
3021 return;
3022 }
3023
3024 String androidId = Long.toHexString(new SecureRandom().nextLong()); // 这里就是了
3025 secureSettings.insertSettingLocked(Settings.Secure.ANDROID_ID, androidId,
3026 null, true, SettingsState.SYSTEM_PACKAGE_NAME);
3027
3028 Slog.d(LOG_TAG, "Generated and saved new ANDROID_ID [" + androidId
3029 + "] for user " + userId);
3030
3031 // Write a drop box entry if it's a restricted profile
3032 if (user.isRestricted()) {
3033 DropBoxManager dbm = (DropBoxManager) getContext().getSystemService(
3034 Context.DROPBOX_SERVICE);
3035 if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
3036 dbm.addText(DROPBOX_TAG_USERLOG, System.currentTimeMillis()
3037 + "," + DROPBOX_TAG_USERLOG + "," + androidId + "\n");
3038 }
3039 }
3040 }
2400 private void generateUserKeyLocked(int userId) {
2401 // Generate a random key for each user used for creating a new ssaid.
2402 final byte[] keyBytes = new byte[32];
2403 final SecureRandom rand = new SecureRandom();
2404 rand.nextBytes(keyBytes);
2405
2406 // Convert to string for storage in settings table.
2407 final String userKey = ByteStringUtils.toHexString(keyBytes);
2408
2409 // Store the key in the ssaid table.
2410 final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
2411 final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null, //这个 userkey 就是 value
2412 true, SettingsState.SYSTEM_PACKAGE_NAME);
2413
2414 if (!success) {
2415 throw new IllegalStateException("Ssaid settings not accessible");
2416 }
2417 }
1417 // Retrieve the ssaid from the table if present.
1418 final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
1419 name);
1420 // If the app is an Instant App use its stored SSAID instead of our own.
1421 final String instantSsaid;
1422 final long token = Binder.clearCallingIdentity();
1423 try {
1424 instantSsaid = mPackageManager.getInstantAppAndroidId(callingPkg.packageName, // 这个就是 value ,怎么通过 intent 传递到的呢?
1425 owningUserId);
1426 } catch (RemoteException e) {
1427 Slog.e(LOG_TAG, "Failed to get Instant App Android ID", e);
1428 return null;
1429 } finally {
1430 Binder.restoreCallingIdentity(token);
1431 }
1432
1433 final SettingsState ssaidSettings = mSettingsRegistry.getSettingsLocked(
1434 SETTINGS_TYPE_SSAID, owningUserId);
1435
1436 if (instantSsaid != null) {
1437 // Use the stored value if it is still valid.
1438 if (ssaid != null && instantSsaid.equals(ssaid.getValue())) {
1439 return mascaradeSsaidSetting(ssaidSettings, ssaid);
1440 }
1441 // The value has changed, update the stored value.
1442 final boolean success = ssaidSettings.insertSettingLocked(name, instantSsaid, null,
1443 true, callingPkg.packageName);
1444 if (!success) {
网友评论