1d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn/*
2d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * Copyright (C) 2017 The Android Open Source Project
3d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn *
4d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * Licensed under the Apache License, Version 2.0 (the "License");
5d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * you may not use this file except in compliance with the License.
6d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * You may obtain a copy of the License at
7d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn *
8d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn *      http://www.apache.org/licenses/LICENSE-2.0
9d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn *
10d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * Unless required by applicable law or agreed to in writing, software
11d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * distributed under the License is distributed on an "AS IS" BASIS,
12d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * See the License for the specific language governing permissions and
14d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * limitations under the License
15d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn */
16d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
17d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynpackage com.android.server.fingerprint;
18d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
19d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport android.content.Context;
20d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport android.hardware.fingerprint.Fingerprint;
21d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport android.hardware.fingerprint.IFingerprintServiceReceiver;
22d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport android.os.IBinder;
23d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport android.util.Slog;
24d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport java.util.ArrayList;
25d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynimport java.util.List;
26d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
27d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn/**
28d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn * An internal class to help clean up unknown fingerprints in the hardware and software
29d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn */
30d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chynpublic abstract class InternalEnumerateClient extends EnumerateClient {
31d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
32d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    private List<Fingerprint> mEnrolledList;
33d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    private List<Fingerprint> mEnumeratedList = new ArrayList<>(); // list of fp to delete
34d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
35d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    public InternalEnumerateClient(Context context, long halDeviceId, IBinder token,
36d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            IFingerprintServiceReceiver receiver, int groupId, int userId,
37d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            boolean restricted, String owner, List<Fingerprint> enrolledList) {
38d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
39d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner);
40d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        mEnrolledList = enrolledList;
41d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    }
42d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
43d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    private void handleEnumeratedFingerprint(int fingerId, int groupId, int remaining) {
44d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
45d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        boolean matched = false;
46d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        for (int i=0; i<mEnrolledList.size(); i++) {
47d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            if (mEnrolledList.get(i).getFingerId() == fingerId) {
48d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                mEnrolledList.remove(i);
49d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                matched = true;
50d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                Slog.e(TAG, "Matched fingerprint fid=" + fingerId);
51d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                break;
52d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            }
53d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        }
54d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
55d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        // fingerId 0 means no fingerprints are in hardware
56d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        if (!matched && fingerId != 0) {
57d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            Fingerprint fingerprint = new Fingerprint("", groupId, fingerId, getHalDeviceId());
58d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            mEnumeratedList.add(fingerprint);
59d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        }
60d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    }
61d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
62d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    private void doFingerprintCleanup() {
63d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
64d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        if (mEnrolledList == null) {
65d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            return;
66d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        }
67d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
68d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        for (Fingerprint f : mEnrolledList) {
69d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            Slog.e(TAG, "Internal Enumerate: Removing dangling enrolled fingerprint: "
70d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                    + f.getName() + " " + f.getFingerId() + " " + f.getGroupId()
71d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                    + " " + f.getDeviceId());
72d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
73d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            FingerprintUtils.getInstance().removeFingerprintIdForUser(getContext(),
74d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn                    f.getFingerId(), getTargetUserId());
75d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        }
76d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        mEnrolledList.clear();
77d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    }
78d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
79d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    public List<Fingerprint> getEnumeratedList() {
80d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        return mEnumeratedList;
81d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    }
82d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
83d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    @Override
84d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    public boolean onEnumerationResult(int fingerId, int groupId, int remaining) {
85d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
86d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        handleEnumeratedFingerprint(fingerId, groupId, remaining);
87d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        if (remaining == 0) {
88d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn            doFingerprintCleanup();
89d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        }
90d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
91d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn        return fingerId == 0; // done when id hits 0
92d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn    }
93d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn
94d1f1a0b60a660cbff9efdf77c2aed11e1f7061f2Kevin Chyn}
95