am 131a19ee: Merge "Persist fingerprint names" into mnc-dev
* commit '131a19ee6f55d95d747d3d1ed62537b1db5a2e69': Persist fingerprint names
This commit is contained in:
@@ -1,126 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2014 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.hardware.fingerprint;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with fingerprints and fingerprint settings.
|
||||
* @hide
|
||||
*/
|
||||
public
|
||||
class FingerprintUtils {
|
||||
private static final boolean DEBUG = true;
|
||||
private static final String TAG = "FingerprintUtils";
|
||||
private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
|
||||
private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
|
||||
|
||||
private static int[] toIntArray(List<Integer> list) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
int[] arr = new int[list.size()];
|
||||
int i = 0;
|
||||
for (int elem : list) {
|
||||
arr[i] = elem;
|
||||
i++;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static int[] getFingerprintIdsForUser(ContentResolver res, int userId) {
|
||||
String fingerIdsRaw = Settings.Secure.getStringForUser(res,
|
||||
Settings.Secure.USER_FINGERPRINT_IDS, userId);
|
||||
ArrayList<Integer> tmp = new ArrayList<Integer>();
|
||||
if (!TextUtils.isEmpty(fingerIdsRaw)) {
|
||||
String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
|
||||
int length = fingerStringIds.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
tmp.add(Integer.decode(fingerStringIds[i]));
|
||||
} catch (NumberFormatException e) {
|
||||
if (DEBUG) Log.w(TAG, "Error parsing finger id: '" + fingerStringIds[i] + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return toIntArray(tmp);
|
||||
}
|
||||
|
||||
public static void addFingerprintIdForUser(ContentResolver res, int fingerId, int userId) {
|
||||
// FingerId 0 has special meaning.
|
||||
if (fingerId == 0) {
|
||||
Log.w(TAG, "Tried to add fingerId 0");
|
||||
return;
|
||||
}
|
||||
|
||||
int[] fingerIds = getFingerprintIdsForUser(res, userId);
|
||||
|
||||
// Don't allow dups
|
||||
if (ArrayUtils.contains(fingerIds, fingerId)) {
|
||||
Log.w(TAG, "finger already added " + fingerId);
|
||||
return;
|
||||
}
|
||||
int[] newList = Arrays.copyOf(fingerIds, fingerIds.length + 1);
|
||||
newList[fingerIds.length] = fingerId;
|
||||
Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
|
||||
Arrays.toString(newList), userId);
|
||||
}
|
||||
|
||||
public static boolean removeFingerprintIdForUser(int fingerId, ContentResolver res, int userId)
|
||||
{
|
||||
// FingerId 0 has special meaning. The HAL layer is supposed to remove each finger one
|
||||
// at a time and invoke notify() for each fingerId. If we get called with 0 here, it means
|
||||
// something bad has happened.
|
||||
if (fingerId == 0) throw new IllegalArgumentException("fingerId can't be 0");
|
||||
|
||||
final int[] fingerIds = getFingerprintIdsForUser(res, userId);
|
||||
if (ArrayUtils.contains(fingerIds, fingerId)) {
|
||||
final int[] result = ArrayUtils.removeInt(fingerIds, fingerId);
|
||||
Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
|
||||
Arrays.toString(result), userId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void vibrateFingerprintError(Context context) {
|
||||
Vibrator vibrator = context.getSystemService(Vibrator.class);
|
||||
if (vibrator != null) {
|
||||
vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void vibrateFingerprintSuccess(Context context) {
|
||||
Vibrator vibrator = context.getSystemService(Vibrator.class);
|
||||
if (vibrator != null) {
|
||||
vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -4362,12 +4362,6 @@ public final class Settings {
|
||||
public static final String LOCK_SCREEN_APPWIDGET_IDS =
|
||||
"lock_screen_appwidget_ids";
|
||||
|
||||
/**
|
||||
* List of enrolled fingerprint identifiers (comma-delimited).
|
||||
* @hide
|
||||
*/
|
||||
public static final String USER_FINGERPRINT_IDS = "user_fingerprint_ids";
|
||||
|
||||
/**
|
||||
* Id of the appwidget shown on the lock screen when appwidgets are disabled.
|
||||
* @hide
|
||||
|
||||
@@ -1255,6 +1255,9 @@
|
||||
<!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
|
||||
<string name="fingerprint_error_unable_to_process">Try again.</string>
|
||||
|
||||
<!-- Template to be used to name enrolled fingerprints by default. -->
|
||||
<string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
|
||||
|
||||
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
|
||||
<string-array name="fingerprint_error_vendor">
|
||||
</string-array>
|
||||
|
||||
@@ -2112,6 +2112,7 @@
|
||||
<java-symbol type="array" name="fingerprint_acquired_vendor" />
|
||||
<java-symbol type="string" name="fingerprint_error_canceled" />
|
||||
<java-symbol type="string" name="fingerprint_error_lockout" />
|
||||
<java-symbol type="string" name="fingerprint_name_template" />
|
||||
|
||||
<!-- From various Material changes -->
|
||||
<java-symbol type="attr" name="titleTextAppearance" />
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.app.PendingIntent;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -56,7 +55,6 @@ import com.android.internal.telephony.TelephonyIntents;
|
||||
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
||||
import android.hardware.fingerprint.FingerprintUtils;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
@@ -367,14 +365,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
|
||||
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
|
||||
return;
|
||||
}
|
||||
final ContentResolver res = mContext.getContentResolver();
|
||||
final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId);
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
// TODO: fix once HAL supports storing group id
|
||||
final boolean isCorrectUser = true || (groupId == userId);
|
||||
if (ids[i] == fingerId && isCorrectUser) {
|
||||
onFingerprintAuthenticated(userId);
|
||||
}
|
||||
if (groupId == userId) {
|
||||
onFingerprintAuthenticated(groupId);
|
||||
}
|
||||
} finally {
|
||||
setFingerprintRunningDetectionRunning(false);
|
||||
|
||||
@@ -31,7 +31,6 @@ import android.util.Slog;
|
||||
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import android.hardware.fingerprint.FingerprintUtils;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.IFingerprintService;
|
||||
@@ -93,6 +92,7 @@ public class FingerprintService extends SystemService {
|
||||
private Context mContext;
|
||||
private int mHalDeviceId;
|
||||
private int mFailedAttempts;
|
||||
private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
|
||||
private final Runnable mLockoutReset = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -172,7 +172,6 @@ public class FingerprintService extends SystemService {
|
||||
* @return true if the operation is done, i.e. authentication completed
|
||||
*/
|
||||
boolean dispatchNotify(ClientMonitor clientMonitor, int type, int arg1, int arg2, int arg3) {
|
||||
ContentResolver contentResolver = mContext.getContentResolver();
|
||||
boolean operationCompleted = false;
|
||||
int fpId;
|
||||
int groupId;
|
||||
@@ -198,7 +197,7 @@ public class FingerprintService extends SystemService {
|
||||
remaining = arg3;
|
||||
operationCompleted = clientMonitor.sendEnrollResult(fpId, groupId, remaining);
|
||||
if (remaining == 0) {
|
||||
addTemplateForUser(clientMonitor, contentResolver, fpId);
|
||||
addTemplateForUser(clientMonitor, fpId);
|
||||
operationCompleted = true; // enroll completed
|
||||
}
|
||||
break;
|
||||
@@ -207,7 +206,7 @@ public class FingerprintService extends SystemService {
|
||||
groupId = arg2;
|
||||
operationCompleted = clientMonitor.sendRemoved(fpId, groupId);
|
||||
if (fpId != 0) {
|
||||
removeTemplateForUser(clientMonitor, contentResolver, fpId);
|
||||
removeTemplateForUser(clientMonitor, fpId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -252,16 +251,12 @@ public class FingerprintService extends SystemService {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void removeTemplateForUser(ClientMonitor clientMonitor, ContentResolver contentResolver,
|
||||
final int fingerId) {
|
||||
FingerprintUtils.removeFingerprintIdForUser(fingerId, contentResolver,
|
||||
clientMonitor.userId);
|
||||
private void removeTemplateForUser(ClientMonitor clientMonitor, int fingerId) {
|
||||
mFingerprintUtils.removeFingerprintIdForUser(mContext, fingerId, clientMonitor.userId);
|
||||
}
|
||||
|
||||
private void addTemplateForUser(ClientMonitor clientMonitor, ContentResolver contentResolver,
|
||||
final int fingerId) {
|
||||
FingerprintUtils.addFingerprintIdForUser(contentResolver, fingerId,
|
||||
clientMonitor.userId);
|
||||
private void addTemplateForUser(ClientMonitor clientMonitor, int fingerId) {
|
||||
mFingerprintUtils.addFingerprintForUser(mContext, fingerId, clientMonitor.userId);
|
||||
}
|
||||
|
||||
void startEnrollment(IBinder token, byte[] cryptoToken, int groupId,
|
||||
@@ -345,24 +340,11 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
|
||||
public List<Fingerprint> getEnrolledFingerprints(int groupId) {
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
int[] ids = FingerprintUtils.getFingerprintIdsForUser(resolver, groupId);
|
||||
List<Fingerprint> result = new ArrayList<Fingerprint>();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
// TODO: persist names in Settings
|
||||
CharSequence name = "Finger" + ids[i];
|
||||
final int group = 0; // TODO
|
||||
final int fingerId = ids[i];
|
||||
final long deviceId = 0; // TODO
|
||||
Fingerprint item = new Fingerprint(name, 0, ids[i], 0);
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
return mFingerprintUtils.getFingerprintsForUser(mContext, groupId);
|
||||
}
|
||||
|
||||
public boolean hasEnrolledFingerprints(int groupId) {
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
return FingerprintUtils.getFingerprintIdsForUser(resolver, groupId).length > 0;
|
||||
return mFingerprintUtils.getFingerprintsForUser(mContext, groupId).size() > 0;
|
||||
}
|
||||
|
||||
void checkPermission(String permission) {
|
||||
@@ -596,7 +578,7 @@ public class FingerprintService extends SystemService {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Slog.w(TAG, "rename id=" + fingerId + ",gid=" + groupId + ",name=" + name);
|
||||
mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, groupId, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (C) 2015 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 com.android.server.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.os.Vibrator;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with fingerprints and fingerprint settings.
|
||||
*/
|
||||
public class FingerprintUtils {
|
||||
|
||||
private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
|
||||
private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
|
||||
|
||||
private static final Object sInstanceLock = new Object();
|
||||
private static FingerprintUtils sInstance;
|
||||
|
||||
@GuardedBy("this")
|
||||
private final SparseArray<FingerprintsUserState> mUsers = new SparseArray<>();
|
||||
|
||||
public static FingerprintUtils getInstance() {
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FingerprintUtils();
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private FingerprintUtils() {
|
||||
}
|
||||
|
||||
public List<Fingerprint> getFingerprintsForUser(Context ctx, int userId) {
|
||||
return getStateForUser(ctx, userId).getFingerprints();
|
||||
}
|
||||
|
||||
public void addFingerprintForUser(Context ctx, int fingerId, int userId) {
|
||||
getStateForUser(ctx, userId).addFingerprint(fingerId);
|
||||
}
|
||||
|
||||
public void removeFingerprintIdForUser(Context ctx, int fingerId, int userId) {
|
||||
getStateForUser(ctx, userId).removeFingerprint(fingerId);
|
||||
}
|
||||
|
||||
public void renameFingerprintForUser(Context ctx, int fingerId, int userId, CharSequence name) {
|
||||
getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
|
||||
}
|
||||
|
||||
public static void vibrateFingerprintError(Context context) {
|
||||
Vibrator vibrator = context.getSystemService(Vibrator.class);
|
||||
if (vibrator != null) {
|
||||
vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void vibrateFingerprintSuccess(Context context) {
|
||||
Vibrator vibrator = context.getSystemService(Vibrator.class);
|
||||
if (vibrator != null) {
|
||||
vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private FingerprintsUserState getStateForUser(Context ctx, int userId) {
|
||||
synchronized (this) {
|
||||
FingerprintsUserState state = mUsers.get(userId);
|
||||
if (state == null) {
|
||||
state = new FingerprintsUserState(ctx, userId);
|
||||
mUsers.put(userId, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.server.fingerprint;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class managing the set of fingerprint per user across device reboots.
|
||||
*/
|
||||
class FingerprintsUserState {
|
||||
|
||||
private static final String TAG = "FingerprintState";
|
||||
private static final String FINGERPRINT_FILE = "settings_fingerprint.xml";
|
||||
|
||||
private static final String TAG_FINGERPRINTS = "fingerprints";
|
||||
private static final String TAG_FINGERPRINT = "fingerprint";
|
||||
private static final String ATTR_NAME = "name";
|
||||
private static final String ATTR_GROUP_ID = "groupId";
|
||||
private static final String ATTR_FINGER_ID = "fingerId";
|
||||
private static final String ATTR_DEVICE_ID = "deviceId";
|
||||
|
||||
private final File mFile;
|
||||
|
||||
@GuardedBy("this")
|
||||
private final ArrayList<Fingerprint> mFingerprints = new ArrayList<>();
|
||||
private final Context mCtx;
|
||||
|
||||
public FingerprintsUserState(Context ctx, int userId) {
|
||||
mFile = getFileForUser(userId);
|
||||
mCtx = ctx;
|
||||
synchronized (this) {
|
||||
readStateSyncLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public void addFingerprint(int fingerId) {
|
||||
synchronized (this) {
|
||||
mFingerprints.add(new Fingerprint(getDefaultFingerprintName(fingerId), 0, fingerId, 0));
|
||||
scheduleWriteStateLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFingerprint(int fingerId) {
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < mFingerprints.size(); i++) {
|
||||
if (mFingerprints.get(i).getFingerId() == fingerId) {
|
||||
mFingerprints.remove(i);
|
||||
scheduleWriteStateLocked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void renameFingerprint(int fingerId, CharSequence name) {
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < mFingerprints.size(); i++) {
|
||||
if (mFingerprints.get(i).getFingerId() == fingerId) {
|
||||
Fingerprint old = mFingerprints.get(i);
|
||||
mFingerprints.set(i, new Fingerprint(name, old.getGroupId(), old.getFingerId(),
|
||||
old.getDeviceId()));
|
||||
scheduleWriteStateLocked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Fingerprint> getFingerprints() {
|
||||
synchronized (this) {
|
||||
return getCopy(mFingerprints);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultFingerprintName(int fingerId) {
|
||||
return mCtx.getString(com.android.internal.R.string.fingerprint_name_template, fingerId);
|
||||
}
|
||||
|
||||
private static File getFileForUser(int userId) {
|
||||
return new File(Environment.getUserSystemDirectory(userId), FINGERPRINT_FILE);
|
||||
}
|
||||
|
||||
private final Runnable mWriteStateRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doWriteState();
|
||||
}
|
||||
};
|
||||
|
||||
private void scheduleWriteStateLocked() {
|
||||
AsyncTask.execute(mWriteStateRunnable);
|
||||
}
|
||||
|
||||
private ArrayList<Fingerprint> getCopy(ArrayList<Fingerprint> array) {
|
||||
ArrayList<Fingerprint> result = new ArrayList<>(array.size());
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
Fingerprint fp = array.get(i);
|
||||
result.add(new Fingerprint(fp.getName(), fp.getGroupId(), fp.getFingerId(),
|
||||
fp.getDeviceId()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void doWriteState() {
|
||||
AtomicFile destination = new AtomicFile(mFile);
|
||||
|
||||
ArrayList<Fingerprint> fingerprints;
|
||||
|
||||
synchronized (this) {
|
||||
fingerprints = getCopy(mFingerprints);
|
||||
}
|
||||
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = destination.startWrite();
|
||||
|
||||
XmlSerializer serializer = Xml.newSerializer();
|
||||
serializer.setOutput(out, "utf-8");
|
||||
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||
serializer.startDocument(null, true);
|
||||
serializer.startTag(null, TAG_FINGERPRINTS);
|
||||
|
||||
final int count = fingerprints.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Fingerprint fp = fingerprints.get(i);
|
||||
serializer.startTag(null, TAG_FINGERPRINT);
|
||||
serializer.attribute(null, ATTR_FINGER_ID, Integer.toString(fp.getFingerId()));
|
||||
serializer.attribute(null, ATTR_NAME, fp.getName().toString());
|
||||
serializer.attribute(null, ATTR_GROUP_ID, Integer.toString(fp.getGroupId()));
|
||||
serializer.attribute(null, ATTR_DEVICE_ID, Long.toString(fp.getDeviceId()));
|
||||
serializer.endTag(null, TAG_FINGERPRINT);
|
||||
}
|
||||
|
||||
serializer.endTag(null, TAG_FINGERPRINTS);
|
||||
serializer.endDocument();
|
||||
destination.finishWrite(out);
|
||||
|
||||
// Any error while writing is fatal.
|
||||
} catch (Throwable t) {
|
||||
Slog.wtf(TAG, "Failed to write settings, restoring backup", t);
|
||||
destination.failWrite(out);
|
||||
throw new IllegalStateException("Failed to write fingerprints", t);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
private void readStateSyncLocked() {
|
||||
FileInputStream in;
|
||||
if (!mFile.exists()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
in = new FileInputStream(mFile);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
Slog.i(TAG, "No fingerprint state");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(in, null);
|
||||
parseStateLocked(parser);
|
||||
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
throw new IllegalStateException("Failed parsing settings file: "
|
||||
+ mFile , e);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStateLocked(XmlPullParser parser)
|
||||
throws IOException, XmlPullParserException {
|
||||
final int outerDepth = parser.getDepth();
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
|
||||
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tagName = parser.getName();
|
||||
if (tagName.equals(TAG_FINGERPRINTS)) {
|
||||
parseFingerprintsLocked(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFingerprintsLocked(XmlPullParser parser)
|
||||
throws IOException, XmlPullParserException {
|
||||
|
||||
final int outerDepth = parser.getDepth();
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
|
||||
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tagName = parser.getName();
|
||||
if (tagName.equals(TAG_FINGERPRINT)) {
|
||||
String name = parser.getAttributeValue(null, ATTR_NAME);
|
||||
String groupId = parser.getAttributeValue(null, ATTR_GROUP_ID);
|
||||
String fingerId = parser.getAttributeValue(null, ATTR_FINGER_ID);
|
||||
String deviceId = parser.getAttributeValue(null, ATTR_DEVICE_ID);
|
||||
mFingerprints.add(new Fingerprint(name, Integer.parseInt(groupId),
|
||||
Integer.parseInt(fingerId), Integer.parseInt(deviceId)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user