FieldClassification.java revision 27f4573d136949abeacb00f7246ff9911e9cb105
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.os.Parcel; 23bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport android.view.autofill.Helper; 24bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 25bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Lemeimport com.android.internal.util.Preconditions; 26bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 2751f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Lemeimport java.util.ArrayList; 2851f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Lemeimport java.util.Collections; 2951f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Lemeimport java.util.Comparator; 30329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Lemeimport java.util.List; 31329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme 32bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme/** 3378172e70f4c5d776678551965db7c167ee11703eFelipe Leme * Represents the <a href="AutofillService.html#FieldClassification">field classification</a> 3478172e70f4c5d776678551965db7c167ee11703eFelipe Leme * results for a given field. 35bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */ 36f1141c00411296b59b59376182083685248f69c8Felipe Lemepublic final class FieldClassification { 37bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 3851f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme private final ArrayList<Match> mMatches; 39bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 40bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** @hide */ 4151f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme public FieldClassification(@NonNull ArrayList<Match> matches) { 4251f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme mMatches = Preconditions.checkNotNull(matches); 4351f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme Collections.sort(mMatches, new Comparator<Match>() { 4451f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme @Override 4551f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme public int compare(Match o1, Match o2) { 4651f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme if (o1.mScore > o2.mScore) return -1; 4751f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme if (o1.mScore < o2.mScore) return 1; 4851f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme return 0; 4951f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme }} 5051f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme ); 51bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 52bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 53bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** 5451f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme * Gets the {@link Match matches} with the highest {@link Match#getScore() scores} (sorted in 5551f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme * descending order). 56329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme * 57329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme * <p><b>Note:</b> There's no guarantee of how many matches will be returned. In fact, 58329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme * the Android System might return just the top match to minimize the impact of field 59329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme * classification in the device's health. 60bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */ 61bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme @NonNull 62329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme public List<Match> getMatches() { 6351f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme return mMatches; 64bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 65bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 66bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme @Override 67bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme public String toString() { 68bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme if (!sDebug) return super.toString(); 69bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 7051f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme return "FieldClassification: " + mMatches; 71bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 72bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 73f1141c00411296b59b59376182083685248f69c8Felipe Leme private void writeToParcel(Parcel parcel) { 7451f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme parcel.writeInt(mMatches.size()); 7551f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme for (int i = 0; i < mMatches.size(); i++) { 7651f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme mMatches.get(i).writeToParcel(parcel); 7751f6cd70316cdd0662e40ad7b0109effab9cd9adFelipe Leme } 78bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 79bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 80f1141c00411296b59b59376182083685248f69c8Felipe Leme private static FieldClassification readFromParcel(Parcel parcel) { 81f1141c00411296b59b59376182083685248f69c8Felipe Leme final int size = parcel.readInt(); 82f1141c00411296b59b59376182083685248f69c8Felipe Leme final ArrayList<Match> matches = new ArrayList<>(); 83f1141c00411296b59b59376182083685248f69c8Felipe Leme for (int i = 0; i < size; i++) { 84f1141c00411296b59b59376182083685248f69c8Felipe Leme matches.add(i, Match.readFromParcel(parcel)); 85f1141c00411296b59b59376182083685248f69c8Felipe Leme } 86bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 87f1141c00411296b59b59376182083685248f69c8Felipe Leme return new FieldClassification(matches); 88f1141c00411296b59b59376182083685248f69c8Felipe Leme } 89f1141c00411296b59b59376182083685248f69c8Felipe Leme 90f1141c00411296b59b59376182083685248f69c8Felipe Leme static FieldClassification[] readArrayFromParcel(Parcel parcel) { 91f1141c00411296b59b59376182083685248f69c8Felipe Leme final int length = parcel.readInt(); 92f1141c00411296b59b59376182083685248f69c8Felipe Leme final FieldClassification[] fcs = new FieldClassification[length]; 93f1141c00411296b59b59376182083685248f69c8Felipe Leme for (int i = 0; i < length; i++) { 94f1141c00411296b59b59376182083685248f69c8Felipe Leme fcs[i] = readFromParcel(parcel); 95bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 96f1141c00411296b59b59376182083685248f69c8Felipe Leme return fcs; 97f1141c00411296b59b59376182083685248f69c8Felipe Leme } 98bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 99f1141c00411296b59b59376182083685248f69c8Felipe Leme static void writeArrayToParcel(@NonNull Parcel parcel, @NonNull FieldClassification[] fcs) { 100f1141c00411296b59b59376182083685248f69c8Felipe Leme parcel.writeInt(fcs.length); 101f1141c00411296b59b59376182083685248f69c8Felipe Leme for (int i = 0; i < fcs.length; i++) { 102f1141c00411296b59b59376182083685248f69c8Felipe Leme fcs[i].writeToParcel(parcel); 103bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 104f1141c00411296b59b59376182083685248f69c8Felipe Leme } 105bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 106bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** 10778172e70f4c5d776678551965db7c167ee11703eFelipe Leme * Represents the score of a {@link UserData} entry for the field. 108bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * 10927f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * <p>The score is calculated by the given {@link #getAlgorithm() algorithm} and 11027f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * the entry is identified by {@link #getRemoteId()}. 111bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */ 11278172e70f4c5d776678551965db7c167ee11703eFelipe Leme public static final class Match { 113bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 114bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme private final String mRemoteId; 115329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme private final float mScore; 11627f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme private final String mAlgorithm; 117bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 118bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** @hide */ 11927f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme public Match(String remoteId, float score, String algorithm) { 120bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme mRemoteId = Preconditions.checkNotNull(remoteId); 121bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme mScore = score; 12227f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme mAlgorithm = algorithm; 123bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 124bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 125bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** 126bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * Gets the remote id of the {@link UserData} entry. 127bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */ 128bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme @NonNull 129bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme public String getRemoteId() { 130bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme return mRemoteId; 131bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 132bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 133bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme /** 13478172e70f4c5d776678551965db7c167ee11703eFelipe Leme * Gets a classification score for the value of this field compared to the value of the 13578172e70f4c5d776678551965db7c167ee11703eFelipe Leme * {@link UserData} entry. 136bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * 13778172e70f4c5d776678551965db7c167ee11703eFelipe Leme * <p>The score is based in a comparison of the field value and the user data entry, and it 13878172e70f4c5d776678551965db7c167ee11703eFelipe Leme * ranges from {@code 0.0F} to {@code 1.0F}: 139bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * <ul> 14078172e70f4c5d776678551965db7c167ee11703eFelipe Leme * <li>{@code 1.0F} represents a full match ({@code 100%}). 14178172e70f4c5d776678551965db7c167ee11703eFelipe Leme * <li>{@code 0.0F} represents a full mismatch ({@code 0%}). 142bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * <li>Any other value is a partial match. 143bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * </ul> 144bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme * 14527f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * <p>How the score is calculated depends on the 14627f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * {@link UserData.Builder#setFieldClassificationAlgorithm(String, android.os.Bundle) 14727f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * algorithm} used. 148bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme */ 149329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme public float getScore() { 150bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme return mScore; 151bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 152bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 15327f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme /** 15427f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * Gets the algorithm used to calculate this score. 15527f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * 15627f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * <p>Typically, this is either the algorithm set by 15727f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * {@link UserData.Builder#setFieldClassificationAlgorithm(String, android.os.Bundle)}, 15827f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * or the 15927f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme * {@link android.view.autofill.AutofillManager#getDefaultFieldClassificationAlgorithm()}. 16027f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme */ 16127f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme @NonNull 16227f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme public String getAlgorithm() { 16327f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme return mAlgorithm; 16427f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme } 16527f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme 166bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme @Override 167bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme public String toString() { 168bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme if (!sDebug) return super.toString(); 169bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 170bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme final StringBuilder string = new StringBuilder("Match: remoteId="); 171bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme Helper.appendRedacted(string, mRemoteId); 17227f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme return string.append(", score=").append(mScore) 17327f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme .append(", algorithm=").append(mAlgorithm) 17427f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme .toString(); 175bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 176bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 17778172e70f4c5d776678551965db7c167ee11703eFelipe Leme private void writeToParcel(@NonNull Parcel parcel) { 178bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme parcel.writeString(mRemoteId); 179329d04097e1db9b6f801972d94f56c5b56c09e8aFelipe Leme parcel.writeFloat(mScore); 18027f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme parcel.writeString(mAlgorithm); 181bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 182bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme 18378172e70f4c5d776678551965db7c167ee11703eFelipe Leme private static Match readFromParcel(@NonNull Parcel parcel) { 18427f4573d136949abeacb00f7246ff9911e9cb105Felipe Leme return new Match(parcel.readString(), parcel.readFloat(), parcel.readString()); 18578172e70f4c5d776678551965db7c167ee11703eFelipe Leme } 186bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme } 187bb6bfea6801cff5b50c990bdcfbd2df93ddf9023Felipe Leme} 188