AutofillManagerServiceImpl.java revision 9f9ee25515591ef33281708c0ab911962f4364a6
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
190aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Lemeimport static android.view.autofill.AutofillManager.ACTION_START_SESSION;
20eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport static android.view.autofill.AutofillManager.NO_SESSION;
21bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
229f9ee25515591ef33281708c0ab911962f4364a6Felipe Lemeimport static com.android.server.autofill.Helper.sVerbose;
23dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme
247b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmannimport android.annotation.NonNull;
256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.annotation.Nullable;
26782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.app.AppGlobals;
275381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.ComponentName;
285381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.Context;
298eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Lemeimport android.content.pm.ApplicationInfo;
305381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.pm.PackageManager;
31782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.content.pm.ServiceInfo;
32bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.graphics.Rect;
33782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.Binder;
346d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Bundle;
355381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.IBinder;
36bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport android.os.Looper;
37782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.RemoteCallbackList;
385381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.RemoteException;
39f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganovimport android.os.UserHandle;
4024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Lemeimport android.os.UserManager;
41782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.provider.Settings;
42640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillService;
43640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillServiceInfo;
44cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillEventHistory;
4549e96960d46022c85d1f6d00440242439f2028ecFelipe Lemeimport android.service.autofill.FillEventHistory.Event;
46cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillResponse;
475381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.service.autofill.IAutoFillService;
48782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.text.TextUtils;
49bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.util.LocalLog;
505381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.util.Slog;
51eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport android.util.SparseArray;
52640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillId;
53640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillValue;
54782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.IAutoFillManagerClient;
556fa8a07143d1984ff42750079cf596a868644663Felipe Leme
56ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Lemeimport com.android.internal.R;
575381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport com.android.internal.annotations.GuardedBy;
58bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport com.android.internal.os.HandlerCaller;
5928a2c7e0579dbcbde09b6e23a17b0a501a3562b9Svet Ganovimport com.android.server.autofill.ui.AutoFillUI;
605381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
615381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport java.io.PrintWriter;
6269a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Lemeimport java.util.ArrayList;
63eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport java.util.Random;
645381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
655381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme/**
662f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
675381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * app's {@link IAutoFillService} implementation.
685381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
695381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme */
702f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganovfinal class AutofillManagerServiceImpl {
715381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
722f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    private static final String TAG = "AutofillManagerServiceImpl";
73eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
745381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
756fa8a07143d1984ff42750079cf596a868644663Felipe Leme    static final int MSG_SERVICE_SAVE = 1;
766d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
77dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme    private final int mUserId;
785381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Context mContext;
795381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Object mLock;
800f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final AutoFillUI mUi;
815381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
82782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private RemoteCallbackList<IAutoFillManagerClient> mClients;
83640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme    private AutofillServiceInfo mInfo;
84bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
85eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final Random sRandom = new Random();
86eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
87782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private final LocalLog mRequestsHistory;
8824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    /**
8924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     * Whether service was disabled for user due to {@link UserManager} restrictions.
9024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     */
9124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    private boolean mDisabled;
925381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
93bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
94bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        switch (msg.what) {
95bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            case MSG_SERVICE_SAVE:
96eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                handleSessionSave(msg.arg1);
97bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                break;
98bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            default:
990ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme                Slog.w(TAG, "invalid msg on handler: " + msg);
100bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
101bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    };
102bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
103bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
104bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            mHandlerCallback, true);
105782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
1066d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
107bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme     * Cache of pending {@link Session}s, keyed by {@code activityToken}.
1086d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     *
109640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme     * <p>They're kept until the {@link AutofillService} finished handling a request, an error
110436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme     * occurs, or the session times out.
1116d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
1126d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @GuardedBy("mLock")
113eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private final SparseArray<Session> mSessions = new SparseArray<>();
1145381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
115cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /** The last selection */
116cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    @GuardedBy("mLock")
117cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    private FillEventHistory mEventHistory;
118cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
1192f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
12024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme            int userId, AutoFillUI ui, boolean disabled) {
1215381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mContext = context;
1225381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mLock = lock;
123bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme        mRequestsHistory = requestsHistory;
124dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme        mUserId = userId;
1250f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mUi = ui;
12624d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        updateLocked(disabled);
1275381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
1285381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
1298eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    CharSequence getServiceName() {
130db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme        final String packageName = getPackageName();
131db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme        if (packageName == null) {
1328eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return null;
1338eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
1348eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
1358eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        try {
1368eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final PackageManager pm = mContext.getPackageManager();
1378eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
1388eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return pm.getApplicationLabel(info);
1398eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        } catch (Exception e) {
1400ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            Slog.e(TAG, "Could not get label for " + packageName + ": " + e);
1418eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return packageName;
1428eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
1438eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    }
1448eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
145db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme    String getPackageName() {
14648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        final ComponentName serviceComponent = getServiceComponentName();
14748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        if (serviceComponent != null) {
14848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            return serviceComponent.getPackageName();
14948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        }
15048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        return null;
15148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    }
15248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
15348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    ComponentName getServiceComponentName() {
15448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        synchronized (mLock) {
15548f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            if (mInfo == null) {
15648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                return null;
15748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
15848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            return mInfo.getServiceInfo().getComponentName();
159db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme        }
160db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme    }
161db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme
16298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    private String getComponentNameFromSettings() {
16398d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        return Settings.Secure.getStringForUser(
16498d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme                mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
16598d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    }
16698d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme
16724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    void updateLocked(boolean disabled) {
16824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        final boolean wasEnabled = isEnabled();
16924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        mDisabled = disabled;
170782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ComponentName serviceComponent = null;
171782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ServiceInfo serviceInfo = null;
17298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        final String componentName = getComponentNameFromSettings();
173782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (!TextUtils.isEmpty(componentName)) {
174782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            try {
175782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceComponent = ComponentName.unflattenFromString(componentName);
176782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
177782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        0, mUserId);
178782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } catch (RuntimeException | RemoteException e) {
179640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
180782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
181782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
182782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
183782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
184782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (serviceInfo != null) {
185640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                mInfo = new AutofillServiceInfo(mContext.getPackageManager(),
186782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        serviceComponent, mUserId);
187782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } else {
188782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                mInfo = null;
189782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
19024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme            if (wasEnabled != isEnabled()) {
19124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                if (!isEnabled()) {
192782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    final int sessionCount = mSessions.size();
193782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    for (int i = sessionCount - 1; i >= 0; i--) {
1946d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        final Session session = mSessions.valueAt(i);
1956d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        session.removeSelfLocked();
196782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    }
197782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
19848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                sendStateToClients(false);
199782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
200decd887f012f0c39bba855c8878eb5d8255595c4Felipe Leme        } catch (Exception e) {
201decd887f012f0c39bba855c8878eb5d8255595c4Felipe Leme            Slog.e(TAG, "Bad AutofillService '" + componentName + "': " + e);
202782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
203782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
2045381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
2050f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    /**
2062f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov     * Used by {@link AutofillManagerServiceShellCommand} to request save for the current top app.
2070f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov     */
2080f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void requestSaveForUserLocked(IBinder activityToken) {
20924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
210782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
211782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
212eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
213eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
214eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
215eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final Session session = mSessions.valueAt(i);
216eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            if (session.getActivityTokenLocked().equals(activityToken)) {
217eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                session.callSaveLocked();
218eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                return;
219eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            }
220bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
221bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
222eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
2235381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
2245381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
225782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    boolean addClientLocked(IAutoFillManagerClient client) {
226782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (mClients == null) {
227782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            mClients = new RemoteCallbackList<>();
228782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
229782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        mClients.register(client);
23024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        return isEnabled();
231782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
232782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
233eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void setAuthenticationResultLocked(Bundle data, int sessionId, int uid) {
23424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
235782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
236782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
237eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
238eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
239782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            session.setAuthenticationResultLocked(data);
240782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
241782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
242782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
243eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void setHasCallback(int sessionId, int uid, boolean hasIt) {
24424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
245e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme            return;
246e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
247eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
248eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
24948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            synchronized (mLock) {
25048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                session.setHasCallbackLocked(hasIt);
25148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
252e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
253e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme    }
254e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme
255eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    int startSessionLocked(@NonNull IBinder activityToken, int uid, @Nullable IBinder windowToken,
2564753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
2574753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
2584753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            int flags, @NonNull String packageName) {
25924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
260eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return 0;
261782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
262782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
263eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session newSession = createSessionByTokenLocked(activityToken, uid, windowToken,
264eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                appCallbackToken, hasCallback, flags, packageName);
265eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (newSession == null) {
266eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return NO_SESSION;
267bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
268bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
269eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final String historyItem =
2700aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme                "id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
271eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
272eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        hasCallback + " f=" + flags;
273eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mRequestsHistory.log(historyItem);
274eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
2750aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        newSession.updateLocked(autofillId, virtualBounds, value, ACTION_START_SESSION, flags);
276eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
2770aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        return newSession.id;
278226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
279bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
280eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void finishSessionLocked(int sessionId, int uid) {
28124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
282782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
283782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
284bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
285eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
286eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
2879f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            if (sVerbose) {
2889f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme                Slog.v(TAG, "finishSessionLocked(): no session for " + sessionId + "(" + uid + ")");
2899f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            }
290bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            return;
29129a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        }
292bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
2936d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        final boolean finished = session.showSaveLocked();
2949f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme        if (sVerbose) Slog.v(TAG, "finishSessionLocked(): session finished on save? " + finished);
2959f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme
2966d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        if (finished) {
29748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            session.removeSelfLocked();
2986d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        }
299226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
3005381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
301eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void cancelSessionLocked(int sessionId, int uid) {
30224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
3032f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3042f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3052f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
306eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
307eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
308eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            Slog.w(TAG, "cancelSessionLocked(): no session for " + sessionId + "(" + uid + ")");
3092f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3102f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3116d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        session.removeSelfLocked();
3122f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    }
3132f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
314f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    void disableOwnedAutofillServicesLocked(int uid) {
315f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid
316f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                != UserHandle.getAppId(uid)) {
317f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            return;
318f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
319f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        final long identity = Binder.clearCallingIdentity();
320f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        try {
321f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            final String autoFillService = getComponentNameFromSettings();
322f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            if (mInfo.getServiceInfo().getComponentName().equals(
323f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                    ComponentName.unflattenFromString(autoFillService))) {
324f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                Settings.Secure.putStringForUser(mContext.getContentResolver(),
325f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                        Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
326f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                destroySessionsLocked();
327f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            }
328f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        } finally {
329f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            Binder.restoreCallingIdentity(identity);
330f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
331f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    }
332f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov
333eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
3347b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmann            @Nullable IBinder windowToken, @NonNull IBinder appCallbackToken, boolean hasCallback,
3357b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmann            int flags, @NonNull String packageName) {
336eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        // use random ids so that one app cannot know that another app creates sessions
337eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int sessionId;
338eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int tries = 0;
339eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        do {
340eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            tries++;
341eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            if (tries > MAX_SESSION_ID_CREATE_TRIES) {
3429f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme                Slog.w(TAG, "Cannot create session in " + MAX_SESSION_ID_CREATE_TRIES + " tries");
343eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                return null;
344eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            }
345eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
346eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            sessionId = sRandom.nextInt();
347eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
348eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
3496fa8a07143d1984ff42750079cf596a868644663Felipe Leme        final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
3500aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme                sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback,
3516fa8a07143d1984ff42750079cf596a868644663Felipe Leme                mInfo.getServiceInfo().getComponentName(), packageName);
3520aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        mSessions.put(newSession.id, newSession);
353bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
354226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long        return newSession;
355bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme    }
356bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
357eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    /**
358eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * Restores a session after an activity was temporarily destroyed.
359eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     *
360eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param sessionId The id of the session to restore
361eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param uid UID of the process that tries to restore the session
362eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param activityToken The new instance of the activity
363eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param appCallback The callbacks to the activity
364eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     */
365eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    boolean restoreSession(int sessionId, int uid, @NonNull IBinder activityToken,
366eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            @NonNull IBinder appCallback) {
367eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
368eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
369eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
370eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return false;
371eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } else {
372eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            session.switchActivity(activityToken, appCallback);
373eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return true;
374eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        }
375eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    }
376eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
377eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    /**
378eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * Set the window the UI should get attached to
379eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     *
380eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param sessionId The id of the session to restore
381eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param uid UID of the process that tries to restore the session
382eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param windowToken The window the activity is now in
383eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     */
384eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    boolean setWindow(int sessionId, int uid, @NonNull IBinder windowToken) {
385eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
386eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
387eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
388eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return false;
389eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } else {
390eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            session.switchWindow(windowToken);
391eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return true;
392eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        }
393eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    }
394eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
395eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
3960aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme            AutofillValue value, int action, int flags) {
397eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
398eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || session.uid != uid) {
3999f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            if (sVerbose) {
400eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Slog.v(TAG, "updateSessionLocked(): session gone for " + sessionId + "(" + uid
401eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        + ")");
4020ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            }
403bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            return;
404bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
405bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
4060aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        session.updateLocked(autofillId, virtualBounds, value, action, flags);
4070200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme    }
4080200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme
409eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void removeSessionLocked(int sessionId) {
410eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mSessions.remove(sessionId);
4116fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
4126fa8a07143d1984ff42750079cf596a868644663Felipe Leme
413eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private void handleSessionSave(int sessionId) {
414bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        synchronized (mLock) {
415eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final Session session = mSessions.get(sessionId);
416bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            if (session == null) {
417eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Slog.w(TAG, "handleSessionSave(): already gone: " + sessionId);
418bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
419bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                return;
420bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            }
421bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            session.callSaveLocked();
422bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
423436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
424436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
4250f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void destroyLocked() {
4269f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme        if (sVerbose) Slog.v(TAG, "destroyLocked()");
427bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
428eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
429eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
430eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            mSessions.valueAt(i).destroyLocked();
4315381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        }
432bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        mSessions.clear();
43348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
43448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        sendStateToClients(true);
4350f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    }
4365381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
4376fa8a07143d1984ff42750079cf596a868644663Felipe Leme    CharSequence getServiceLabel() {
4386fa8a07143d1984ff42750079cf596a868644663Felipe Leme        return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
4396fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
4406fa8a07143d1984ff42750079cf596a868644663Felipe Leme
441cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
442cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Initializes the last fill selection after an autofill service returned a new
443cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * {@link FillResponse}.
444cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
445cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setLastResponse(int serviceUid, @NonNull FillResponse response) {
446cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
447cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            mEventHistory = new FillEventHistory(serviceUid, response.getClientState());
448cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
449cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
450cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
451cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
452cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an authentication was selected.
453cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
454cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setAuthenticationSelected() {
455cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
45649e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_AUTHENTICATION_SELECTED, null));
457cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
458cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
459cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
460cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
461cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an dataset authentication was selected.
462cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
463cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setDatasetAuthenticationSelected(@Nullable String selectedDataset) {
464cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
46549e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(
46649e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                    new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
467cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
468cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
469cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
470cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
471cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an save Ui is shown.
472cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
473cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setSaveShown() {
474cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
47549e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null));
476cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
477cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
478cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
479cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
480cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill response when a dataset was selected.
481cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
482cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    void setDatasetSelected(@Nullable String selectedDataset) {
483cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
48449e96960d46022c85d1f6d00440242439f2028ecFelipe Leme            mEventHistory.addEvent(new Event(Event.TYPE_DATASET_SELECTED, selectedDataset));
485cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
486cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
487cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
488cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
489cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Gets the fill event history.
490cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
491cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @param callingUid The calling uid
492cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
493cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @return The history or {@code null} if there is none.
494cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
495cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    FillEventHistory getFillEventHistory(int callingUid) {
496cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
497cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            if (mEventHistory != null && mEventHistory.getServiceUid() == callingUid) {
498cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                return mEventHistory;
499cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
500cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
501cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
502cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        return null;
503cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
504cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
5050f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void dumpLocked(String prefix, PrintWriter pw) {
5066d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        final String prefix2 = prefix + "  ";
507bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
50898d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("User: "); pw.println(mUserId);
50998d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component: "); pw.println(mInfo != null
510782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null);
51198d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component from settings: ");
51298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme            pw.println(getComponentNameFromSettings());
513ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme        pw.print(prefix); pw.print("Default component: ");
514ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme            pw.println(mContext.getString(R.string.config_defaultAutofillService));
51598d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
516bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
517436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        final int size = mSessions.size();
5186d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        if (size == 0) {
519436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.println("No sessions");
5206d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        } else {
521436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.print(size); pw.println(" sessions:");
5226d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            for (int i = 0; i < size; i++) {
523bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                pw.print(prefix); pw.print("#"); pw.println(i + 1);
524bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                mSessions.valueAt(i).dumpLocked(prefix2, pw);
5256d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            }
5266d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
527cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
52849e96960d46022c85d1f6d00440242439f2028ecFelipe Leme        if (mEventHistory == null || mEventHistory.getEvents() == null
52949e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                || mEventHistory.getEvents().size() == 0) {
530cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("No event on last fill response");
531cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        } else {
532cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("Events of last fill response:");
533cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix);
534cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
535cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            int numEvents = mEventHistory.getEvents().size();
536cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            for (int i = 0; i < numEvents; i++) {
53749e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                final Event event = mEventHistory.getEvents().get(i);
538cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                pw.println("  " + i + ": eventType=" + event.getType() + " datasetId="
539cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                        + event.getDatasetId());
540cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
541cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
5425381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
5435381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
5447ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    void destroySessionsLocked() {
545eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        while (mSessions.size() > 0) {
54648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            mSessions.valueAt(0).removeSelfLocked();
5477ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov        }
5487ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    }
5497ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov
55069a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    void listSessionsLocked(ArrayList<String> output) {
551eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
552eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
553782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            output.add((mInfo != null ? mInfo.getServiceInfo().getComponentName()
554eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                    : null) + ":" + mSessions.keyAt(i));
555782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
556782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
557782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
55848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    private void sendStateToClients(boolean resetClient) {
559782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final RemoteCallbackList<IAutoFillManagerClient> clients;
560782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final int userClientCount;
561782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        synchronized (mLock) {
562782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (mClients == null) {
563782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
564782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
565782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients = mClients;
566782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            userClientCount = clients.beginBroadcast();
567782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
568782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
569782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            for (int i = 0; i < userClientCount; i++) {
57024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                final IAutoFillManagerClient client = clients.getBroadcastItem(i);
571782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                try {
57248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    final boolean resetSession;
57348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    synchronized (mLock) {
57448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                        resetSession = resetClient || isClientSessionDestroyedLocked(client);
57548f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    }
57648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    client.setState(isEnabled(), resetSession, resetClient);
577782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                } catch (RemoteException re) {
578782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    /* ignore */
579782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
580782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
581782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        } finally {
582782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients.finishBroadcast();
58369a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme        }
58469a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    }
58569a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme
58648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    private boolean isClientSessionDestroyedLocked(IAutoFillManagerClient client) {
58748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        final int sessionCount = mSessions.size();
58848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        for (int i = 0; i < sessionCount; i++) {
58948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            final Session session = mSessions.valueAt(i);
59048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            if (session.getClient().equals(client)) {
59148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                return session.isDestroyed();
59248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
59348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        }
59448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        return true;
59548f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    }
59648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
59748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    boolean isEnabled() {
59824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        return mInfo != null && !mDisabled;
599782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
600782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
6015381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    @Override
6025381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    public String toString() {
6032f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        return "AutofillManagerServiceImpl: [userId=" + mUserId
604782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                + ", component=" + (mInfo != null
605782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null) + "]";
6065381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
6075381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme}
608