16fa8a07143d1984ff42750079cf596a868644663Felipe Leme/* 26fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Copyright (C) 2017 The Android Open Source Project 36fa8a07143d1984ff42750079cf596a868644663Felipe Leme * 46fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 56fa8a07143d1984ff42750079cf596a868644663Felipe Leme * you may not use this file except in compliance with the License. 66fa8a07143d1984ff42750079cf596a868644663Felipe Leme * You may obtain a copy of the License at 76fa8a07143d1984ff42750079cf596a868644663Felipe Leme * 86fa8a07143d1984ff42750079cf596a868644663Felipe Leme * http://www.apache.org/licenses/LICENSE-2.0 96fa8a07143d1984ff42750079cf596a868644663Felipe Leme * 106fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Unless required by applicable law or agreed to in writing, software 116fa8a07143d1984ff42750079cf596a868644663Felipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 126fa8a07143d1984ff42750079cf596a868644663Felipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136fa8a07143d1984ff42750079cf596a868644663Felipe Leme * See the License for the specific language governing permissions and 146fa8a07143d1984ff42750079cf596a868644663Felipe Leme * limitations under the License. 156fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 166fa8a07143d1984ff42750079cf596a868644663Felipe Leme 176fa8a07143d1984ff42750079cf596a868644663Felipe Lemepackage com.android.server.autofill; 186fa8a07143d1984ff42750079cf596a868644663Felipe Leme 198697a31d3c32f212cee48b4d0576e8783c6c9d5fFelipe Lemeimport static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; 209f9ee25515591ef33281708c0ab911962f4364a6Felipe Lemeimport static com.android.server.autofill.Helper.sDebug; 21c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Lemeimport static com.android.server.autofill.Helper.sVerbose; 22f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme 236fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport android.annotation.Nullable; 246fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport android.graphics.Rect; 256fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport android.service.autofill.FillResponse; 260f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Lemeimport android.util.DebugUtils; 27f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Lemeimport android.util.Slog; 286fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport android.view.autofill.AutofillId; 296fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport android.view.autofill.AutofillValue; 306fa8a07143d1984ff42750079cf596a868644663Felipe Leme 316fa8a07143d1984ff42750079cf596a868644663Felipe Lemeimport java.io.PrintWriter; 326fa8a07143d1984ff42750079cf596a868644663Felipe Leme 336fa8a07143d1984ff42750079cf596a868644663Felipe Leme/** 346fa8a07143d1984ff42750079cf596a868644663Felipe Leme * State for a given view with a AutofillId. 356fa8a07143d1984ff42750079cf596a868644663Felipe Leme * 366fa8a07143d1984ff42750079cf596a868644663Felipe Leme * <p>This class holds state about a view and calls its listener when the fill UI is ready to 376fa8a07143d1984ff42750079cf596a868644663Felipe Leme * be displayed for the view. 386fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 396fa8a07143d1984ff42750079cf596a868644663Felipe Lemefinal class ViewState { 406fa8a07143d1984ff42750079cf596a868644663Felipe Leme interface Listener { 416fa8a07143d1984ff42750079cf596a868644663Felipe Leme /** 426fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Called when the fill UI is ready to be shown for this view. 436fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 446fa8a07143d1984ff42750079cf596a868644663Felipe Leme void onFillReady(FillResponse fillResponse, AutofillId focusedId, 456fa8a07143d1984ff42750079cf596a868644663Felipe Leme @Nullable AutofillValue value); 466fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 476fa8a07143d1984ff42750079cf596a868644663Felipe Leme 48f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme private static final String TAG = "ViewState"; 49f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme 500f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme // NOTE: state constants must be public because of flagstoString(). 519a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_UNKNOWN = 0x000; 520f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme /** Initial state. */ 539a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_INITIAL = 0x001; 540f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme /** View id is present in a dataset returned by the service. */ 559a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_FILLABLE = 0x002; 560f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme /** View was autofilled after user selected a dataset. */ 579a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_AUTOFILLED = 0x004; 580f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme /** View value was changed, but not by the service. */ 599a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_CHANGED = 0x008; 6078696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme /** Set only in the View that started a session. */ 619a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_STARTED_SESSION = 0x010; 62f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme /** View that started a new partition when focused on. */ 639a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_STARTED_PARTITION = 0x020; 64f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme /** User select a dataset in this view, but service must authenticate first. */ 659a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_WAITING_DATASET_AUTH = 0x040; 66c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme /** Service does not care about this view. */ 679a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_IGNORED = 0x080; 689a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme /** User manually request autofill in this view, after it was already autofilled. */ 699a2e6058df51e94417dcedd4c7dd2a0cc380dcb1Felipe Leme public static final int STATE_RESTARTED_SESSION = 0x100; 700f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 710f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme public final AutofillId id; 720aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme 736fa8a07143d1984ff42750079cf596a868644663Felipe Leme private final Listener mListener; 746fa8a07143d1984ff42750079cf596a868644663Felipe Leme private final Session mSession; 756fa8a07143d1984ff42750079cf596a868644663Felipe Leme 760aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme private FillResponse mResponse; 770f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme private AutofillValue mCurrentValue; 7878696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme private AutofillValue mAutofilledValue; 790f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme private Rect mVirtualBounds; 800f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme private int mState; 816fa8a07143d1984ff42750079cf596a868644663Felipe Leme 82e8f68080795374c4c3ee25a068990d602e63320fFelipe Leme ViewState(Session session, AutofillId id, Listener listener, int state) { 836fa8a07143d1984ff42750079cf596a868644663Felipe Leme mSession = session; 840f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme this.id = id; 856fa8a07143d1984ff42750079cf596a868644663Felipe Leme mListener = listener; 860f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme mState = state; 876fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 886fa8a07143d1984ff42750079cf596a868644663Felipe Leme 896fa8a07143d1984ff42750079cf596a868644663Felipe Leme /** 900f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme * Gets the boundaries of the virtual view, or {@code null} if the the view is not virtual. 916fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 920f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme @Nullable 930f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme Rect getVirtualBounds() { 940f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme return mVirtualBounds; 956fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 966fa8a07143d1984ff42750079cf596a868644663Felipe Leme 976fa8a07143d1984ff42750079cf596a868644663Felipe Leme /** 980f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme * Gets the current value of the view. 996fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 1000f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme @Nullable 1010f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme AutofillValue getCurrentValue() { 1020f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme return mCurrentValue; 1030f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1040f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 10578696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme void setCurrentValue(AutofillValue value) { 10678696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme mCurrentValue = value; 10778696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme } 10878696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme 10978696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme @Nullable 11078696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme AutofillValue getAutofilledValue() { 11178696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme return mAutofilledValue; 1120f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1130f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 114a9379d0b44ca1f68a0036d2b65218e17fa348514Svetoslav Ganov void setAutofilledValue(@Nullable AutofillValue value) { 11578696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme mAutofilledValue = value; 11678696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme } 11778696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme 11878696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme @Nullable 1190f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme FillResponse getResponse() { 1200f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme return mResponse; 1216fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1226fa8a07143d1984ff42750079cf596a868644663Felipe Leme 12378696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme void setResponse(FillResponse response) { 12478696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme mResponse = response; 1256fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1266fa8a07143d1984ff42750079cf596a868644663Felipe Leme 12778696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme CharSequence getServiceName() { 12878696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme return mSession.getServiceName(); 1290f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1300f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 1310f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme int getState() { 1320f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme return mState; 1330f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1340f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 1350f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme String getStateAsString() { 1360f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme return DebugUtils.flagsToString(ViewState.class, "STATE_", mState); 1370f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1380f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 1390f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme void setState(int state) { 140f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme if (mState == STATE_INITIAL) { 141f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme mState = state; 142f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme } else { 143f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme mState |= state; 144f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme } 145f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme } 146f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme 147f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme void resetState(int state) { 148f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme mState &= ~state; 1490f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1500f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme 15185d1c2d2905362b984563d9b5e8332010c272fc5Felipe Leme // TODO: refactor / rename / document this method (and maybeCallOnFillReady) to make it clear 15285d1c2d2905362b984563d9b5e8332010c272fc5Felipe Leme // that it can change the value and update the UI; similarly, should replace code that 15385d1c2d2905362b984563d9b5e8332010c272fc5Felipe Leme // directly sets mAutofillValue to use encapsulation. 1548697a31d3c32f212cee48b4d0576e8783c6c9d5fFelipe Leme void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds, int flags) { 1556fa8a07143d1984ff42750079cf596a868644663Felipe Leme if (autofillValue != null) { 1560f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme mCurrentValue = autofillValue; 1576fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1586fa8a07143d1984ff42750079cf596a868644663Felipe Leme if (virtualBounds != null) { 1596fa8a07143d1984ff42750079cf596a868644663Felipe Leme mVirtualBounds = virtualBounds; 1606fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1616fa8a07143d1984ff42750079cf596a868644663Felipe Leme 1628697a31d3c32f212cee48b4d0576e8783c6c9d5fFelipe Leme maybeCallOnFillReady(flags); 1636fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1646fa8a07143d1984ff42750079cf596a868644663Felipe Leme 1656fa8a07143d1984ff42750079cf596a868644663Felipe Leme /** 1666fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Calls {@link 1676fa8a07143d1984ff42750079cf596a868644663Felipe Leme * Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the 1686fa8a07143d1984ff42750079cf596a868644663Felipe Leme * fill UI is ready to be displayed (i.e. when response and bounds are set). 1696fa8a07143d1984ff42750079cf596a868644663Felipe Leme */ 1708697a31d3c32f212cee48b4d0576e8783c6c9d5fFelipe Leme void maybeCallOnFillReady(int flags) { 1718697a31d3c32f212cee48b4d0576e8783c6c9d5fFelipe Leme if ((mState & STATE_AUTOFILLED) != 0 && (flags & FLAG_MANUAL_REQUEST) == 0) { 1729f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme if (sDebug) Slog.d(TAG, "Ignoring UI for " + id + " on " + getStateAsString()); 173f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme return; 174f43ca7968fed9fe8862d9b7217c94687dbb12e0aFelipe Leme } 1750f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme // First try the current response associated with this View. 1760f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme if (mResponse != null) { 177a9379d0b44ca1f68a0036d2b65218e17fa348514Svetoslav Ganov if (mResponse.getDatasets() != null || mResponse.getAuthentication() != null) { 1780f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme mListener.onFillReady(mResponse, this.id, mCurrentValue); 1790f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme } 1806fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1816fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1826fa8a07143d1984ff42750079cf596a868644663Felipe Leme 1836fa8a07143d1984ff42750079cf596a868644663Felipe Leme @Override 1846fa8a07143d1984ff42750079cf596a868644663Felipe Leme public String toString() { 185e8f68080795374c4c3ee25a068990d602e63320fFelipe Leme return "ViewState: [id=" + id + ", currentValue=" + mCurrentValue 186e8f68080795374c4c3ee25a068990d602e63320fFelipe Leme + ", autofilledValue=" + mAutofilledValue 187cde040ae9563600179502f8ce8dd06bc7bb5a1c0Felipe Leme + ", bounds=" + mVirtualBounds + ", state=" + getStateAsString() + "]"; 1886fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 1896fa8a07143d1984ff42750079cf596a868644663Felipe Leme 1906fa8a07143d1984ff42750079cf596a868644663Felipe Leme void dump(String prefix, PrintWriter pw) { 1910f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme pw.print(prefix); pw.print("id:" ); pw.println(this.id); 1920f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme pw.print(prefix); pw.print("state:" ); pw.println(getStateAsString()); 193c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme pw.print(prefix); pw.print("response:"); 194c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme if (mResponse == null) { 195c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme pw.println("N/A"); 196c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme } else { 197c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme if (sVerbose) { 198c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme pw.println(mResponse); 199c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme } else { 200c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme pw.println(mResponse.getRequestId()); 201c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme } 202c2430f3c4d6e3b996917f57c8afb0b00b5bef45bFelipe Leme } 2030f9464e1729bbc5a018436244c3ad7bfe69eea6aFelipe Leme pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue); 20478696bfeb7ac5ae298765bfb9f82cf24d12b7dccFelipe Leme pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue); 2056fa8a07143d1984ff42750079cf596a868644663Felipe Leme pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds); 2066fa8a07143d1984ff42750079cf596a868644663Felipe Leme } 2076fa8a07143d1984ff42750079cf596a868644663Felipe Leme}