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.autofillframework.app 17 18 import android.content.Context 19 import android.content.Intent 20 import android.os.Bundle 21 import android.support.v7.app.AppCompatActivity 22 import android.util.Log 23 import android.view.View 24 import android.view.autofill.AutofillManager 25 import android.widget.ArrayAdapter 26 import android.widget.AutoCompleteTextView 27 import android.widget.Toast 28 import com.example.android.autofillframework.CommonUtil.TAG 29 import com.example.android.autofillframework.R 30 import kotlinx.android.synthetic.main.login_with_autocomplete_activity.clear 31 import kotlinx.android.synthetic.main.login_with_autocomplete_activity.login 32 import kotlinx.android.synthetic.main.login_with_autocomplete_activity.passwordField 33 import kotlinx.android.synthetic.main.login_with_autocomplete_activity.usernameField 34 35 class StandardAutoCompleteSignInActivity : AppCompatActivity() { 36 private var autofillReceived = false 37 private lateinit var autofillCallback: AutofillManager.AutofillCallback 38 private lateinit var autofillManager: AutofillManager 39 40 override fun onCreate(savedInstanceState: Bundle?) { 41 super.onCreate(savedInstanceState) 42 43 setContentView(R.layout.login_with_autocomplete_activity) 44 45 login.setOnClickListener { submitLogin() } 46 clear.setOnClickListener { resetFields() } 47 autofillCallback = MyAutofillCallback() 48 autofillManager = getSystemService(AutofillManager::class.java) 49 val mockAutocompleteAdapter = ArrayAdapter.createFromResource(this, R.array.mock_autocomplete_sign_in_suggestions, 50 android.R.layout.simple_dropdown_item_1line) 51 usernameField.setAdapter(mockAutocompleteAdapter) 52 } 53 54 override fun onResume() { 55 super.onResume() 56 autofillManager.registerCallback(autofillCallback) 57 } 58 59 override fun onPause() { 60 super.onPause() 61 autofillManager.unregisterCallback(autofillCallback) 62 } 63 64 private fun resetFields() { 65 usernameField.setText("") 66 passwordField.setText("") 67 } 68 69 /** 70 * Emulates a login action. 71 */ 72 private fun submitLogin() { 73 val username = usernameField.text.toString() 74 val password = passwordField.text.toString() 75 val valid = isValidCredentials(username, password) 76 if (valid) { 77 val intent = WelcomeActivity.getStartActivityIntent(this@StandardAutoCompleteSignInActivity) 78 startActivity(intent) 79 finish() 80 } else { 81 Toast.makeText(this, "Authentication failed.", Toast.LENGTH_SHORT).show() 82 } 83 } 84 85 /** 86 * Dummy implementation for demo purposes. A real service should use secure mechanisms to 87 * authenticate users. 88 */ 89 fun isValidCredentials(username: String?, password: String?): Boolean { 90 return username != null && password != null && username == password 91 } 92 93 private inner class MyAutofillCallback : AutofillManager.AutofillCallback() { 94 override fun onAutofillEvent(view: View, event: Int) { 95 super.onAutofillEvent(view, event) 96 if (view is AutoCompleteTextView) { 97 when (event) { 98 AutofillManager.AutofillCallback.EVENT_INPUT_UNAVAILABLE, 99 AutofillManager.AutofillCallback.EVENT_INPUT_HIDDEN -> { 100 if (!autofillReceived) { 101 view.showDropDown() 102 } 103 } 104 AutofillManager.AutofillCallback.EVENT_INPUT_SHOWN -> { 105 autofillReceived = true 106 view.setAdapter(null) 107 } 108 else -> Log.d(TAG, "Unexpected callback: " + event) 109 } 110 } 111 } 112 } 113 114 companion object { 115 116 fun getStartActivityIntent(context: Context): Intent { 117 val intent = Intent(context, StandardAutoCompleteSignInActivity::class.java) 118 return intent 119 } 120 } 121 }