Home | History | Annotate | Download | only in service
      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.service;
     17 
     18 import android.app.PendingIntent;
     19 import android.app.assist.AssistStructure;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentSender;
     23 import android.os.Bundle;
     24 import android.service.autofill.Dataset;
     25 import android.service.autofill.FillResponse;
     26 import android.support.annotation.Nullable;
     27 import android.support.v7.app.AppCompatActivity;
     28 import android.text.Editable;
     29 import android.util.Log;
     30 import android.view.View;
     31 import android.view.View.OnClickListener;
     32 import android.widget.EditText;
     33 import android.widget.Toast;
     34 
     35 import com.example.android.autofill.service.datasource.SharedPrefsAutofillRepository;
     36 import com.example.android.autofill.service.model.FilledAutofillFieldCollection;
     37 import com.example.android.autofill.service.settings.MyPreferences;
     38 
     39 import java.util.HashMap;
     40 
     41 import static android.view.autofill.AutofillManager.EXTRA_ASSIST_STRUCTURE;
     42 import static android.view.autofill.AutofillManager.EXTRA_AUTHENTICATION_RESULT;
     43 import static com.example.android.autofill.service.CommonUtil.EXTRA_DATASET_NAME;
     44 import static com.example.android.autofill.service.CommonUtil.EXTRA_FOR_RESPONSE;
     45 import static com.example.android.autofill.service.CommonUtil.TAG;
     46 
     47 /**
     48  * This Activity controls the UI for logging in to the Autofill service.
     49  * It is launched when an Autofill Response or specific Dataset within the Response requires
     50  * authentication to access. It bundles the result in an Intent.
     51  */
     52 public class AuthActivity extends AppCompatActivity {
     53 
     54     // Unique id for dataset intents.
     55     private static int sDatasetPendingIntentId = 0;
     56 
     57     private EditText mMasterPassword;
     58     private Intent mReplyIntent;
     59 
     60     static IntentSender getAuthIntentSenderForResponse(Context context) {
     61         final Intent intent = new Intent(context, AuthActivity.class);
     62         return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)
     63                 .getIntentSender();
     64     }
     65 
     66     static IntentSender getAuthIntentSenderForDataset(Context context, String datasetName) {
     67         final Intent intent = new Intent(context, AuthActivity.class);
     68         intent.putExtra(EXTRA_DATASET_NAME, datasetName);
     69         intent.putExtra(EXTRA_FOR_RESPONSE, false);
     70         return PendingIntent.getActivity(context, ++sDatasetPendingIntentId, intent,
     71                 PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
     72     }
     73 
     74     @Override
     75     protected void onCreate(@Nullable Bundle savedInstanceState) {
     76         super.onCreate(savedInstanceState);
     77         setContentView(R.layout.multidataset_service_auth_activity);
     78         mMasterPassword = findViewById(R.id.master_password);
     79         findViewById(R.id.login).setOnClickListener(new OnClickListener() {
     80             @Override
     81             public void onClick(View v) {
     82                 login();
     83             }
     84 
     85         });
     86         findViewById(R.id.cancel).setOnClickListener(new OnClickListener() {
     87             @Override
     88             public void onClick(View v) {
     89                 onFailure();
     90                 AuthActivity.this.finish();
     91             }
     92         });
     93     }
     94 
     95     private void login() {
     96         Editable password = mMasterPassword.getText();
     97         if (password.toString()
     98                 .equals(MyPreferences.getInstance(AuthActivity.this).getMasterPassword())) {
     99             onSuccess();
    100         } else {
    101             Toast.makeText(this, "Password incorrect", Toast.LENGTH_SHORT).show();
    102             onFailure();
    103         }
    104         finish();
    105     }
    106 
    107     @Override
    108     public void finish() {
    109         if (mReplyIntent != null) {
    110             setResult(RESULT_OK, mReplyIntent);
    111         } else {
    112             setResult(RESULT_CANCELED);
    113         }
    114         super.finish();
    115     }
    116 
    117     private void onFailure() {
    118         Log.w(TAG, "Failed auth.");
    119         mReplyIntent = null;
    120     }
    121 
    122     private void onSuccess() {
    123         Intent intent = getIntent();
    124         boolean forResponse = intent.getBooleanExtra(EXTRA_FOR_RESPONSE, true);
    125         AssistStructure structure = intent.getParcelableExtra(EXTRA_ASSIST_STRUCTURE);
    126         StructureParser parser = new StructureParser(getApplicationContext(), structure);
    127         parser.parseForFill();
    128         AutofillFieldMetadataCollection autofillFields = parser.getAutofillFields();
    129         int saveTypes = autofillFields.getSaveType();
    130         mReplyIntent = new Intent();
    131         HashMap<String, FilledAutofillFieldCollection> clientFormDataMap =
    132                 SharedPrefsAutofillRepository.getInstance().getFilledAutofillFieldCollection
    133                         (this, autofillFields.getFocusedHints(), autofillFields.getAllHints());
    134         if (forResponse) {
    135             setResponseIntent(AutofillHelper.newResponse
    136                     (this, false, autofillFields, clientFormDataMap));
    137         } else {
    138             String datasetName = intent.getStringExtra(EXTRA_DATASET_NAME);
    139             setDatasetIntent(AutofillHelper.newDataset
    140                     (this, autofillFields, clientFormDataMap.get(datasetName), false));
    141         }
    142     }
    143 
    144     private void setResponseIntent(FillResponse fillResponse) {
    145         mReplyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, fillResponse);
    146     }
    147 
    148     private void setDatasetIntent(Dataset dataset) {
    149         mReplyIntent.putExtra(EXTRA_AUTHENTICATION_RESULT, dataset);
    150     }
    151 }
    152