diff options
author | Douglas Sigelbaum <sigelbaum@google.com> | 2017-08-03 15:23:36 -0700 |
---|---|---|
committer | Douglas Sigelbaum <sigelbaum@google.com> | 2017-08-31 21:05:28 +0000 |
commit | 71556a6f6969b258fbcfd5bbc01ac32bb03d9674 (patch) | |
tree | adae9b1a8e82eb20dc874d6539c4bb680d0443b9 /input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example | |
parent | 741ba0876afd00188e2108d88e9cf694d680c4bb (diff) | |
download | android-71556a6f6969b258fbcfd5bbc01ac32bb03d9674.tar.gz |
Autofill kotlin sample: Improve kotlin style.
Bug: 38182790
Test: manual
Change-Id: I8250c1de268f2dcff7f3aca459a1a6c0a484a844
Diffstat (limited to 'input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example')
15 files changed, 218 insertions, 202 deletions
diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/CommonUtil.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/CommonUtil.kt index e2839e92..c64a6707 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/CommonUtil.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/CommonUtil.kt @@ -16,6 +16,8 @@ package com.example.android.autofillframework import android.os.Bundle +import com.google.gson.Gson +import com.google.gson.GsonBuilder import java.util.Arrays object CommonUtil { @@ -49,4 +51,8 @@ object CommonUtil { bundleToString(builder, data) return builder.toString() } + + fun createGson(): Gson { + return GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create() + } }
\ No newline at end of file diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.kt index c8136ed3..88e28b44 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CreditCardActivity.kt @@ -34,30 +34,31 @@ class CreditCardActivity : AppCompatActivity() { private val CC_EXP_YEARS_COUNT = 5 - private val years: Array<CharSequence?> = arrayOfNulls<CharSequence>(CC_EXP_YEARS_COUNT) - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.credit_card_activity) // Create an ArrayAdapter using the string array and a default spinner layout - val dayAdapter = ArrayAdapter.createFromResource(this, R.array.day_array, android.R.layout.simple_spinner_item) - // Specify the layout to use when the list of choices appears - dayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - // Apply the adapter to the spinner - expirationDay.adapter = dayAdapter + expirationDay.adapter = ArrayAdapter.createFromResource(this, R.array.day_array, + android.R.layout.simple_spinner_item).apply { + // Specify the layout to use when the list of choices appears + setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + } - val monthAdapter = ArrayAdapter.createFromResource(this, R.array.month_array, android.R.layout.simple_spinner_item) - monthAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - expirationMonth.adapter = monthAdapter + expirationMonth.adapter = ArrayAdapter.createFromResource(this, R.array.month_array, + android.R.layout.simple_spinner_item).apply { + setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + } val year = Calendar.getInstance().get(Calendar.YEAR) - for (i in years.indices) { - years[i] = Integer.toString(year + i) - } - expirationYear.adapter = - object : ArrayAdapter<CharSequence?>(this, android.R.layout.simple_spinner_item, years) { - override fun getAutofillOptions(): Array<CharSequence?> { + + val years = (0 until CC_EXP_YEARS_COUNT) + .map {Integer.toString(year + it)} + .toTypedArray<CharSequence>() + + expirationYear.adapter = object : ArrayAdapter<CharSequence?>(this, + android.R.layout.simple_spinner_item, years) { + override fun getAutofillOptions(): Array<CharSequence> { return years } } @@ -77,15 +78,12 @@ class CreditCardActivity : AppCompatActivity() { * any new data. */ private fun submitCcInfo() { - val intent = WelcomeActivity.getStartActivityIntent(this) - startActivity(intent) + startActivity(WelcomeActivity.getStartActivityIntent(this)) finish() } companion object { - fun getStartActivityIntent(context: Context): Intent { - val intent = Intent(context, CreditCardActivity::class.java) - return intent - } + fun getStartActivityIntent(context: Context) = + Intent(context, CreditCardActivity::class.java) } } diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt index c737fe4c..36c43439 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/CustomVirtualView.kt @@ -21,7 +21,6 @@ import android.graphics.Color import android.graphics.Paint import android.graphics.Paint.Style import android.graphics.Rect -import android.text.TextUtils import android.util.AttributeSet import android.util.Log import android.util.SparseArray @@ -32,6 +31,7 @@ import android.view.autofill.AutofillManager import android.view.autofill.AutofillValue import android.widget.EditText import android.widget.TextView +import com.example.android.autofillframework.CommonUtil.TAG import com.example.android.autofillframework.CommonUtil.bundleToString import com.example.android.autofillframework.R import java.util.Arrays @@ -42,33 +42,30 @@ import java.util.Arrays */ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, attrs) { - private val mLines = ArrayList<Line>() - private val mItems = SparseArray<Item>() - private val mAfm: AutofillManager = context.getSystemService(AutofillManager::class.java) - - private var mFocusedLine: Line? = null - private val mTextPaint: Paint = Paint() - private val mTextHeight: Int = 90 - private val mTopMargin: Int = 100 - private val mLeftMargin: Int = 100 - private val mVerticalGap: Int = 10 - private val mLineLength: Int = mTextHeight + mVerticalGap - private val mFocusedColor: Int = Color.RED - private val mUnfocusedColor: Int = Color.BLACK - - private val mUsernameLine: Line - private val mPasswordLine: Line - - init { - mTextPaint.style = Style.FILL - mTextPaint.textSize = mTextHeight.toFloat() - mUsernameLine = addLine("usernameField", context.getString(R.string.username_label), - arrayOf(View.AUTOFILL_HINT_USERNAME), " ", true) - mPasswordLine = addLine("passwordField", context.getString(R.string.password_label), - arrayOf(View.AUTOFILL_HINT_PASSWORD), " ", false) - - Log.d(TAG, "Text height: " + mTextHeight) + val usernameText: CharSequence + get() = usernameLine.fieldTextItem.text + val passwordText: CharSequence + get() = passwordLine.fieldTextItem.text + private var nextId: Int = 0 + private val lines = ArrayList<Line>() + private val items = SparseArray<Item>() + private val autofillManager = context.getSystemService(AutofillManager::class.java) + private var focusedLine: Line? = null + private val textHeight = 90 + private val textPaint = Paint().apply { + style = Style.FILL + textSize = textHeight.toFloat() } + private val topMargin = 100 + private val leftMargin = 100 + private val verticalGap = 10 + private val lineLength = textHeight + verticalGap + private val focusedColor = Color.RED + private val unfocusedColor = Color.BLACK + private val usernameLine = addLine("usernameField", context.getString(R.string.username_label), + arrayOf(View.AUTOFILL_HINT_USERNAME), " ", true) + private val passwordLine = addLine("passwordField", context.getString(R.string.password_label), + arrayOf(View.AUTOFILL_HINT_PASSWORD), " ", false) override fun autofill(values: SparseArray<AutofillValue>) { // User has just selected a Dataset from the list of autofill suggestions. @@ -76,15 +73,15 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a // to fill a specific autofillable view. Now we have to update the UI based on the // AutofillValues in the list. Log.d(TAG, "autofill(): " + values) - for (i in 0..values.size() - 1) { + for (i in 0 until values.size()) { val id = values.keyAt(i) val value = values.valueAt(i) - mItems[id]?.let { item -> - if (item.editable) { + items[id]?.apply { + if (editable) { // Set the item's text to the text wrapped in the AutofillValue. - item.text = value.textValue + text = value.textValue } else { - Log.w(TAG, "Item for autofillId $id is not editable: $item") + Log.w(TAG, "Item for autofillId $id is not editable: $this") } } } @@ -94,24 +91,23 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a override fun onProvideAutofillVirtualStructure(structure: ViewStructure, flags: Int) { // Build a ViewStructure to pack in AutoFillService requests. structure.setClassName(javaClass.name) - val childrenSize = mItems.size() + val childrenSize = items.size() Log.d(TAG, "onProvideAutofillVirtualStructure(): flags = " + flags + ", items = " + childrenSize + ", extras: " + bundleToString(structure.extras)) var index = structure.addChildCount(childrenSize) - for (i in 0..childrenSize - 1) { - val item = mItems.valueAt(i) + for (i in 0 until childrenSize) { + val item = items.valueAt(i) Log.d(TAG, "Adding new child at index $index: $item") - val child = structure.newChild(index) - child.setAutofillId(structure.getAutofillId(), item.id) - child.setAutofillHints(item.hints) - child.setAutofillType(item.type) - child.setDataIsSensitive(!item.sanitized) - if (TextUtils.getTrimmedLength(item.text) > 0) { - child.setAutofillValue(AutofillValue.forText(item.text)) + structure.newChild(index).apply { + setAutofillId(structure.autofillId, item.id) + setAutofillHints(item.hints) + setAutofillType(item.type) + setDataIsSensitive(!item.sanitized) + setAutofillValue(AutofillValue.forText(item.text)) + setFocused(item.focused) + setId(item.id, context.packageName, null, item.line.idEntry) + setClassName(item.className) } - child.setFocused(item.focused) - child.setId(item.id, context.packageName, null, item.line.idEntry) - child.setClassName(item.className) index++ } } @@ -119,74 +115,71 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a override fun onDraw(canvas: Canvas) { super.onDraw(canvas) - Log.d(TAG, "onDraw: " + mLines.size + " lines; canvas:" + canvas) + Log.d(TAG, "onDraw: " + lines.size + " lines; canvas:" + canvas) var x: Float - var y = (mTopMargin + mLineLength).toFloat() - for (line in mLines) { - x = mLeftMargin.toFloat() - Log.v(TAG, "Drawing '" + line + "' at " + x + "x" + y) - mTextPaint.color = if (line.fieldTextItem.focused) mFocusedColor else mUnfocusedColor - val readOnlyText = line.labelItem.text.toString() + ": [" - val writeText = line.fieldTextItem.text.toString() + "]" + var y = (topMargin + lineLength).toFloat() + + lines.forEach { + x = leftMargin.toFloat() + Log.v(TAG, "Drawing $it at x=$x, y=$y") + textPaint.color = if (it.fieldTextItem.focused) focusedColor else unfocusedColor + val readOnlyText = it.labelItem.text.toString() + ": [" + val writeText = it.fieldTextItem.text.toString() + "]" // Paints the label first... - canvas.drawText(readOnlyText, x, y, mTextPaint) + canvas.drawText(readOnlyText, x, y, textPaint) // ...then paints the edit text and sets the proper boundary - val deltaX = mTextPaint.measureText(readOnlyText) + val deltaX = textPaint.measureText(readOnlyText) x += deltaX - line.bounds.set(x.toInt(), (y - mLineLength).toInt(), - (x + mTextPaint.measureText(writeText)).toInt(), y.toInt()) - Log.d(TAG, "setBounds(" + x + ", " + y + "): " + line.bounds) - canvas.drawText(writeText, x, y, mTextPaint) - y += mLineLength.toFloat() + it.bounds.set(x.toInt(), (y - lineLength).toInt(), + (x + textPaint.measureText(writeText)).toInt(), y.toInt()) + Log.d(TAG, "setBounds(" + x + ", " + y + "): " + it.bounds) + canvas.drawText(writeText, x, y, textPaint) + y += lineLength.toFloat() } } override fun onTouchEvent(event: MotionEvent): Boolean { val y = event.y.toInt() - Log.d(TAG, "Touched: y=$y, range=$mLineLength, top=$mTopMargin") - var lowerY = mTopMargin + Log.d(TAG, "Touched: y=$y, range=$lineLength, top=$topMargin") + var lowerY = topMargin var upperY = -1 - for (i in mLines.indices) { - upperY = lowerY + mLineLength - val line = mLines[i] - Log.d(TAG, "Line $i ranges from $lowerY to $upperY") - if (lowerY <= y && y <= upperY) { - Log.d(TAG, "Removing focus from " + mFocusedLine) - mFocusedLine?.changeFocus(false) + for (line in lines) { + upperY = lowerY + lineLength + Log.d(TAG, "Line $line ranges from $lowerY to $upperY") + if (y in lowerY..upperY) { + Log.d(TAG, "Removing focus from " + focusedLine) + focusedLine?.changeFocus(false) Log.d(TAG, "Changing focus to " + line) - mFocusedLine = line - mFocusedLine?.changeFocus(true) + focusedLine = line.apply { changeFocus(true) } invalidate() break } - lowerY += mLineLength + lowerY += lineLength } return super.onTouchEvent(event) } - val usernameText: CharSequence - get() = mUsernameLine.fieldTextItem.text - - val passwordText: CharSequence - get() = mPasswordLine.fieldTextItem.text - fun resetFields() { - mUsernameLine.reset() - mPasswordLine.reset() + usernameLine.reset() + passwordLine.reset() postInvalidate() } - private fun addLine(idEntry: String, label: String, hints: Array<String>, text: String, sanitized: Boolean): Line { - val line = Line(idEntry, label, hints, text, sanitized) - mLines.add(line) - mItems.put(line.labelItem.id, line.labelItem) - mItems.put(line.fieldTextItem.id, line.fieldTextItem) - return line + private fun addLine(idEntry: String, label: String, hints: Array<String>, text: String, + sanitized: Boolean) = Line(idEntry, label, hints, text, sanitized).also { + lines.add(it) + items.apply { + put(it.labelItem.id, it.labelItem) + put(it.fieldTextItem.id, it.fieldTextItem) + } } - private class Item internal constructor(val line: Line, val id: Int, val hints: Array<String>?, - val type: Int, var text: CharSequence, - val editable: Boolean, val sanitized: Boolean) { + private inner class Item internal constructor( + val line: Line, + val id: Int, + val hints: Array<String>?, + val type: Int, var text: CharSequence, val editable: Boolean, + val sanitized: Boolean) { var focused = false override fun toString(): String { @@ -213,15 +206,15 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a if (focused) { val absBounds = absCoordinates Log.d(TAG, "focus gained on " + fieldTextItem.id + "; absBounds=" + absBounds) - mAfm.notifyViewEntered(this@CustomVirtualView, fieldTextItem.id, absBounds) + autofillManager.notifyViewEntered(this@CustomVirtualView, fieldTextItem.id, absBounds) } else { Log.d(TAG, "focus lost on " + fieldTextItem.id) - mAfm.notifyViewExited(this@CustomVirtualView, fieldTextItem.id) + autofillManager.notifyViewExited(this@CustomVirtualView, fieldTextItem.id) } } - private // Must offset the boundaries so they're relative to the CustomView. - val absCoordinates: Rect + private val absCoordinates: Rect + // Must offset the boundaries so they're relative to the CustomView. get() { val offset = IntArray(2) getLocationOnScreen(offset) @@ -242,11 +235,4 @@ class CustomVirtualView(context: Context, attrs: AttributeSet) : View(context, a fieldTextItem.focused } } - - companion object { - - private val TAG = "CustomView" - - private var nextId: Int = 0 - } }
\ No newline at end of file diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/InfoButton.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/InfoButton.kt index 3a2c0e3d..5b480b8d 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/InfoButton.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/InfoButton.kt @@ -21,8 +21,11 @@ import android.support.v7.widget.AppCompatImageButton import android.util.AttributeSet import com.example.android.autofillframework.R -class InfoButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) : AppCompatImageButton(context, attrs, defStyleAttr) { +class InfoButton @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AppCompatImageButton(context, attrs, defStyleAttr) { init { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.InfoButton, @@ -34,8 +37,7 @@ class InfoButton @JvmOverloads constructor(context: Context, attrs: AttributeSet fun setInfoText(infoText: String) { setOnClickListener { - AlertDialog.Builder(this@InfoButton.context) - .setMessage(infoText).create().show() + AlertDialog.Builder(this@InfoButton.context).setMessage(infoText).create().show() } } }
\ No newline at end of file diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/NavigationItem.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/NavigationItem.kt index 0701e146..be09a99a 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/NavigationItem.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/NavigationItem.kt @@ -29,8 +29,11 @@ import kotlinx.android.synthetic.main.navigation_item.view.buttonLabel import kotlinx.android.synthetic.main.navigation_item.view.cardView import kotlinx.android.synthetic.main.navigation_item.view.infoButton -class NavigationItem @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr) { +class NavigationItem @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { init { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.NavigationItem, @@ -43,13 +46,17 @@ class NavigationItem @JvmOverloads constructor(context: Context, attrs: Attribut typedArray.recycle() LayoutInflater.from(context).inflate(R.layout.navigation_item, this) logoDrawable?.setColorFilter(imageColor, PorterDuff.Mode.SRC_IN) - buttonLabel.text = labelText - buttonLabel.setCompoundDrawablesRelativeWithIntrinsicBounds(logoDrawable, null, null, null) - infoButton.setOnClickListener { - AlertDialog.Builder(this@NavigationItem.context) - .setMessage(infoText).create().show() + buttonLabel.apply { + text = labelText + setCompoundDrawablesRelativeWithIntrinsicBounds(logoDrawable, null, null, null) + } + infoButton.apply { + setOnClickListener { + AlertDialog.Builder(this@NavigationItem.context) + .setMessage(infoText).create().show() + } + setColorFilter(imageColor) } - infoButton.setColorFilter(imageColor) } fun setNavigationButtonClickListener(l: View.OnClickListener?) { diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/StandardAutoCompleteSignInActivity.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/StandardAutoCompleteSignInActivity.kt index 21eb4d70..2e154fbf 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/StandardAutoCompleteSignInActivity.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/app/StandardAutoCompleteSignInActivity.kt @@ -33,9 +33,9 @@ import kotlinx.android.synthetic.main.login_with_autocomplete_activity.passwordF import kotlinx.android.synthetic.main.login_with_autocomplete_activity.usernameField class StandardAutoCompleteSignInActivity : AppCompatActivity() { - private var mAutofillReceived = false - private var mAutofillCallback: AutofillManager.AutofillCallback? = null - private var mAutofillManager: AutofillManager? = null + private var autofillReceived = false + private lateinit var autofillCallback: AutofillManager.AutofillCallback + private lateinit var autofillManager: AutofillManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -44,8 +44,8 @@ class StandardAutoCompleteSignInActivity : AppCompatActivity() { login.setOnClickListener { submitLogin() } clear.setOnClickListener { resetFields() } - mAutofillCallback = MyAutofillCallback() - mAutofillManager = getSystemService(AutofillManager::class.java) + autofillCallback = MyAutofillCallback() + autofillManager = getSystemService(AutofillManager::class.java) val mockAutocompleteAdapter = ArrayAdapter.createFromResource(this, R.array.mock_autocomplete_sign_in_suggestions, android.R.layout.simple_dropdown_item_1line) usernameField.setAdapter(mockAutocompleteAdapter) @@ -53,12 +53,12 @@ class StandardAutoCompleteSignInActivity : AppCompatActivity() { override fun onResume() { super.onResume() - mAutofillManager?.registerCallback(mAutofillCallback) + autofillManager.registerCallback(autofillCallback) } override fun onPause() { super.onPause() - mAutofillManager?.unregisterCallback(mAutofillCallback) + autofillManager.unregisterCallback(autofillCallback) } private fun resetFields() { @@ -96,11 +96,13 @@ class StandardAutoCompleteSignInActivity : AppCompatActivity() { if (view is AutoCompleteTextView) { when (event) { AutofillManager.AutofillCallback.EVENT_INPUT_UNAVAILABLE, - AutofillManager.AutofillCallback.EVENT_INPUT_HIDDEN -> if (!mAutofillReceived) { - view.showDropDown() + AutofillManager.AutofillCallback.EVENT_INPUT_HIDDEN -> { + if (!autofillReceived) { + view.showDropDown() + } } AutofillManager.AutofillCallback.EVENT_INPUT_SHOWN -> { - mAutofillReceived = true + autofillReceived = true view.setAdapter(null) } else -> Log.d(TAG, "Unexpected callback: " + event) diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AuthActivity.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AuthActivity.kt index eea17992..e02a311a 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AuthActivity.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AuthActivity.kt @@ -46,7 +46,7 @@ import kotlinx.android.synthetic.main.multidataset_service_auth_activity.master_ */ class AuthActivity : AppCompatActivity() { - private var mReplyIntent: Intent? = null + private var replyIntent: Intent? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -70,8 +70,8 @@ class AuthActivity : AppCompatActivity() { } override fun finish() { - if (mReplyIntent != null) { - setResult(Activity.RESULT_OK, mReplyIntent) + if (replyIntent != null) { + setResult(Activity.RESULT_OK, replyIntent) } else { setResult(Activity.RESULT_CANCELED) } @@ -80,7 +80,7 @@ class AuthActivity : AppCompatActivity() { private fun onFailure() { Log.w(TAG, "Failed auth.") - mReplyIntent = null + replyIntent = null } private fun onSuccess() { @@ -90,7 +90,7 @@ class AuthActivity : AppCompatActivity() { val parser = StructureParser(structure) parser.parseForFill() val autofillFields = parser.autofillFields - mReplyIntent = Intent() + replyIntent = Intent() val clientFormDataMap = SharedPrefsAutofillRepository .getFilledAutofillFieldCollection(this, autofillFields.focusedAutofillHints, autofillFields.allAutofillHints) if (forResponse) { @@ -106,11 +106,11 @@ class AuthActivity : AppCompatActivity() { } private fun setResponseIntent(fillResponse: FillResponse) { - mReplyIntent?.putExtra(EXTRA_AUTHENTICATION_RESULT, fillResponse) + replyIntent?.putExtra(EXTRA_AUTHENTICATION_RESULT, fillResponse) } private fun setDatasetIntent(dataset: Dataset) { - mReplyIntent?.putExtra(EXTRA_AUTHENTICATION_RESULT, dataset) + replyIntent?.putExtra(EXTRA_AUTHENTICATION_RESULT, dataset) } companion object { diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadata.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadata.kt index f894a18b..bf12c574 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadata.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadata.kt @@ -28,7 +28,7 @@ class AutofillFieldMetadata(view: ViewNode) { var saveType = 0 private set - val autofillHints: Array<String> = view.autofillHints.filter(AutofillHelper::isValidHint).toTypedArray() + val autofillHints = view.autofillHints.filter(AutofillHelper::isValidHint).toTypedArray() val autofillId: AutofillId = view.autofillId val autofillType: Int = view.autofillType val autofillOptions: Array<CharSequence>? = view.autofillOptions @@ -42,8 +42,12 @@ class AutofillFieldMetadata(view: ViewNode) { * When the [ViewNode] is a list that the user needs to choose a string from (i.e. a spinner), * this is called to return the index of a specific item in the list. */ - fun getAutofillOptionIndex(value: CharSequence): Int? { - return autofillOptions?.indexOf(value) + fun getAutofillOptionIndex(value: CharSequence): Int { + if (autofillOptions != null) { + return autofillOptions.indexOf(value) + } else { + return -1 + } } private fun updateSaveTypeFromHints() { diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadataCollection.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadataCollection.kt index 4aa3e1fd..1044ec78 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadataCollection.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/AutofillFieldMetadataCollection.kt @@ -21,11 +21,13 @@ import android.view.autofill.AutofillId * Data structure that stores a collection of `AutofillFieldMetadata`s. Contains all of the client's `View` * hierarchy autofill-relevant metadata. */ -data class AutofillFieldMetadataCollection(val autofillIds: java.util.ArrayList<AutofillId> = java.util.ArrayList<AutofillId>(), - val allAutofillHints: java.util.ArrayList<String> = java.util.ArrayList<String>(), - val focusedAutofillHints: java.util.ArrayList<String> = java.util.ArrayList<String>()) { +data class AutofillFieldMetadataCollection @JvmOverloads constructor( + val autofillIds: ArrayList<AutofillId> = ArrayList<AutofillId>(), + val allAutofillHints: ArrayList<String> = ArrayList<String>(), + val focusedAutofillHints: ArrayList<String> = ArrayList<String>() +) { - private val autofillHintsToFieldsMap = java.util.HashMap<String, MutableList<AutofillFieldMetadata>>() + private val autofillHintsToFieldsMap = HashMap<String, MutableList<AutofillFieldMetadata>>() var saveType = 0 private set @@ -37,9 +39,10 @@ data class AutofillFieldMetadataCollection(val autofillIds: java.util.ArrayList< if (autofillFieldMetadata.isFocused) { focusedAutofillHints.addAll(hintsList) } - autofillFieldMetadata.autofillHints.forEach { autofillHint -> - autofillHintsToFieldsMap[autofillHint] = autofillHintsToFieldsMap[autofillHint] ?: java.util.ArrayList<AutofillFieldMetadata>() - autofillHintsToFieldsMap[autofillHint]?.add(autofillFieldMetadata) + autofillFieldMetadata.autofillHints.forEach { + val fields = autofillHintsToFieldsMap[it] ?: ArrayList<AutofillFieldMetadata>() + autofillHintsToFieldsMap[it] = fields + fields.add(autofillFieldMetadata) } } diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/StructureParser.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/StructureParser.kt index f185b8ea..e5042101 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/StructureParser.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/StructureParser.kt @@ -27,12 +27,11 @@ import com.example.android.autofillframework.multidatasetservice.model.FilledAut * AssistStructure from the client Activity, representing its View hierarchy. In this sample, it * parses the hierarchy and collects autofill metadata from {@link ViewNode}s along the way. */ -internal class StructureParser(private val mStructure: AssistStructure) { +internal class StructureParser(private val autofillStructure: AssistStructure) { val autofillFields = AutofillFieldMetadataCollection() var filledAutofillFieldCollection: FilledAutofillFieldCollection = FilledAutofillFieldCollection() private set - fun parseForFill() { parse(true) } @@ -45,13 +44,11 @@ internal class StructureParser(private val mStructure: AssistStructure) { * Traverse AssistStructure and add ViewNode metadata to a flat list. */ private fun parse(forFill: Boolean) { - Log.d(TAG, "Parsing structure for " + mStructure.activityComponent) - val nodes = mStructure.windowNodeCount + Log.d(TAG, "Parsing structure for " + autofillStructure.activityComponent) + val nodes = autofillStructure.windowNodeCount filledAutofillFieldCollection = FilledAutofillFieldCollection() - for (i in 0..nodes - 1) { - val node = mStructure.getWindowNodeAt(i) - val view = node.rootViewNode - parseLocked(forFill, view) + for (i in 0 until nodes) { + parseLocked(forFill, autofillStructure.getWindowNodeAt(i).rootViewNode) } } @@ -66,10 +63,9 @@ internal class StructureParser(private val mStructure: AssistStructure) { } } val childrenSize = viewNode.childCount - if (childrenSize > 0) { - for (i in 0..childrenSize - 1) { - parseLocked(forFill, viewNode.getChildAt(i)) - } + for (i in 0 until childrenSize) { + parseLocked(forFill, viewNode.getChildAt(i)) + } } } diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/AutofillRepository.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/AutofillRepository.kt index 00a7d8df..4cb5ab87 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/AutofillRepository.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/AutofillRepository.kt @@ -31,7 +31,8 @@ interface AutofillRepository { /** * Saves LoginCredential under this datasetName. */ - fun saveFilledAutofillFieldCollection(context: Context, filledAutofillFieldCollection: FilledAutofillFieldCollection) + fun saveFilledAutofillFieldCollection(context: Context, + filledAutofillFieldCollection: FilledAutofillFieldCollection) /** * Clears all data. diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/SharedPrefsAutofillRepository.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/SharedPrefsAutofillRepository.kt index 98119152..1e7ed0da 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/SharedPrefsAutofillRepository.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/datasource/SharedPrefsAutofillRepository.kt @@ -18,6 +18,7 @@ package com.example.android.autofillframework.multidatasetservice.datasource import android.content.Context import android.content.SharedPreferences import android.util.ArraySet +import com.example.android.autofillframework.CommonUtil import com.example.android.autofillframework.multidatasetservice.model.FilledAutofillFieldCollection import com.google.gson.Gson import com.google.gson.GsonBuilder @@ -43,19 +44,19 @@ object SharedPrefsAutofillRepository : AutofillRepository { var hasDataForFocusedAutofillHints = false val clientFormDataMap = HashMap<String, FilledAutofillFieldCollection>() val clientFormDataStringSet = getAllAutofillDataStringSet(context) + val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create() + val type = object : TypeToken<FilledAutofillFieldCollection>() {}.type for (clientFormDataString in clientFormDataStringSet) { - val type = object : TypeToken<FilledAutofillFieldCollection>() {}.type - val gson: Gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create() - gson.fromJson<FilledAutofillFieldCollection>(clientFormDataString, type)?.let { clientFormData -> - if (clientFormData.helpsWithHints(focusedAutofillHints)) { + gson.fromJson<FilledAutofillFieldCollection>(clientFormDataString, type)?.let { + if (it.helpsWithHints(focusedAutofillHints)) { // Saved data has data relevant to at least 1 of the hints associated with the // View in focus. hasDataForFocusedAutofillHints = true - clientFormData.datasetName?.let { datasetName -> - if (clientFormData.helpsWithHints(allAutofillHints)) { + it.datasetName?.let { datasetName -> + if (it.helpsWithHints(allAutofillHints)) { // Saved data has data relevant to at least 1 of these hints associated with any // of the Views in the hierarchy. - clientFormDataMap.put(datasetName, clientFormData) + clientFormDataMap.put(datasetName, it) } } } @@ -72,7 +73,7 @@ object SharedPrefsAutofillRepository : AutofillRepository { val datasetName = "dataset-" + getDatasetNumber(context) filledAutofillFieldCollection.datasetName = datasetName val allAutofillData = getAllAutofillDataStringSet(context) - val gson: Gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create() + val gson = CommonUtil.createGson() allAutofillData.add(gson.toJson(filledAutofillFieldCollection).toString()) saveAllAutofillDataStringSet(context, allAutofillData) incrementDatasetNumber(context) @@ -86,7 +87,8 @@ object SharedPrefsAutofillRepository : AutofillRepository { return getPrefs(context).getStringSet(CLIENT_FORM_DATA_KEY, ArraySet<String>()) } - private fun saveAllAutofillDataStringSet(context: Context, allAutofillDataStringSet: Set<String>) { + private fun saveAllAutofillDataStringSet(context: Context, + allAutofillDataStringSet: Set<String>) { getPrefs(context).edit().putStringSet(CLIENT_FORM_DATA_KEY, allAutofillDataStringSet).apply() } diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillField.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillField.kt index 64617ccf..7421cbcd 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillField.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillField.kt @@ -33,24 +33,23 @@ class FilledAutofillField(viewNode: AssistStructure.ViewNode) { @Expose var toggleValue: Boolean? = null - val autofillHints: Array<String> = - viewNode.autofillHints.filter(AutofillHelper::isValidHint).toTypedArray() + val autofillHints = viewNode.autofillHints.filter(AutofillHelper::isValidHint).toTypedArray() init { - viewNode.autofillValue?.let { autofillValue -> - if (autofillValue.isList) { - val index = autofillValue.listValue + viewNode.autofillValue?.let { + if (it.isList) { + val index = it.listValue viewNode.autofillOptions?.let { autofillOptions -> if (autofillOptions.size > index) { textValue = autofillOptions[index].toString() } } - } else if (autofillValue.isDate) { - dateValue = autofillValue.dateValue - } else if (autofillValue.isText) { + } else if (it.isDate) { + dateValue = it.dateValue + } else if (it.isText) { // Using toString of AutofillValue.getTextValue in order to save it to // SharedPreferences. - textValue = autofillValue.textValue.toString() + textValue = it.textValue.toString() } else { } } diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillFieldCollection.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillFieldCollection.kt index 2de46809..cef29185 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillFieldCollection.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/model/FilledAutofillFieldCollection.kt @@ -30,8 +30,11 @@ import java.util.HashMap * FilledAutofillFieldCollection is the model that represents all of the form data on a client app's page, plus the * dataset name associated with it. */ -class FilledAutofillFieldCollection constructor(@Expose var datasetName: String? = null, - @Expose private val hintMap: HashMap<String, FilledAutofillField> = HashMap<String, FilledAutofillField>()) { +class FilledAutofillFieldCollection @JvmOverloads constructor( + @Expose var datasetName: String? = null, + @Expose private val hintMap: HashMap<String, FilledAutofillField> = HashMap<String, + FilledAutofillField>() +) { /** * Sets values for a list of autofillHints. @@ -60,9 +63,12 @@ class FilledAutofillFieldCollection constructor(@Expose var datasetName: String? val savedAutofillValue = hintMap[hint] when (autofillType) { View.AUTOFILL_TYPE_LIST -> { - savedAutofillValue?.textValue?.let(autofillField::getAutofillOptionIndex)?.let { index -> - datasetBuilder.setValue(autofillId, AutofillValue.forList(index)) - setValueAtLeastOnce = true + savedAutofillValue?.textValue?.let { + val index = autofillField.getAutofillOptionIndex(it) + if (index != -1) { + datasetBuilder.setValue(autofillId, AutofillValue.forList(index)) + setValueAtLeastOnce = true + } } } View.AUTOFILL_TYPE_DATE -> { diff --git a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/settings/SettingsActivity.kt b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/settings/SettingsActivity.kt index e314ccd7..5004fa26 100644 --- a/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/settings/SettingsActivity.kt +++ b/input/autofill/AutofillFramework/kotlinApp/Application/src/main/java/com/example/android/autofillframework/multidatasetservice/settings/SettingsActivity.kt @@ -70,9 +70,11 @@ class SettingsActivity : AppCompatActivity() { settings_auth_credentials_label, settings_auth_credentials_icon, View.OnClickListener { - MyPreferences.getMasterPassword(this@SettingsActivity)?.let { + if (MyPreferences.getMasterPassword(this@SettingsActivity) != null) { buildCurrentCredentialsDialog().show() - } ?: buildNewCredentialsDialog().show() + } else { + buildNewCredentialsDialog().show() + } }) } @@ -132,10 +134,12 @@ class SettingsActivity : AppCompatActivity() { private fun setupSettingsSwitch(container: ViewGroup, switchLabelView: TextView, switchView: Switch, checked: Boolean, checkedChangeListener: CompoundButton.OnCheckedChangeListener) { val switchLabel = switchLabelView.text.toString() - switchView.contentDescription = switchLabel - switchView.isChecked = checked + with(switchView) { + contentDescription = switchLabel + isChecked = checked + setOnCheckedChangeListener (checkedChangeListener) + } container.setOnClickListener { switchView.performClick() } - switchView.setOnCheckedChangeListener(checkedChangeListener) } private fun setupSettingsButton(container: ViewGroup, buttonLabelView: TextView, imageView: ImageView, |