FieldClassification.java revision bb6bfea6801cff5b50c990bdcfbd2df93ddf9023
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.service.autofill;
18
19import static android.view.autofill.Helper.sDebug;
20
21import android.annotation.NonNull;
22import android.annotation.TestApi;
23import android.os.Parcel;
24import android.os.Parcelable;
25import android.view.autofill.Helper;
26
27import com.android.internal.util.Preconditions;
28
29/**
30 * Gets the <a href="#FieldsClassification">fields classification</a> results for a given field.
31 *
32 * TODO(b/67867469):
33 * - improve javadoc
34 * - unhide / remove testApi
35 *
36 * @hide
37 */
38@TestApi
39public final class FieldClassification implements Parcelable {
40
41    private final Match mMatch;
42
43    /** @hide */
44    public FieldClassification(@NonNull Match match) {
45        mMatch = Preconditions.checkNotNull(match);
46    }
47
48    /**
49     * Gets the {@link Match} with the highest {@link Match#getScore() score} for the field.
50     */
51    @NonNull
52    public Match getTopMatch() {
53        return mMatch;
54    }
55
56    @Override
57    public String toString() {
58        if (!sDebug) return super.toString();
59
60        return "FieldClassification: " + mMatch;
61    }
62
63    /////////////////////////////////////
64    // Parcelable "contract" methods. //
65    /////////////////////////////////////
66
67    @Override
68    public int describeContents() {
69        return 0;
70    }
71
72    @Override
73    public void writeToParcel(Parcel parcel, int flags) {
74        parcel.writeParcelable(mMatch, flags);
75    }
76
77    public static final Parcelable.Creator<FieldClassification> CREATOR =
78            new Parcelable.Creator<FieldClassification>() {
79
80        @Override
81        public FieldClassification createFromParcel(Parcel parcel) {
82            return new FieldClassification(parcel.readParcelable(null));
83        }
84
85        @Override
86        public FieldClassification[] newArray(int size) {
87            return new FieldClassification[size];
88        }
89    };
90
91    /**
92     * Gets the score of a {@link UserData} entry for the field.
93     *
94     * TODO(b/67867469):
95     * - improve javadoc
96     * - unhide / remove testApi
97     *
98     * @hide
99     */
100    @TestApi
101    public static final class Match implements Parcelable {
102
103        private final String mRemoteId;
104        private final int mScore;
105
106        /** @hide */
107        public Match(String remoteId, int score) {
108            mRemoteId = Preconditions.checkNotNull(remoteId);
109            mScore = score;
110        }
111
112        /**
113         * Gets the remote id of the {@link UserData} entry.
114         */
115        @NonNull
116        public String getRemoteId() {
117            return mRemoteId;
118        }
119
120        /**
121         * Gets a score between the value of this field and the value of the {@link UserData} entry.
122         *
123         * <p>The score is based in a case-insensitive comparisson of all characters from both the
124         * field value and the user data entry, and it ranges from {@code 0} to {@code 1000000}:
125         * <ul>
126         *   <li>{@code 1000000} represents a full match ({@code 100.0000%}).
127         *   <li>{@code 0} represents a full mismatch ({@code 0.0000%}).
128         *   <li>Any other value is a partial match.
129         * </ul>
130         *
131         * <p>How the score is calculated depends on the algorithm used by the Android System.
132         * For example, if the user  data is {@code "abc"} and the field value us {@code " abc"},
133         * the result could be:
134         * <ul>
135         *   <li>{@code 1000000} if the algorithm trims the values.
136         *   <li>{@code 0} if the algorithm compares the values sequentially.
137         *   <li>{@code 750000} if the algorithm consideres that 3/4 (75%) of the characters match.
138         * </ul>
139         *
140         * <p>Currently, the autofill service cannot configure the algorithm.
141         */
142        public int getScore() {
143            return mScore;
144        }
145
146        @Override
147        public String toString() {
148            if (!sDebug) return super.toString();
149
150            final StringBuilder string = new StringBuilder("Match: remoteId=");
151            Helper.appendRedacted(string, mRemoteId);
152            return string.append(", score=").append(mScore).toString();
153        }
154
155        /////////////////////////////////////
156        // Parcelable "contract" methods. //
157        /////////////////////////////////////
158
159        @Override
160        public int describeContents() {
161            return 0;
162        }
163
164        @Override
165        public void writeToParcel(Parcel parcel, int flags) {
166            parcel.writeString(mRemoteId);
167            parcel.writeInt(mScore);
168        }
169
170        @SuppressWarnings("hiding")
171        public static final Parcelable.Creator<Match> CREATOR = new Parcelable.Creator<Match>() {
172
173            @Override
174            public Match createFromParcel(Parcel parcel) {
175                return new Match(parcel.readString(), parcel.readInt());
176            }
177
178            @Override
179            public Match[] newArray(int size) {
180                return new Match[size];
181            }
182        };
183    }
184}
185