LuhnChecksumValidator.java revision 979013d027d828f404e71f48b88403e562ccbc7b
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.os.Parcel;
23import android.os.Parcelable;
24import android.text.TextUtils;
25import android.util.Log;
26import android.view.autofill.AutofillId;
27
28import com.android.internal.util.Preconditions;
29
30/**
31 * Validator that returns {@code true} if the number created by concatenating all given fields
32 * pass a Luhn algorithm checksum.
33 *
34 * <p>See {@link SaveInfo.Builder#setValidator(Validator)} for examples.
35 */
36public final class LuhnChecksumValidator extends InternalValidator implements Parcelable {
37    private static final String TAG = "LuhnChecksumValidator";
38
39    private final AutofillId[] mIds;
40
41    /**
42      * Default constructor.
43      *
44      * @param ids id of fields that comprises the number to be checked.
45      */
46    public LuhnChecksumValidator(@NonNull AutofillId... ids) {
47        mIds = Preconditions.checkArrayElementsNotNull(ids, "ids");
48    }
49
50    /** @hide */
51    @Override
52    public boolean isValid(@NonNull ValueFinder finder) {
53        if (mIds == null || mIds.length == 0) return false;
54
55        final StringBuilder number = new StringBuilder();
56        for (AutofillId id : mIds) {
57            final String partialNumber = finder.findByAutofillId(id);
58            if (partialNumber == null) {
59                if (sDebug) Log.d(TAG, "No partial number for id " + id);
60                return false;
61            }
62            number.append(partialNumber);
63        }
64        final boolean isValid = TextUtils.isDigitsOnly(number.toString());
65        if (sDebug) Log.d(TAG, "Is valid: " + isValid);
66        // TODO(b/62534917): proper implementation - copy & paste code from:
67        // PaymentUtils.java
68        // PaymentUtilsTest.java
69        return isValid;
70    }
71
72    /////////////////////////////////////
73    // Parcelable "contract" methods. //
74    /////////////////////////////////////
75    @Override
76    public int describeContents() {
77        return 0;
78    }
79
80    @Override
81    public void writeToParcel(Parcel parcel, int flags) {
82        parcel.writeParcelableArray(mIds, flags);
83    }
84
85    public static final Parcelable.Creator<LuhnChecksumValidator> CREATOR =
86            new Parcelable.Creator<LuhnChecksumValidator>() {
87        @Override
88        public LuhnChecksumValidator createFromParcel(Parcel parcel) {
89            return new LuhnChecksumValidator(parcel.readParcelableArray(null, AutofillId.class));
90        }
91
92        @Override
93        public LuhnChecksumValidator[] newArray(int size) {
94            return new LuhnChecksumValidator[size];
95        }
96    };
97}
98