Merge "Roll forward SSAID Migration to be Per App/User Unique Values."
This commit is contained in:
82
core/java/android/util/ByteStringUtils.java
Normal file
82
core/java/android/util/ByteStringUtils.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.util;
|
||||
|
||||
/**
|
||||
* A utility class for common byte array to hex string operations and vise versa.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class ByteStringUtils {
|
||||
private final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
private ByteStringUtils() {
|
||||
/* hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hex encoded string representation of bytes.
|
||||
* @param bytes Byte array to encode.
|
||||
* @return Hex encoded string representation of bytes.
|
||||
*/
|
||||
public static String toString(byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0 || bytes.length % 2 != 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int byteLength = bytes.length;
|
||||
final int charCount = 2 * byteLength;
|
||||
final char[] chars = new char[charCount];
|
||||
|
||||
for (int i = 0; i < byteLength; i++) {
|
||||
final int byteHex = bytes[i] & 0xFF;
|
||||
chars[i * 2] = HEX_ARRAY[byteHex >>> 4];
|
||||
chars[i * 2 + 1] = HEX_ARRAY[byteHex & 0x0F];
|
||||
}
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the decoded byte array representation of str.
|
||||
* @param str Hex encoded string to decode.
|
||||
* @return Decoded byte array representation of str.
|
||||
*/
|
||||
public static byte[] toByteArray(String str) {
|
||||
if (str == null || str.length() == 0 || str.length() % 2 != 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final char[] chars = str.toCharArray();
|
||||
final int charLength = chars.length;
|
||||
final byte[] bytes = new byte[charLength / 2];
|
||||
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] =
|
||||
(byte)(((getIndex(chars[i * 2]) << 4) & 0xF0) | (getIndex(chars[i * 2 + 1]) & 0x0F));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static int getIndex(char c) {
|
||||
for (int i = 0; i < HEX_ARRAY.length; i++) {
|
||||
if (HEX_ARRAY[i] == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import java.security.NoSuchAlgorithmException;
|
||||
* @hide
|
||||
*/
|
||||
public final class PackageUtils {
|
||||
private final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
private PackageUtils() {
|
||||
/* hide constructor */
|
||||
@@ -81,16 +80,6 @@ public final class PackageUtils {
|
||||
|
||||
messageDigest.update(data);
|
||||
|
||||
final byte[] digest = messageDigest.digest();
|
||||
final int digestLength = digest.length;
|
||||
final int charCount = 2 * digestLength;
|
||||
|
||||
final char[] chars = new char[charCount];
|
||||
for (int i = 0; i < digestLength; i++) {
|
||||
final int byteHex = digest[i] & 0xFF;
|
||||
chars[i * 2] = HEX_ARRAY[byteHex >>> 4];
|
||||
chars[i * 2 + 1] = HEX_ARRAY[byteHex & 0x0F];
|
||||
}
|
||||
return new String(chars);
|
||||
return ByteStringUtils.toString(messageDigest.digest());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,4 +364,20 @@ public class SettingsProviderTest extends AndroidTestCase {
|
||||
// one or more activity can handle this intent.
|
||||
assertTrue(resolveInfoList.size() > 0);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testValidSsaid() {
|
||||
ContentResolver r = getContext().getContentResolver();
|
||||
|
||||
// Verify ssaid
|
||||
String ssaid = Settings.Secure.getString(r, Settings.Secure.ANDROID_ID);
|
||||
assertTrue(ssaid != null);
|
||||
assertTrue(ssaid.length() == 16);
|
||||
|
||||
String ssaid2 = Settings.Secure.getString(r, Settings.Secure.ANDROID_ID);
|
||||
assertTrue(ssaid2 != null);
|
||||
assertTrue(ssaid2.length() == 16);
|
||||
|
||||
assertTrue(ssaid.equals(ssaid2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import android.provider.Settings.Global;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.ByteStringUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -76,9 +77,13 @@ import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -162,6 +167,7 @@ public class SettingsProvider extends ContentProvider {
|
||||
public static final int SETTINGS_TYPE_GLOBAL = 0;
|
||||
public static final int SETTINGS_TYPE_SYSTEM = 1;
|
||||
public static final int SETTINGS_TYPE_SECURE = 2;
|
||||
public static final int SETTINGS_TYPE_SSAID = 3;
|
||||
|
||||
public static final int SETTINGS_TYPE_MASK = 0xF0000000;
|
||||
public static final int SETTINGS_TYPE_SHIFT = 28;
|
||||
@@ -249,6 +255,9 @@ public class SettingsProvider extends ContentProvider {
|
||||
case SETTINGS_TYPE_SYSTEM: {
|
||||
return "SETTINGS_SYSTEM";
|
||||
}
|
||||
case SETTINGS_TYPE_SSAID: {
|
||||
return "SETTINGS_SSAID";
|
||||
}
|
||||
default: {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
@@ -704,6 +713,13 @@ public class SettingsProvider extends ContentProvider {
|
||||
UserHandle.getUserId(uid));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUidRemoved(int uid) {
|
||||
synchronized (mLock) {
|
||||
mSettingsRegistry.onUidRemovedLocked(uid);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// package changes
|
||||
@@ -957,8 +973,15 @@ public class SettingsProvider extends ContentProvider {
|
||||
continue;
|
||||
}
|
||||
|
||||
Setting setting = mSettingsRegistry.getSettingLocked(
|
||||
SETTINGS_TYPE_SECURE, owningUserId, name);
|
||||
// As of Android O (API 24), the SSAID is read from an app-specific entry in table
|
||||
// SETTINGS_FILE_SSAID, unless accessed by a system process.
|
||||
final Setting setting;
|
||||
if (isNewSsaidSetting(name)) {
|
||||
setting = getSsaidSettingLocked(owningUserId);
|
||||
} else {
|
||||
setting = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE, owningUserId,
|
||||
name);
|
||||
}
|
||||
appendSettingToCursor(result, setting);
|
||||
}
|
||||
|
||||
@@ -986,11 +1009,43 @@ public class SettingsProvider extends ContentProvider {
|
||||
|
||||
// Get the value.
|
||||
synchronized (mLock) {
|
||||
// As of Android O (API 24), the SSAID is read from an app-specific entry in table
|
||||
// SETTINGS_FILE_SSAID, unless accessed by a system process.
|
||||
if (isNewSsaidSetting(name)) {
|
||||
return getSsaidSettingLocked(owningUserId);
|
||||
}
|
||||
|
||||
return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SECURE,
|
||||
owningUserId, name);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNewSsaidSetting(String name) {
|
||||
return Settings.Secure.ANDROID_ID.equals(name)
|
||||
&& UserHandle.getAppId(Binder.getCallingUid()) >= Process.FIRST_APPLICATION_UID;
|
||||
}
|
||||
|
||||
private Setting getSsaidSettingLocked(int owningUserId) {
|
||||
// Get uid of caller (key) used to store ssaid value
|
||||
String name = Integer.toString(
|
||||
UserHandle.getUid(owningUserId, UserHandle.getAppId(Binder.getCallingUid())));
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.v(LOG_TAG, "getSsaidSettingLocked(" + name + "," + owningUserId + ")");
|
||||
}
|
||||
|
||||
// Retrieve the ssaid from the table if present.
|
||||
final Setting ssaid = mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_SSAID, owningUserId,
|
||||
name);
|
||||
|
||||
// Lazy initialize ssaid if not yet present in ssaid table.
|
||||
if (ssaid.isNull() || ssaid.getValue() == null) {
|
||||
return mSettingsRegistry.generateSsaidLocked(getCallingPackage(), owningUserId);
|
||||
}
|
||||
|
||||
return ssaid;
|
||||
}
|
||||
|
||||
private boolean insertSecureSetting(String name, String value, String tag,
|
||||
boolean makeDefault, int requestingUserId, boolean forceNotify) {
|
||||
if (DEBUG) {
|
||||
@@ -1818,6 +1873,9 @@ public class SettingsProvider extends ContentProvider {
|
||||
private static final String SETTINGS_FILE_GLOBAL = "settings_global.xml";
|
||||
private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
|
||||
private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
|
||||
private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
|
||||
|
||||
private static final String SSAID_USER_KEY = "userkey";
|
||||
|
||||
private final SparseArray<SettingsState> mSettingsStates = new SparseArray<>();
|
||||
|
||||
@@ -1832,6 +1890,115 @@ public class SettingsProvider extends ContentProvider {
|
||||
mGenerationRegistry = new GenerationRegistry(mLock);
|
||||
mBackupManager = new BackupManager(getContext());
|
||||
migrateAllLegacySettingsIfNeeded();
|
||||
syncSsaidTableOnStart();
|
||||
}
|
||||
|
||||
private void generateUserKeyLocked(int userId) {
|
||||
// Generate a random key for each user used for creating a new ssaid.
|
||||
final byte[] keyBytes = new byte[16];
|
||||
final SecureRandom rand = new SecureRandom();
|
||||
rand.nextBytes(keyBytes);
|
||||
|
||||
// Convert to string for storage in settings table.
|
||||
final String userKey = ByteStringUtils.toString(keyBytes);
|
||||
|
||||
// Store the key in the ssaid table.
|
||||
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
|
||||
final boolean success = ssaidSettings.insertSettingLocked(SSAID_USER_KEY, userKey, null,
|
||||
true, SettingsState.SYSTEM_PACKAGE_NAME);
|
||||
|
||||
if (!success) {
|
||||
throw new IllegalStateException("Ssaid settings not accessible");
|
||||
}
|
||||
}
|
||||
|
||||
public Setting generateSsaidLocked(String packageName, int userId) {
|
||||
final PackageInfo packageInfo;
|
||||
try {
|
||||
packageInfo = mPackageManager.getPackageInfo(packageName,
|
||||
PackageManager.GET_SIGNATURES, userId);
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Package info doesn't exist");
|
||||
}
|
||||
|
||||
// Read the user's key from the ssaid table.
|
||||
Setting userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
|
||||
if (userKeySetting.isNull() || userKeySetting.getValue() == null) {
|
||||
// Lazy initialize and store the user key.
|
||||
generateUserKeyLocked(userId);
|
||||
userKeySetting = getSettingLocked(SETTINGS_TYPE_SSAID, userId, SSAID_USER_KEY);
|
||||
if (userKeySetting.isNull() || userKeySetting.getValue() == null) {
|
||||
throw new IllegalStateException("User key not accessible");
|
||||
}
|
||||
}
|
||||
final String userKey = userKeySetting.getValue();
|
||||
|
||||
// Convert the user's key back to a byte array.
|
||||
final byte[] keyBytes = ByteStringUtils.toByteArray(userKey);
|
||||
if (keyBytes == null || keyBytes.length != 16) {
|
||||
throw new IllegalStateException("User key invalid");
|
||||
}
|
||||
|
||||
final MessageDigest md;
|
||||
try {
|
||||
// Hash package name and signature.
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("HmacSHA256 is not available");
|
||||
}
|
||||
md.update(keyBytes);
|
||||
md.update(packageInfo.packageName.getBytes(StandardCharsets.UTF_8));
|
||||
md.update(packageInfo.signatures[0].toByteArray());
|
||||
|
||||
// Convert result to a string for storage in settings table. Only want first 64 bits.
|
||||
final String ssaid = ByteStringUtils.toString(md.digest()).substring(0, 16)
|
||||
.toLowerCase();
|
||||
|
||||
// Save the ssaid in the ssaid table.
|
||||
final String uid = Integer.toString(packageInfo.applicationInfo.uid);
|
||||
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
|
||||
final boolean success = ssaidSettings.insertSettingLocked(uid, ssaid, null, true,
|
||||
packageName);
|
||||
|
||||
if (!success) {
|
||||
throw new IllegalStateException("Ssaid settings not accessible");
|
||||
}
|
||||
|
||||
return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid);
|
||||
}
|
||||
|
||||
public void syncSsaidTableOnStart() {
|
||||
synchronized (mLock) {
|
||||
// Verify that each user's packages and ssaid's are in sync.
|
||||
for (UserInfo user : mUserManager.getUsers(true)) {
|
||||
// Get all uids for the user's packages.
|
||||
final List<PackageInfo> packages;
|
||||
try {
|
||||
packages = mPackageManager.getInstalledPackages(0, user.id).getList();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Package manager not available");
|
||||
}
|
||||
final Set<String> appUids = new HashSet<>();
|
||||
for (PackageInfo info : packages) {
|
||||
appUids.add(Integer.toString(info.applicationInfo.uid));
|
||||
}
|
||||
|
||||
// Get all uids currently stored in the user's ssaid table.
|
||||
final Set<String> ssaidUids = new HashSet<>(
|
||||
getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id));
|
||||
ssaidUids.remove(SSAID_USER_KEY);
|
||||
|
||||
// Perform a set difference for the appUids and ssaidUids.
|
||||
ssaidUids.removeAll(appUids);
|
||||
|
||||
// If there are ssaidUids left over they need to be removed from the table.
|
||||
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
|
||||
user.id);
|
||||
for (String uid : ssaidUids) {
|
||||
ssaidSettings.deleteSettingLocked(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getSettingsNamesLocked(int type, int userId) {
|
||||
@@ -1884,6 +2051,10 @@ public class SettingsProvider extends ContentProvider {
|
||||
final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
|
||||
ensureSettingsStateLocked(systemKey);
|
||||
|
||||
// Ensure secure settings loaded.
|
||||
final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
|
||||
ensureSettingsStateLocked(ssaidKey);
|
||||
|
||||
// Upgrade the settings to the latest version.
|
||||
UpgradeController upgrader = new UpgradeController(userId);
|
||||
upgrader.upgradeIfNeededLocked();
|
||||
@@ -1936,6 +2107,23 @@ public class SettingsProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// Nuke ssaid settings.
|
||||
final int ssaidKey = makeKey(SETTINGS_TYPE_SSAID, userId);
|
||||
final SettingsState ssaidSettingsState = mSettingsStates.get(ssaidKey);
|
||||
if (ssaidSettingsState != null) {
|
||||
if (permanently) {
|
||||
mSettingsStates.remove(ssaidKey);
|
||||
ssaidSettingsState.destroyLocked(null);
|
||||
} else {
|
||||
ssaidSettingsState.destroyLocked(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSettingsStates.remove(ssaidKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Nuke generation tracking data
|
||||
mGenerationRegistry.onUserRemoved(userId);
|
||||
}
|
||||
@@ -1977,8 +2165,10 @@ public class SettingsProvider extends ContentProvider {
|
||||
|
||||
SettingsState settingsState = peekSettingsStateLocked(key);
|
||||
if (settingsState == null) {
|
||||
return null;
|
||||
return settingsState.getNullSetting();
|
||||
}
|
||||
|
||||
// getSettingLocked will return non-null result
|
||||
return settingsState.getSettingLocked(name);
|
||||
}
|
||||
|
||||
@@ -2079,6 +2269,12 @@ public class SettingsProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public void onUidRemovedLocked(int uid) {
|
||||
final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID,
|
||||
UserHandle.getUserId(uid));
|
||||
ssaidSettings.deleteSettingLocked(Integer.toString(uid));
|
||||
}
|
||||
|
||||
private SettingsState peekSettingsStateLocked(int key) {
|
||||
SettingsState settingsState = mSettingsStates.get(key);
|
||||
if (settingsState != null) {
|
||||
@@ -2300,6 +2496,10 @@ public class SettingsProvider extends ContentProvider {
|
||||
return getTypeFromKey(key) == SETTINGS_TYPE_SECURE;
|
||||
}
|
||||
|
||||
private boolean isSsaidSettingsKey(int key) {
|
||||
return getTypeFromKey(key) == SETTINGS_TYPE_SSAID;
|
||||
}
|
||||
|
||||
private File getSettingsFile(int key) {
|
||||
if (isGlobalSettingsKey(key)) {
|
||||
final int userId = getUserIdFromKey(key);
|
||||
@@ -2313,6 +2513,10 @@ public class SettingsProvider extends ContentProvider {
|
||||
final int userId = getUserIdFromKey(key);
|
||||
return new File(Environment.getUserSystemDirectory(userId),
|
||||
SETTINGS_FILE_SECURE);
|
||||
} else if (isSsaidSettingsKey(key)) {
|
||||
final int userId = getUserIdFromKey(key);
|
||||
return new File(Environment.getUserSystemDirectory(userId),
|
||||
SETTINGS_FILE_SSAID);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid settings key:" + key);
|
||||
}
|
||||
@@ -2336,7 +2540,8 @@ public class SettingsProvider extends ContentProvider {
|
||||
private int getMaxBytesPerPackageForType(int type) {
|
||||
switch (type) {
|
||||
case SETTINGS_TYPE_GLOBAL:
|
||||
case SETTINGS_TYPE_SECURE: {
|
||||
case SETTINGS_TYPE_SECURE:
|
||||
case SETTINGS_TYPE_SSAID: {
|
||||
return SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED;
|
||||
}
|
||||
|
||||
@@ -2374,7 +2579,7 @@ public class SettingsProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
private final class UpgradeController {
|
||||
private static final int SETTINGS_VERSION = 136;
|
||||
private static final int SETTINGS_VERSION = 137;
|
||||
|
||||
private final int mUserId;
|
||||
|
||||
@@ -2447,6 +2652,10 @@ public class SettingsProvider extends ContentProvider {
|
||||
return getSettingsLocked(SETTINGS_TYPE_SECURE, userId);
|
||||
}
|
||||
|
||||
private SettingsState getSsaidSettingsLocked(int userId) {
|
||||
return getSettingsLocked(SETTINGS_TYPE_SSAID, userId);
|
||||
}
|
||||
|
||||
private SettingsState getSystemSettingsLocked(int userId) {
|
||||
return getSettingsLocked(SETTINGS_TYPE_SYSTEM, userId);
|
||||
}
|
||||
@@ -2776,6 +2985,48 @@ public class SettingsProvider extends ContentProvider {
|
||||
currentVersion = 136;
|
||||
}
|
||||
|
||||
if (currentVersion == 136) {
|
||||
// Version 136: Store legacy SSAID for all apps currently installed on the
|
||||
// device as first step in migrating SSAID to be unique per application.
|
||||
|
||||
final boolean isUpgrade;
|
||||
try {
|
||||
isUpgrade = mPackageManager.isUpgrade();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Package manager not available");
|
||||
}
|
||||
// Only retain legacy ssaid if the device is performing an OTA. After wiping
|
||||
// user data or first boot on a new device should use new ssaid generation.
|
||||
if (isUpgrade) {
|
||||
// Retrieve the legacy ssaid from the secure settings table.
|
||||
final String legacySsaid = getSettingLocked(SETTINGS_TYPE_SECURE, userId,
|
||||
Settings.Secure.ANDROID_ID).getValue();
|
||||
|
||||
// Fill each uid with the legacy ssaid to be backwards compatible.
|
||||
final List<PackageInfo> packages;
|
||||
try {
|
||||
packages = mPackageManager.getInstalledPackages(0, userId).getList();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Package manager not available");
|
||||
}
|
||||
|
||||
final SettingsState ssaidSettings = getSsaidSettingsLocked(userId);
|
||||
for (PackageInfo info : packages) {
|
||||
// Check if the UID already has an entry in the table.
|
||||
final String uid = Integer.toString(info.applicationInfo.uid);
|
||||
final Setting ssaid = ssaidSettings.getSettingLocked(uid);
|
||||
|
||||
if (ssaid.isNull() || ssaid.getValue() == null) {
|
||||
// Android Id doesn't exist for this package so create it.
|
||||
ssaidSettings.insertSettingLocked(uid, legacySsaid, null, true,
|
||||
info.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentVersion = 137;
|
||||
}
|
||||
|
||||
if (currentVersion != newVersion) {
|
||||
Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
|
||||
+ newVersion + " left it at "
|
||||
|
||||
Reference in New Issue
Block a user