LockSettingsService服务的主要作用:保存图案密码,数字密码的数据,多用户管理等.系统非核心服务,初始化构造方式上说明了这一点.该服务在SystemServer中进行启动,内部包含了LockPatternUtils工具类和locksettings.db数据库.
1,服务的初始化:
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
//if (!disableNonCoreServices) { // TODO: View depends on these; mock them?
if (true) {
try {
Slog.i(TAG, "Input Method Service");
imm = new InputMethodManagerService(context, wm);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
reportWtf("starting Input Manager Service", e);
}
try {
Slog.i(TAG, "Accessibility Manager");
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
new AccessibilityManagerService(context));
} catch (Throwable e) {
reportWtf("starting Accessibility Manager", e);
}
}
}
2,locksettings.db的位置.
在android系统中,应用的数据库文件在data/data//databases目录中.对于系统服务,其数据库源文件在/data/system目录内.具体详情可以参考ContextImpl.java的getDatabaseDir()方法.
ContextImpl.java
private File getDatabasesDir() {
synchronized (mSync) {
if (mDatabasesDir == null) {
mDatabasesDir = new File(getDataDirFile(), "databases");
}
if (mDatabasesDir.getPath().equals("databases")) {
mDatabasesDir = new File("/data/system");
}
return mDatabasesDir;
}
}
3,LockPatternUtils工具类常用的方法介绍:
3.1:isSecure():是否含有锁屏,图案,密码,复杂密码
3.2:getKeyguardStoredPasswordQuality();得到当前锁屏类型,其取值如下:
final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; final boolean isPassword = mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
3.3:isDeviceEncryptionEnabled():设备是否加密
4,图案密码数据保存位置:
图案密码调用LockPatternUtils工具类的saveLockPattern进行存储.
最终图案数据会存储在/data /system /gesture.key文件中.该方式不是最安全的,但有两层防护,第一:数据经过了SHA-1哈希转换.第二:数据文件只能系统进程能够读取.
/*
* Generate an SHA-1 hash for the pattern. Not the most secure, but it is
* at least a second level of protection. First level is that the file
* is in a location only readable by the system process.
* @param pattern the gesture pattern.
* @return the hash of the pattern in a byte array.
*/
public static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
if (pattern == null) {
return null;
}
final int patternSize = pattern.size();
byte[] res = new byte[patternSize];
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] hash = md.digest(res);
return hash;
} catch (NoSuchAlgorithmException nsa) {
return res;
}
}
5,数字密码数据保存位置:
数字密码调用LockPatternUtils工具类的saveLockPassword进行存储.
最终数字密码会存储在/data/system/password.key中,经过MD5加密.
public byte[] passwordToHash(String password, int userId) {
if (password == null) {
return null;
}
String algo = null;
byte[] hashed = null;
try {
byte[] saltedPassword = (password + getSalt(userId)).getBytes();
byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword);
byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword);
hashed = (toHex(sha1) + toHex(md5)).getBytes();
} catch (NoSuchAlgorithmException e) {
Log.w(TAG, "Failed to encode string because of missing algorithm: " + algo);
}
return hashed;
}