FieldClassification.java revision 329d04097e1db9b6f801972d94f56c5b56c09e8a
1bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme/*
2bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * Copyright (C) 2017 The Android Open Source Project
3bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *
4bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
5bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * you may not use this file except in compliance with the License.
6bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * You may obtain a copy of the License at
7bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *
8bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
9bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *
10bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * Unless required by applicable law or agreed to in writing, software
11bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
12bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * See the License for the specific language governing permissions and
14bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * limitations under the License.
15bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */
16bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
17bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemepackage android.service.autofill;
18bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
19bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport static android.view.autofill.Helper.sDebug;
20bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
21bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.annotation.NonNull;
22bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.annotation.TestApi;
23bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.os.Parcel;
24bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.os.Parcelable;
25bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.view.autofill.Helper;
26bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
27bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport com.android.internal.util.Preconditions;
28bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
29329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Lemeimport com.google.android.collect.Lists;
30329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme
31329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Lemeimport java.util.List;
32329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme
33bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme/**
34bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * Gets the <a href="#FieldsClassification">fields classification</a> results for a given field.
35bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *
36bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * TODO(b/67867469):
37bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * - improve javadoc
38bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * - unhide / remove testApi
39bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme *
40bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * @hide
41bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */
42bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme@TestApi
43bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemepublic final class FieldClassification implements Parcelable {
44bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
45bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    private final Match mMatch;
46bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
47bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    /** @hide */
48bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public FieldClassification(@NonNull Match match) {
49bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        mMatch = Preconditions.checkNotNull(match);
50bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
51bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
52bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    /**
53329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme     * Gets the {@link Match matches} with the highest {@link Match#getScore() scores}.
54329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme     *
55329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme     * <p><b>Note:</b> There's no guarantee of how many matches will be returned. In fact,
56329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme     * the Android System might return just the top match to minimize the impact of field
57329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme     * classification in the device's health.
58bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     */
59bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    @NonNull
60329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme    public List<Match> getMatches() {
61329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme        return Lists.newArrayList(mMatch);
62bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
63bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
64bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    @Override
65bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public String toString() {
66bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        if (!sDebug) return super.toString();
67bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
68bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        return "FieldClassification: " + mMatch;
69bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
70bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
71bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    /////////////////////////////////////
72bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    // Parcelable "contract" methods. //
73bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    /////////////////////////////////////
74bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
75bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    @Override
76bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public int describeContents() {
77bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        return 0;
78bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
79bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
80bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    @Override
81bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public void writeToParcel(Parcel parcel, int flags) {
82bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        parcel.writeParcelable(mMatch, flags);
83bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
84bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
85bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public static final Parcelable.Creator<FieldClassification> CREATOR =
86bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            new Parcelable.Creator<FieldClassification>() {
87bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
88bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @Override
89bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public FieldClassification createFromParcel(Parcel parcel) {
90bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return new FieldClassification(parcel.readParcelable(null));
91bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
92bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
93bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @Override
94bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public FieldClassification[] newArray(int size) {
95bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return new FieldClassification[size];
96bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
97bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    };
98bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
99bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    /**
100bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     * Gets the score of a {@link UserData} entry for the field.
101bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     *
102bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     * TODO(b/67867469):
103bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     * - improve javadoc
104bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     * - unhide / remove testApi
105bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     *
106bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     * @hide
107bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme     */
108bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    @TestApi
109bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    public static final class Match implements Parcelable {
110bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
111bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        private final String mRemoteId;
112329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme        private final float mScore;
113bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
114bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        /** @hide */
115329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme        public Match(String remoteId, float score) {
116bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            mRemoteId = Preconditions.checkNotNull(remoteId);
117bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            mScore = score;
118bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
119bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
120bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        /**
121bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * Gets the remote id of the {@link UserData} entry.
122bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         */
123bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @NonNull
124bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public String getRemoteId() {
125bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return mRemoteId;
126bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
127bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
128bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        /**
129bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * Gets a score between the value of this field and the value of the {@link UserData} entry.
130bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         *
131bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * <p>The score is based in a case-insensitive comparisson of all characters from both the
132bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * field value and the user data entry, and it ranges from {@code 0} to {@code 1000000}:
133bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * <ul>
134329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme         *   <li>{@code 1.0} represents a full match ({@code 100%}).
135329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme         *   <li>{@code 0.0} represents a full mismatch ({@code 0%}).
136bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         *   <li>Any other value is a partial match.
137bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * </ul>
138bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         *
139bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * <p>How the score is calculated depends on the algorithm used by the Android System.
140bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * For example, if the user  data is {@code "abc"} and the field value us {@code " abc"},
141bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * the result could be:
142bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * <ul>
143329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme         *   <li>{@code 1.0} if the algorithm trims the values.
144329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme         *   <li>{@code 0.0} if the algorithm compares the values sequentially.
145329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme         *   <li>{@code 0.75} if the algorithm consideres that 3/4 (75%) of the characters match.
146bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * </ul>
147bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         *
148bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         * <p>Currently, the autofill service cannot configure the algorithm.
149bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme         */
150329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme        public float getScore() {
151bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return mScore;
152bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
153bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
154bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @Override
155bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public String toString() {
156bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            if (!sDebug) return super.toString();
157bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
158bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            final StringBuilder string = new StringBuilder("Match: remoteId=");
159bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            Helper.appendRedacted(string, mRemoteId);
160bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return string.append(", score=").append(mScore).toString();
161bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
162bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
163bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        /////////////////////////////////////
164bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        // Parcelable "contract" methods. //
165bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        /////////////////////////////////////
166bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
167bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @Override
168bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public int describeContents() {
169bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            return 0;
170bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
171bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
172bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @Override
173bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public void writeToParcel(Parcel parcel, int flags) {
174bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            parcel.writeString(mRemoteId);
175329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme            parcel.writeFloat(mScore);
176bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        }
177bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
178bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        @SuppressWarnings("hiding")
179bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        public static final Parcelable.Creator<Match> CREATOR = new Parcelable.Creator<Match>() {
180bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
181bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            @Override
182bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            public Match createFromParcel(Parcel parcel) {
183329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme                return new Match(parcel.readString(), parcel.readFloat());
184bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            }
185bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme
186bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            @Override
187bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            public Match[] newArray(int size) {
188bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme                return new Match[size];
189bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme            }
190bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme        };
191bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme    }
192bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme}
193