Home | History | Annotate | Download | only in autofillable
      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 package com.example.android.autofill.app.view.autofillable;
     17 
     18 import android.content.Context;
     19 import android.support.annotation.NonNull;
     20 import android.support.annotation.Nullable;
     21 import android.util.AttributeSet;
     22 import android.util.Log;
     23 import android.view.LayoutInflater;
     24 import android.view.View;
     25 import android.view.autofill.AutofillManager;
     26 import android.view.autofill.AutofillValue;
     27 import android.widget.AdapterView;
     28 import android.widget.ArrayAdapter;
     29 import android.widget.FrameLayout;
     30 import android.widget.Spinner;
     31 
     32 import com.example.android.autofill.app.R;
     33 
     34 import java.util.Calendar;
     35 
     36 import static com.example.android.autofill.app.Util.TAG;
     37 
     38 /**
     39  * A custom view that represents a {@link View#AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DATE} using
     40  * 2 {@link Spinner spinners} to represent the credit card expiration month and year.
     41  */
     42 public class CreditCardExpirationDateCompoundView extends FrameLayout {
     43 
     44     private static final int CC_EXP_YEARS_COUNT = 5;
     45 
     46     private final String[] mYears = new String[CC_EXP_YEARS_COUNT];
     47 
     48     private Spinner mCcExpMonthSpinner;
     49     private Spinner mCcExpYearSpinner;
     50 
     51     public CreditCardExpirationDateCompoundView(@NonNull Context context) {
     52         this(context, null);
     53     }
     54 
     55     public CreditCardExpirationDateCompoundView(@NonNull Context context,
     56             @Nullable AttributeSet attrs) {
     57         this(context, attrs, 0);
     58     }
     59 
     60     public CreditCardExpirationDateCompoundView(@NonNull Context context,
     61             @Nullable AttributeSet attrs, int defStyleAttr) {
     62         this(context, attrs, defStyleAttr, 0);
     63     }
     64 
     65     public CreditCardExpirationDateCompoundView(@NonNull final Context context,
     66             @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
     67         super(context, attrs, defStyleAttr, defStyleRes);
     68         View rootView = LayoutInflater.from(context).inflate(R.layout.cc_exp_date, this);
     69         mCcExpMonthSpinner = rootView.findViewById(R.id.ccExpMonth);
     70         mCcExpYearSpinner = rootView.findViewById(R.id.ccExpYear);
     71         setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES_EXCLUDE_DESCENDANTS);
     72         ArrayAdapter<CharSequence> monthAdapter = ArrayAdapter.createFromResource
     73                 (context, R.array.month_array, android.R.layout.simple_spinner_item);
     74         monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     75         mCcExpMonthSpinner.setAdapter(monthAdapter);
     76         int year = Calendar.getInstance().get(Calendar.YEAR);
     77         for (int i = 0; i < mYears.length; i++) {
     78             mYears[i] = Integer.toString(year + i);
     79         }
     80         mCcExpYearSpinner.setAdapter(new ArrayAdapter<>(context,
     81                 android.R.layout.simple_spinner_item, mYears));
     82         AdapterView.OnItemSelectedListener onItemSelectedListener =
     83                 new AdapterView.OnItemSelectedListener() {
     84                     @Override
     85                     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
     86                         context.getSystemService(AutofillManager.class)
     87                                 .notifyValueChanged(CreditCardExpirationDateCompoundView.this);
     88                     }
     89 
     90                     @Override
     91                     public void onNothingSelected(AdapterView<?> parent) {
     92                     }
     93                 };
     94         mCcExpMonthSpinner.setOnItemSelectedListener(onItemSelectedListener);
     95         mCcExpYearSpinner.setOnItemSelectedListener(onItemSelectedListener);
     96     }
     97 
     98     @Override
     99     public AutofillValue getAutofillValue() {
    100         Calendar calendar = Calendar.getInstance();
    101         // Set hours, minutes, seconds, and millis to 0 to ensure getAutofillValue() == the value
    102         // set by autofill(). Without this line, the view will not turn yellow when updated.
    103         calendar.clear();
    104         int year = Integer.parseInt(mCcExpYearSpinner.getSelectedItem().toString());
    105         int month = mCcExpMonthSpinner.getSelectedItemPosition();
    106         calendar.set(Calendar.YEAR, year);
    107         calendar.set(Calendar.MONTH, month);
    108         long unixTime = calendar.getTimeInMillis();
    109         return AutofillValue.forDate(unixTime);
    110     }
    111 
    112     @Override
    113     public void autofill(AutofillValue value) {
    114         if (!value.isDate()) {
    115             Log.w(TAG, "Ignoring autofill() because service sent a non-date value:" + value);
    116             return;
    117         }
    118         Calendar calendar = Calendar.getInstance();
    119         calendar.setTimeInMillis(value.getDateValue());
    120         int month = calendar.get(Calendar.MONTH);
    121         int year = calendar.get(Calendar.YEAR);
    122         mCcExpMonthSpinner.setSelection(month);
    123         mCcExpYearSpinner.setSelection(year - Integer.parseInt(mYears[0]));
    124     }
    125 
    126     @Override
    127     public int getAutofillType() {
    128         return AUTOFILL_TYPE_DATE;
    129     }
    130 
    131     public void reset() {
    132         mCcExpMonthSpinner.setSelection(0);
    133         mCcExpYearSpinner.setSelection(0);
    134     }
    135 }