AutofillManagerServiceImpl.java revision 49e96960d46022c85d1f6d00440242439f2028ec
15381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme/*
25381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * Copyright (C) 2016 The Android Open Source Project
35381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
45381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
55381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * you may not use this file except in compliance with the License.
65381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * You may obtain a copy of the License at
75381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
85381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
95381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
105381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * Unless required by applicable law or agreed to in writing, software
115381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
125381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * See the License for the specific language governing permissions and
145381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * limitations under the License.
155381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme */
165381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
175381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemepackage com.android.server.autofill;
185381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
19eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport static android.service.autofill.AutofillService.EXTRA_SESSION_ID;
20bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
21bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
22640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport static android.view.autofill.AutofillManager.FLAG_START_SESSION;
23eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport static android.view.autofill.AutofillManager.NO_SESSION;
24bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
25bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport static com.android.server.autofill.Helper.DEBUG;
260200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Lemeimport static com.android.server.autofill.Helper.VERBOSE;
27dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme
287b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmannimport android.annotation.NonNull;
296d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.annotation.Nullable;
306d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.app.Activity;
3129a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Lemeimport android.app.ActivityManager;
32782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.app.AppGlobals;
336d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.app.assist.AssistStructure;
345381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.ComponentName;
355381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.Context;
368eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Lemeimport android.content.pm.ApplicationInfo;
375381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.pm.PackageManager;
38782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.content.pm.ServiceInfo;
39bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.graphics.Rect;
40782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.Binder;
416d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Bundle;
425381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.IBinder;
43bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport android.os.Looper;
44782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.RemoteCallbackList;
455381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.RemoteException;
46f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganovimport android.os.UserHandle;
4724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Lemeimport android.os.UserManager;
48782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.provider.Settings;
49640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillService;
50640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillServiceInfo;
51cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillEventHistory;
5249e96960d46022c85d1f6d00440242439f2028ecFelipe Lemeimport android.service.autofill.FillEventHistory.Event;
53013efe173e56612a910ebd8576480ce4ef005e3cSvet Ganovimport android.service.autofill.FillRequest;
54cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillResponse;
555381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.service.autofill.IAutoFillService;
56782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.text.TextUtils;
57bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.util.LocalLog;
589668903731c272e51ce610598c052ef411c9d89fPhilip P. Moltmannimport android.util.Log;
595381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.util.PrintWriterPrinter;
605381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.util.Slog;
61eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport android.util.SparseArray;
62640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillId;
63640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillValue;
64782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.IAutoFillManagerClient;
656fa8a07143d1984ff42750079cf596a868644663Felipe Leme
66ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Lemeimport com.android.internal.R;
675381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport com.android.internal.annotations.GuardedBy;
68bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport com.android.internal.os.HandlerCaller;
696d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport com.android.internal.os.IResultReceiver;
7028a2c7e0579dbcbde09b6e23a17b0a501a3562b9Svet Ganovimport com.android.server.autofill.ui.AutoFillUI;
715381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
725381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport java.io.PrintWriter;
7369a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Lemeimport java.util.ArrayList;
74eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport java.util.Random;
755381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
765381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme/**
772f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
785381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * app's {@link IAutoFillService} implementation.
795381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
805381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme */
812f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganovfinal class AutofillManagerServiceImpl {
825381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
832f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    private static final String TAG = "AutofillManagerServiceImpl";
84eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
855381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
866fa8a07143d1984ff42750079cf596a868644663Felipe Leme    static final int MSG_SERVICE_SAVE = 1;
876d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
88dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme    private final int mUserId;
895381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Context mContext;
905381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Object mLock;
910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final AutoFillUI mUi;
925381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
93782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private RemoteCallbackList<IAutoFillManagerClient> mClients;
94640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme    private AutofillServiceInfo mInfo;
95bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
96eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final Random sRandom = new Random();
97eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
98782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private final LocalLog mRequestsHistory;
9924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    /**
10024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     * Whether service was disabled for user due to {@link UserManager} restrictions.
10124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     */
10224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    private boolean mDisabled;
1035381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
104bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
105bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        switch (msg.what) {
106bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            case MSG_SERVICE_SAVE:
107eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                handleSessionSave(msg.arg1);
108bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                break;
109bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            default:
1100ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme                Slog.w(TAG, "invalid msg on handler: " + msg);
111bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
112bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    };
113bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
114bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
115bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            mHandlerCallback, true);
116782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
1176d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
118bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme     * Cache of pending {@link Session}s, keyed by {@code activityToken}.
1196d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     *
120640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme     * <p>They're kept until the {@link AutofillService} finished handling a request, an error
121436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme     * occurs, or the session times out.
1226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
123436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    // TODO(b/33197203): need to make sure service is bound while callback is pending and/or
124436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    // use WeakReference
1256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @GuardedBy("mLock")
126eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private final SparseArray<Session> mSessions = new SparseArray<>();
1275381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
128cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /** The last selection */
129cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    @GuardedBy("mLock")
130cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    private FillEventHistory mEventHistory;
131cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
1326d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
133bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme     * Receiver of assist data from the app's {@link Activity}.
1346d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
1356d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
1366d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        @Override
1376d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        public void send(int resultCode, Bundle resultData) throws RemoteException {
1380ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            if (VERBOSE) {
1390ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme                Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
1400ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            }
1416d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
142bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
1430f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            if (structure == null) {
1440ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme                Slog.wtf(TAG, "no assist structure for id " + resultCode);
1450f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov                return;
1460f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov            }
1476d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
148bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            final Bundle receiverExtras = resultData.getBundle(KEY_RECEIVER_EXTRAS);
149bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            if (receiverExtras == null) {
150bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                Slog.wtf(TAG, "No " + KEY_RECEIVER_EXTRAS + " on receiver");
151bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                return;
152bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            }
153bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
154eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final int sessionId = receiverExtras.getInt(EXTRA_SESSION_ID);
155436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            final Session session;
1566d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            synchronized (mLock) {
157eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                session = mSessions.get(sessionId);
158436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme                if (session == null) {
159eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                    Slog.w(TAG, "no server session for " + sessionId);
1606d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme                    return;
1616d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme                }
162bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                // TODO(b/33197203): since service is fetching the data (to use for save later),
163bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                // we should optimize what's sent (for example, remove layout containers,
164bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                // color / font info, etc...)
16552d5d3dfc7d4d4b6dfed1686cc904c08d7433a04Felipe Leme                session.setStructureLocked(structure);
1666d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            }
1676d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
168f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme
169f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // TODO(b/33197203, b/33269702): Must fetch the data so it's available later on
170f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // handleSave(), even if if the activity is gone by then, but structure.ensureData()
171f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // gives a ONE_WAY warning because system_service could block on app calls.
172f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // We need to change AssistStructure so it provides a "one-way" writeToParcel()
173f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // method that sends all the data
174f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            structure.ensureData();
175f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme
176f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            // Sanitize structure before it's sent to service.
177f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme            structure.sanitizeForParceling(true);
178f894be41d61d0f0bbd985f61f156a1b7489d6f75Felipe Leme
179bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            // TODO(b/33197203): Need to pipe the bundle
180013efe173e56612a910ebd8576480ce4ef005e3cSvet Ganov            FillRequest request = new FillRequest(structure, null, session.mFlags);
181013efe173e56612a910ebd8576480ce4ef005e3cSvet Ganov            session.mRemoteFillService.onFillRequest(request);
1820f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        }
1830f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    };
1840f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov
1852f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
18624d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme            int userId, AutoFillUI ui, boolean disabled) {
1875381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mContext = context;
1885381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mLock = lock;
189bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme        mRequestsHistory = requestsHistory;
190dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme        mUserId = userId;
1910f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mUi = ui;
19224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        updateLocked(disabled);
1935381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
1945381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
1958eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    CharSequence getServiceName() {
1968eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        if (mInfo == null) {
1978eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return null;
1988eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
1998eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        final ComponentName serviceComponent = mInfo.getServiceInfo().getComponentName();
2008eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        final String packageName = serviceComponent.getPackageName();
2018eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
2028eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        try {
2038eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final PackageManager pm = mContext.getPackageManager();
2048eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
2058eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return pm.getApplicationLabel(info);
2068eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        } catch (Exception e) {
2070ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            Slog.e(TAG, "Could not get label for " + packageName + ": " + e);
2088eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return packageName;
2098eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
2108eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    }
2118eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
21298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    private String getComponentNameFromSettings() {
21398d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        return Settings.Secure.getStringForUser(
21498d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme                mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
21598d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    }
21698d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme
21724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    void updateLocked(boolean disabled) {
21824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        final boolean wasEnabled = isEnabled();
21924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        mDisabled = disabled;
220782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ComponentName serviceComponent = null;
221782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ServiceInfo serviceInfo = null;
22298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        final String componentName = getComponentNameFromSettings();
223782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (!TextUtils.isEmpty(componentName)) {
224782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            try {
225782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceComponent = ComponentName.unflattenFromString(componentName);
226782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
227782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        0, mUserId);
228782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } catch (RuntimeException | RemoteException e) {
229640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
230782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
231782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
232782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
233782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
234782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (serviceInfo != null) {
235640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                mInfo = new AutofillServiceInfo(mContext.getPackageManager(),
236782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        serviceComponent, mUserId);
237782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } else {
238782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                mInfo = null;
239782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
24024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme            if (wasEnabled != isEnabled()) {
24124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                if (!isEnabled()) {
242782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    final int sessionCount = mSessions.size();
243782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    for (int i = sessionCount - 1; i >= 0; i--) {
2446d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        final Session session = mSessions.valueAt(i);
2456d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        session.removeSelfLocked();
246782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    }
247782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
248782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                sendStateToClients();
249782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
250782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        } catch (PackageManager.NameNotFoundException e) {
251640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme            Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
252782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
253782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
2545381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
2550f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    /**
2562f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov     * Used by {@link AutofillManagerServiceShellCommand} to request save for the current top app.
2570f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     */
2580f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void requestSaveForUserLocked(IBinder activityToken) {
25924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
260782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
261782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
262eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
263eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
264eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
265eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final Session session = mSessions.valueAt(i);
266eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            if (session.getActivityTokenLocked().equals(activityToken)) {
267eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                session.callSaveLocked();
268eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                return;
269eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            }
270bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
271bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
272eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
2735381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
2745381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
275782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    boolean addClientLocked(IAutoFillManagerClient client) {
276782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (mClients == null) {
277782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            mClients = new RemoteCallbackList<>();
278782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
279782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        mClients.register(client);
28024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        return isEnabled();
281782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
282782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
283eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void setAuthenticationResultLocked(Bundle data, int sessionId, int uid) {
28424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
285782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
286782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
287eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
288eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
289782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            session.setAuthenticationResultLocked(data);
290782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
291782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
292782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
293eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void setHasCallback(int sessionId, int uid, boolean hasIt) {
29424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
295e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme            return;
296e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
297eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
298eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
299e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme            session.setHasCallback(hasIt);
300e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
301e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme    }
302e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme
303eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    int startSessionLocked(@NonNull IBinder activityToken, int uid, @Nullable IBinder windowToken,
3044753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
3054753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
3064753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            int flags, @NonNull String packageName) {
30724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
308eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return 0;
309782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
310782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
311eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session newSession = createSessionByTokenLocked(activityToken, uid, windowToken,
312eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                appCallbackToken, hasCallback, flags, packageName);
313eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (newSession == null) {
314eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return NO_SESSION;
315bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
316bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
317eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final String historyItem =
318eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                "id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
319eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
320eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        hasCallback + " f=" + flags;
321eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mRequestsHistory.log(historyItem);
322eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
3234753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        newSession.updateLocked(autofillId, virtualBounds, value, FLAG_START_SESSION);
324eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
325eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        return newSession.id;
326226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
327bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
328eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void finishSessionLocked(int sessionId, int uid) {
32924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
330782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
331782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
332bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
333eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
334eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
335eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            Slog.w(TAG, "finishSessionLocked(): no session for " + sessionId + "(" + uid + ")");
336bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            return;
33729a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        }
338bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
3396d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        final boolean finished = session.showSaveLocked();
3406d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        if (DEBUG) {
3416d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme            Log.d(TAG, "finishSessionLocked(): session finished on save? " + finished);
3426d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        }
3436d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        if (finished) {
3446d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme            session.removeSelf();
3456d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        }
346226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
3475381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
348eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void cancelSessionLocked(int sessionId, int uid) {
34924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
3502f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3512f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3522f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
353eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
354eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
355eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            Slog.w(TAG, "cancelSessionLocked(): no session for " + sessionId + "(" + uid + ")");
3562f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3572f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3586d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        session.removeSelfLocked();
3592f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    }
3602f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
361f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    void disableOwnedAutofillServicesLocked(int uid) {
362f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid
363f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                != UserHandle.getAppId(uid)) {
364f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            return;
365f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
366f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        final long identity = Binder.clearCallingIdentity();
367f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        try {
368f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            final String autoFillService = getComponentNameFromSettings();
369f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            if (mInfo.getServiceInfo().getComponentName().equals(
370f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                    ComponentName.unflattenFromString(autoFillService))) {
371f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                Settings.Secure.putStringForUser(mContext.getContentResolver(),
372f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                        Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
373f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                destroySessionsLocked();
374f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            }
375f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        } finally {
376f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            Binder.restoreCallingIdentity(identity);
377f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
378f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    }
379f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov
380eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
3817b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmann            @Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
3827b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmann            int flags, @NonNull String packageName) {
383eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        // use random ids so that one app cannot know that another app creates sessions
384eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int sessionId;
385eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int tries = 0;
386eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        do {
387eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            tries++;
388eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            if (tries > MAX_SESSION_ID_CREATE_TRIES) {
389eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Log.w(TAG, "Cannot create session in " + MAX_SESSION_ID_CREATE_TRIES + " tries");
390eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                return null;
391eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            }
392eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
393eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            sessionId = sRandom.nextInt();
394eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
395eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
3966fa8a07143d1984ff42750079cf596a868644663Felipe Leme        final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
397eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback, flags,
3986fa8a07143d1984ff42750079cf596a868644663Felipe Leme                mInfo.getServiceInfo().getComponentName(), packageName);
399eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mSessions.put(newSession.id, newSession);
400bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
40129a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        /*
4021ca634a544a47193dd9e57f9b3eb3e42ab0dbbf1Felipe Leme         * TODO(b/33197203): apply security checks below:
40329a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme         * - checks if disabled by secure settings / device policy
40429a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme         * - log operation using noteOp()
40529a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme         * - check flags
40629a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme         * - display disclosure if needed
40729a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme         */
40829a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        try {
409bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            final Bundle receiverExtras = new Bundle();
410eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            receiverExtras.putInt(EXTRA_SESSION_ID, sessionId);
411782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            final long identity = Binder.clearCallingIdentity();
412782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            try {
413640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
414782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        receiverExtras, activityToken)) {
415640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                    Slog.w(TAG, "failed to request autofill data for " + activityToken);
416782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
417782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } finally {
418782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                Binder.restoreCallingIdentity(identity);
41929a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme            }
42029a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        } catch (RemoteException e) {
421bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme            // Should not happen, it's a local call.
422bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme        }
423226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long        return newSession;
424bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme    }
425bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
426eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    /**
427eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * Restores a session after an activity was temporarily destroyed.
428eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     *
429eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param sessionId The id of the session to restore
430eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param uid UID of the process that tries to restore the session
431eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param activityToken The new instance of the activity
432eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param appCallback The callbacks to the activity
433eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     */
434eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    boolean restoreSession(int sessionId, int uid, @NonNull IBinder activityToken,
435eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            @NonNull IBinder appCallback) {
436eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
437eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
438eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
439eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return false;
440eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } else {
441eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            session.switchActivity(activityToken, appCallback);
442eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return true;
443eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        }
444eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    }
445eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
446eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    /**
447eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * Set the window the UI should get attached to
448eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     *
449eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param sessionId The id of the session to restore
450eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param uid UID of the process that tries to restore the session
451eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param windowToken The window the activity is now in
452eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     */
453eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    boolean setWindow(int sessionId, int uid, @NonNull IBinder windowToken) {
454eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
455eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
456eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
457eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return false;
458eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } else {
459eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            session.switchWindow(windowToken);
460eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return true;
461eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        }
462eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    }
463eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
464eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
465640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme            AutofillValue value, int flags) {
466eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
467eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || session.uid != uid) {
4680ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            if (VERBOSE) {
469eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Slog.v(TAG, "updateSessionLocked(): session gone for " + sessionId + "(" + uid
470eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        + ")");
4710ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            }
472bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            return;
473bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
474bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
4754753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme        session.updateLocked(autofillId, virtualBounds, value, flags);
4760200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme    }
4770200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme
478eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void removeSessionLocked(int sessionId) {
479eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mSessions.remove(sessionId);
4806fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
4816fa8a07143d1984ff42750079cf596a868644663Felipe Leme
482eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private void handleSessionSave(int sessionId) {
483bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        synchronized (mLock) {
484eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final Session session = mSessions.get(sessionId);
485bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            if (session == null) {
486eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Slog.w(TAG, "handleSessionSave(): already gone: " + sessionId);
487bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
488bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                return;
489bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            }
490bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            session.callSaveLocked();
491bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
492436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
493436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
4940f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void destroyLocked() {
4950ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme        if (VERBOSE) {
4960ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            Slog.v(TAG, "destroyLocked()");
4970ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme        }
498bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
499eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
500eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
501eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            mSessions.valueAt(i).destroyLocked();
5025381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        }
503bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        mSessions.clear();
5040f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    }
5055381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
5066fa8a07143d1984ff42750079cf596a868644663Felipe Leme    CharSequence getServiceLabel() {
5076fa8a07143d1984ff42750079cf596a868644663Felipe Leme        return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
5086fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
5096fa8a07143d1984ff42750079cf596a868644663Felipe Leme
510cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
511cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Initializes the last fill selection after an autofill service returned a new
512cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * {@link FillResponse}.
513cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
514cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setLastResponse(int serviceUid, @NonNull FillResponse response) {
515cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
516cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            mEventHistory = new FillEventHistory(serviceUid, response.getClientState());
517cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
518cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
519cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
520cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
521cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an authentication was selected.
522cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
523cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setAuthenticationSelected() {
524cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
52549e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_AUTHENTICATION_SELECTED, null));
526cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
527cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
528cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
529cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
530cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an dataset authentication was selected.
531cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
532cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setDatasetAuthenticationSelected(@Nullable String selectedDataset) {
533cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
53449e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(
53549e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                    new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
536cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
537cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
538cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
539cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
540cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an save Ui is shown.
541cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
542cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setSaveShown() {
543cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
54449e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null));
545cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
546cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
547cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
548cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
549cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill response when a dataset was selected.
550cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
551cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setDatasetSelected(@Nullable String selectedDataset) {
552cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
55349e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_DATASET_SELECTED, selectedDataset));
554cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
555cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
556cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
557cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
558cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Gets the fill event history.
559cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
560cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @param callingUid The calling uid
561cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
562cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @return The history or {@code null} if there is none.
563cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
564cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    FillEventHistory getFillEventHistory(int callingUid) {
565cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
566cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            if (mEventHistory != null && mEventHistory.getServiceUid() == callingUid) {
567cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                return mEventHistory;
568cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
569cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
570cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
571cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        return null;
572cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
573cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
5740f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void dumpLocked(String prefix, PrintWriter pw) {
5756d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        final String prefix2 = prefix + "  ";
576bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
57798d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("User: "); pw.println(mUserId);
57898d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component: "); pw.println(mInfo != null
579782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null);
58098d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component from settings: ");
58198d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme            pw.println(getComponentNameFromSettings());
582ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme        pw.print(prefix); pw.print("Default component: ");
583ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme            pw.println(mContext.getString(R.string.config_defaultAutofillService));
58498d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
585bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
58624d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (VERBOSE && mInfo != null) {
5875381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme            // ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps)
588436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.println("ServiceInfo:");
5895381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme            mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), prefix + prefix);
5905381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        }
5915381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
592436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        final int size = mSessions.size();
5936d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        if (size == 0) {
594436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.println("No sessions");
5956d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        } else {
596436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.print(size); pw.println(" sessions:");
5976d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            for (int i = 0; i < size; i++) {
598bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                pw.print(prefix); pw.print("#"); pw.println(i + 1);
599bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                mSessions.valueAt(i).dumpLocked(prefix2, pw);
6006d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            }
6016d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
602cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
60349e96960d46022c85d1f6d00440242439f2028ecFelipe Leme        if (mEventHistory == null || mEventHistory.getEvents() == null
60449e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                || mEventHistory.getEvents().size() == 0) {
605cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("No event on last fill response");
606cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        } else {
607cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("Events of last fill response:");
608cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix);
609cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
610cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            int numEvents = mEventHistory.getEvents().size();
611cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            for (int i = 0; i < numEvents; i++) {
61249e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                final Event event = mEventHistory.getEvents().get(i);
613cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                pw.println("  " + i + ": eventType=" + event.getType() + " datasetId="
614cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                        + event.getDatasetId());
615cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
616cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
6175381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
6185381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
6197ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    void destroySessionsLocked() {
620eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        while (mSessions.size() > 0) {
621eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            mSessions.valueAt(0).removeSelf();
6227ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov        }
6237ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    }
6247ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov
62569a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    void listSessionsLocked(ArrayList<String> output) {
626eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
627eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
628782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            output.add((mInfo != null ? mInfo.getServiceInfo().getComponentName()
629eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                    : null) + ":" + mSessions.keyAt(i));
630782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
631782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
632782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
633782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private void sendStateToClients() {
634782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final RemoteCallbackList<IAutoFillManagerClient> clients;
635782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final int userClientCount;
636782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        synchronized (mLock) {
637782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (mClients == null) {
638782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
639782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
640782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients = mClients;
641782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            userClientCount = clients.beginBroadcast();
642782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
643782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
644782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            for (int i = 0; i < userClientCount; i++) {
64524d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                final IAutoFillManagerClient client = clients.getBroadcastItem(i);
646782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                try {
64724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                    client.setState(isEnabled());
648782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                } catch (RemoteException re) {
649782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    /* ignore */
650782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
651782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
652782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        } finally {
653782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients.finishBroadcast();
65469a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme        }
65569a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    }
65669a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme
65724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    private boolean isEnabled() {
65824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        return mInfo != null && !mDisabled;
659782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
660782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
6615381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    @Override
6625381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    public String toString() {
6632f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        return "AutofillManagerServiceImpl: [userId=" + mUserId
664782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                + ", component=" + (mInfo != null
665782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null) + "]";
6665381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
6675381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme}
668