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
197f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Lemeimport static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
200aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Lemeimport static android.view.autofill.AutofillManager.ACTION_START_SESSION;
21eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport static android.view.autofill.AutofillManager.NO_SESSION;
22bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
23f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmannimport static com.android.server.autofill.Helper.sDebug;
249f9ee25515591ef33281708c0ab911962f4364a6Felipe Lemeimport static com.android.server.autofill.Helper.sVerbose;
25dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme
267b7711680244108923f0dbb4ca6e35db7e659e6aPhilip P. Moltmannimport android.annotation.NonNull;
276d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.annotation.Nullable;
28f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmannimport android.app.ActivityManager;
29160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Lemeimport android.app.ActivityManagerInternal;
30782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.app.AppGlobals;
31f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmannimport android.app.IActivityManager;
325381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.ComponentName;
335381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.Context;
348eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Lemeimport android.content.pm.ApplicationInfo;
355381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.content.pm.PackageManager;
366eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Lemeimport android.content.pm.PackageManager.NameNotFoundException;
37782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.content.pm.ServiceInfo;
38bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.graphics.Rect;
39e11139c73d234efdd672a91830b09c92f6120d5eFelipe Lemeimport android.graphics.drawable.Drawable;
409d41449ff4efac108268815f67dd35797319e78cFelipe Lemeimport android.metrics.LogMaker;
41f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmannimport android.os.AsyncTask;
42782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.Binder;
436d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Lemeimport android.os.Bundle;
445381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.IBinder;
45bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport android.os.Looper;
46782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.os.RemoteCallbackList;
475381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.os.RemoteException;
486eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Lemeimport android.os.UserHandle;
4924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Lemeimport android.os.UserManager;
50782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.provider.Settings;
51640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillService;
52640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.service.autofill.AutofillServiceInfo;
53cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillEventHistory;
5449e96960d46022c85d1f6d00440242439f2028ecFelipe Lemeimport android.service.autofill.FillEventHistory.Event;
55cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmannimport android.service.autofill.FillResponse;
565381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.service.autofill.IAutoFillService;
57782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.text.TextUtils;
589b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Lemeimport android.util.ArraySet;
59c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Lemeimport android.util.DebugUtils;
60bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Lemeimport android.util.LocalLog;
615381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport android.util.Slog;
62eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport android.util.SparseArray;
63640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillId;
64c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Lemeimport android.view.autofill.AutofillManager;
65640f30a7763b0a4b80c767acb84c740aac04768bFelipe Lemeimport android.view.autofill.AutofillValue;
66782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganovimport android.view.autofill.IAutoFillManagerClient;
676fa8a07143d1984ff42750079cf596a868644663Felipe Leme
68ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Lemeimport com.android.internal.R;
695381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport com.android.internal.annotations.GuardedBy;
709d41449ff4efac108268815f67dd35797319e78cFelipe Lemeimport com.android.internal.logging.MetricsLogger;
719d41449ff4efac108268815f67dd35797319e78cFelipe Lemeimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
72bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Lemeimport com.android.internal.os.HandlerCaller;
73160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Lemeimport com.android.server.LocalServices;
7428a2c7e0579dbcbde09b6e23a17b0a501a3562b9Svet Ganovimport com.android.server.autofill.ui.AutoFillUI;
755381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
765381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Lemeimport java.io.PrintWriter;
7769a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Lemeimport java.util.ArrayList;
78eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmannimport java.util.Random;
795381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
805381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme/**
812f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov * Bridge between the {@code system_server}'s {@link AutofillManagerService} and the
825381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme * app's {@link IAutoFillService} implementation.
835381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme *
845381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme */
852f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganovfinal class AutofillManagerServiceImpl {
865381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
872f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    private static final String TAG = "AutofillManagerServiceImpl";
88eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
895381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
90f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    /** Minimum interval to prune abandoned sessions */
91f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    private static final int MAX_ABANDONED_SESSION_MILLIS = 30000;
92f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
936fa8a07143d1984ff42750079cf596a868644663Felipe Leme    static final int MSG_SERVICE_SAVE = 1;
946d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme
95dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme    private final int mUserId;
965381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Context mContext;
975381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    private final Object mLock;
980f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    private final AutoFillUI mUi;
999d41449ff4efac108268815f67dd35797319e78cFelipe Leme    private final MetricsLogger mMetricsLogger = new MetricsLogger();
1005381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
101782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private RemoteCallbackList<IAutoFillManagerClient> mClients;
102640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme    private AutofillServiceInfo mInfo;
103bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
104eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private static final Random sRandom = new Random();
105eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
106782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    private final LocalLog mRequestsHistory;
107021b878a23d4a42eca927161dab0acbc6b0ece12Felipe Leme    private final LocalLog mUiLatencyHistory;
108021b878a23d4a42eca927161dab0acbc6b0ece12Felipe Leme
10924d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    /**
11024d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     * Whether service was disabled for user due to {@link UserManager} restrictions.
11124d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme     */
11224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    private boolean mDisabled;
1135381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
114350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme    /**
115350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme     * Caches whether the setup completed for the current user.
116350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme     */
117350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme    @GuardedBy("mLock")
118350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme    private boolean mSetupComplete;
119350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme
120bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
121bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        switch (msg.what) {
122bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            case MSG_SERVICE_SAVE:
123eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                handleSessionSave(msg.arg1);
124bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                break;
125bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            default:
1260ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme                Slog.w(TAG, "invalid msg on handler: " + msg);
127bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
128bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    };
129bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
130bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme    private final HandlerCaller mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(),
131bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            mHandlerCallback, true);
132782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
1336d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    /**
134f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann     * Cache of pending {@link Session}s, keyed by sessionId.
1356d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     *
136640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme     * <p>They're kept until the {@link AutofillService} finished handling a request, an error
137f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann     * occurs, or the session is abandoned.
1386d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme     */
1396d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme    @GuardedBy("mLock")
140eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private final SparseArray<Session> mSessions = new SparseArray<>();
1415381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
142cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /** The last selection */
143cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    @GuardedBy("mLock")
144cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    private FillEventHistory mEventHistory;
145cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
146f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    /** When was {@link PruneTask} last executed? */
147f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    private long mLastPrune = 0;
148f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
1492f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
150021b878a23d4a42eca927161dab0acbc6b0ece12Felipe Leme            LocalLog uiLatencyHistory, int userId, AutoFillUI ui, boolean disabled) {
1515381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mContext = context;
1525381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        mLock = lock;
153bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme        mRequestsHistory = requestsHistory;
154021b878a23d4a42eca927161dab0acbc6b0ece12Felipe Leme        mUiLatencyHistory = uiLatencyHistory;
155dfa7fbc8702fae62e6b3f78c4d9245995baee04eFelipe Leme        mUserId = userId;
1560f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov        mUi = ui;
15724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        updateLocked(disabled);
1585381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
1595381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
160b22d635dadea68d91f7601e339f2e0d9f33a12c0Felipe Leme    @Nullable
1618eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    CharSequence getServiceName() {
162b22d635dadea68d91f7601e339f2e0d9f33a12c0Felipe Leme        final String packageName = getServicePackageName();
163db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme        if (packageName == null) {
1648eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return null;
1658eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
1668eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
1678eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        try {
1688eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final PackageManager pm = mContext.getPackageManager();
1698eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
1708eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return pm.getApplicationLabel(info);
1718eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        } catch (Exception e) {
1720ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            Slog.e(TAG, "Could not get label for " + packageName + ": " + e);
1738eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme            return packageName;
1748eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme        }
1758eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme    }
1768eab775d2cbc0d66f9b57451ec8a973f2464d014Felipe Leme
177b22d635dadea68d91f7601e339f2e0d9f33a12c0Felipe Leme    @Nullable
178b22d635dadea68d91f7601e339f2e0d9f33a12c0Felipe Leme    String getServicePackageName() {
17948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        final ComponentName serviceComponent = getServiceComponentName();
18048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        if (serviceComponent != null) {
18148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            return serviceComponent.getPackageName();
18248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        }
18348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        return null;
18448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    }
18548f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
18648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    ComponentName getServiceComponentName() {
18748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        synchronized (mLock) {
18848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            if (mInfo == null) {
18948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                return null;
19048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
19148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            return mInfo.getServiceInfo().getComponentName();
192db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme        }
193db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme    }
194db041188bc9ca03bed3c14a7ca1b3eb9524a9287Felipe Leme
195350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme    private boolean isSetupCompletedLocked() {
196350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        final String setupComplete = Settings.Secure.getStringForUser(
197350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme                mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
198350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        return "1".equals(setupComplete);
199350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme    }
200350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme
20198d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    private String getComponentNameFromSettings() {
20298d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        return Settings.Secure.getStringForUser(
20398d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme                mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
20498d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme    }
20598d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme
20624d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme    void updateLocked(boolean disabled) {
20724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        final boolean wasEnabled = isEnabled();
208350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        if (sVerbose) {
209350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme            Slog.v(TAG, "updateLocked(u=" + mUserId + "): wasEnabled=" + wasEnabled
210350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme                    + ", mSetupComplete= " + mSetupComplete
211350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme                    + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
212350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        }
213350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        mSetupComplete = isSetupCompletedLocked();
21424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        mDisabled = disabled;
215782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ComponentName serviceComponent = null;
216782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        ServiceInfo serviceInfo = null;
21798d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        final String componentName = getComponentNameFromSettings();
218782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (!TextUtils.isEmpty(componentName)) {
219782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            try {
220782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceComponent = ComponentName.unflattenFromString(componentName);
221782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
222782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        0, mUserId);
223782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } catch (RuntimeException | RemoteException e) {
224640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                Slog.e(TAG, "Bad autofill service name " + componentName + ": " + e);
225782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
226782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
227782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
228782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
229782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (serviceInfo != null) {
230640f30a7763b0a4b80c767acb84c740aac04768bFelipe Leme                mInfo = new AutofillServiceInfo(mContext.getPackageManager(),
231782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                        serviceComponent, mUserId);
2329d41449ff4efac108268815f67dd35797319e78cFelipe Leme                if (sDebug) Slog.d(TAG, "Set component for user " + mUserId + " as " + mInfo);
233782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            } else {
234782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                mInfo = null;
2359d41449ff4efac108268815f67dd35797319e78cFelipe Leme                if (sDebug) Slog.d(TAG, "Reset component for user " + mUserId);
236782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
237350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme            final boolean isEnabled = isEnabled();
238350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme            if (wasEnabled != isEnabled) {
239350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme                if (!isEnabled) {
240782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    final int sessionCount = mSessions.size();
241782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    for (int i = sessionCount - 1; i >= 0; i--) {
2426d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        final Session session = mSessions.valueAt(i);
2436d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme                        session.removeSelfLocked();
244782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    }
245782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
24648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                sendStateToClients(false);
247782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
248decd887f012f0c39bba855c8878eb5d8255595c4Felipe Leme        } catch (Exception e) {
249decd887f012f0c39bba855c8878eb5d8255595c4Felipe Leme            Slog.e(TAG, "Bad AutofillService '" + componentName + "': " + e);
250782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
251782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
2525381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
253782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    boolean addClientLocked(IAutoFillManagerClient client) {
254782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        if (mClients == null) {
255782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            mClients = new RemoteCallbackList<>();
256782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
257782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        mClients.register(client);
25824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        return isEnabled();
259782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
260782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
261a9379d0b44ca1f68a0036d2b65218e17fa348514Svetoslav Ganov    void setAuthenticationResultLocked(Bundle data, int sessionId, int authenticationId, int uid) {
26224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
263782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
264782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
265eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
266eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
267a9379d0b44ca1f68a0036d2b65218e17fa348514Svetoslav Ganov            session.setAuthenticationResultLocked(data, authenticationId);
268782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
269782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
270782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
271eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void setHasCallback(int sessionId, int uid, boolean hasIt) {
27224d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
273e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme            return;
274e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
275eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
276eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session != null && uid == session.uid) {
27748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            synchronized (mLock) {
27848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                session.setHasCallbackLocked(hasIt);
27948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
280e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme        }
281e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme    }
282e6010f2fb4d512c00a21cda55197f5f57e63fdc1Felipe Leme
283134cee27b8a54ff4c8bebda51c5fe4a4e6f1fd8aPhilip P. Moltmann    int startSessionLocked(@NonNull IBinder activityToken, int uid,
2844753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
2854753bb0c34e068f57fff208529836a7688b3ef41Felipe Leme            @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
2866eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            int flags, @NonNull ComponentName componentName) {
28724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
288eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return 0;
289782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
290c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        if (sVerbose) Slog.v(TAG, "startSession(): token=" + activityToken + ", flags=" + flags);
291782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
292f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        // Occasionally clean up abandoned sessions
293f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        pruneAbandonedSessionsLocked();
294f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
295134cee27b8a54ff4c8bebda51c5fe4a4e6f1fd8aPhilip P. Moltmann        final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
2966eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                hasCallback, componentName);
297eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (newSession == null) {
298eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return NO_SESSION;
299bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
300bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
301eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final String historyItem =
3020aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme                "id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
303eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        + " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
304eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                        hasCallback + " f=" + flags;
305eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mRequestsHistory.log(historyItem);
306eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
3070aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        newSession.updateLocked(autofillId, virtualBounds, value, ACTION_START_SESSION, flags);
308eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
3090aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        return newSession.id;
310226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
311bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
312f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    /**
313f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann     * Remove abandoned sessions if needed.
314f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann     */
315f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    private void pruneAbandonedSessionsLocked() {
316f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        long now = System.currentTimeMillis();
317f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        if (mLastPrune < now - MAX_ABANDONED_SESSION_MILLIS) {
318f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            mLastPrune = now;
319f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
320f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            if (mSessions.size() > 0) {
321f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                (new PruneTask()).execute();
322f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            }
323f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        }
324f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    }
325f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
326eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void finishSessionLocked(int sessionId, int uid) {
32724d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
328782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            return;
329782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
330bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
331eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
332eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
3339f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            if (sVerbose) {
3349f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme                Slog.v(TAG, "finishSessionLocked(): no session for " + sessionId + "(" + uid + ")");
3359f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            }
336bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            return;
33729a5b0d0f1cc7fd6cbfe97c816b8a687d9e438ccFelipe Leme        }
338bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
3396d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        final boolean finished = session.showSaveLocked();
3409f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme        if (sVerbose) Slog.v(TAG, "finishSessionLocked(): session finished on save? " + finished);
3419f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme
3426d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        if (finished) {
34348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            session.removeSelfLocked();
3446d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        }
345226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long    }
3465381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
347eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void cancelSessionLocked(int sessionId, int uid) {
34824d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme        if (!isEnabled()) {
3492f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3502f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3512f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
352eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
353eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
354eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            Slog.w(TAG, "cancelSessionLocked(): no session for " + sessionId + "(" + uid + ")");
3552f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov            return;
3562f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        }
3576d0cb1e8eb8ff2e0b4cc8d14823debbc37cb7c6eFelipe Leme        session.removeSelfLocked();
3582f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov    }
3592f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov
360f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    void disableOwnedAutofillServicesLocked(int uid) {
3619d41449ff4efac108268815f67dd35797319e78cFelipe Leme        Slog.i(TAG, "disableOwnedServices(" + uid + "): " + mInfo);
3629d41449ff4efac108268815f67dd35797319e78cFelipe Leme        if (mInfo == null) return;
3639d41449ff4efac108268815f67dd35797319e78cFelipe Leme
3649d41449ff4efac108268815f67dd35797319e78cFelipe Leme        final ServiceInfo serviceInfo = mInfo.getServiceInfo();
3659d41449ff4efac108268815f67dd35797319e78cFelipe Leme        if (serviceInfo.applicationInfo.uid != uid) {
3669d41449ff4efac108268815f67dd35797319e78cFelipe Leme            Slog.w(TAG, "disableOwnedServices(): ignored when called by UID " + uid
3679d41449ff4efac108268815f67dd35797319e78cFelipe Leme                    + " instead of " + serviceInfo.applicationInfo.uid
3689d41449ff4efac108268815f67dd35797319e78cFelipe Leme                    + " for service " + mInfo);
369f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            return;
370f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
3719d41449ff4efac108268815f67dd35797319e78cFelipe Leme
3729d41449ff4efac108268815f67dd35797319e78cFelipe Leme
373f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        final long identity = Binder.clearCallingIdentity();
374f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        try {
375f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            final String autoFillService = getComponentNameFromSettings();
3769d41449ff4efac108268815f67dd35797319e78cFelipe Leme            final ComponentName componentName = serviceInfo.getComponentName();
3779d41449ff4efac108268815f67dd35797319e78cFelipe Leme            if (componentName.equals(ComponentName.unflattenFromString(autoFillService))) {
3789d41449ff4efac108268815f67dd35797319e78cFelipe Leme                mMetricsLogger.action(MetricsEvent.AUTOFILL_SERVICE_DISABLED_SELF,
3799d41449ff4efac108268815f67dd35797319e78cFelipe Leme                        componentName.getPackageName());
380f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                Settings.Secure.putStringForUser(mContext.getContentResolver(),
381f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                        Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
382f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov                destroySessionsLocked();
3839d41449ff4efac108268815f67dd35797319e78cFelipe Leme            } else {
3849d41449ff4efac108268815f67dd35797319e78cFelipe Leme                Slog.w(TAG, "disableOwnedServices(): ignored because current service ("
3859d41449ff4efac108268815f67dd35797319e78cFelipe Leme                        + serviceInfo + ") does not match Settings (" + autoFillService + ")");
386f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            }
387f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        } finally {
388f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov            Binder.restoreCallingIdentity(identity);
389f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov        }
390f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov    }
391f20a037ba2a6990bb51ad40ee18c7af18464f620Svet Ganov
392eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
3936eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            @NonNull IBinder appCallbackToken, boolean hasCallback,
3946eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            @NonNull ComponentName componentName) {
395eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        // use random ids so that one app cannot know that another app creates sessions
396eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int sessionId;
397eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        int tries = 0;
398eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        do {
399eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            tries++;
400eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            if (tries > MAX_SESSION_ID_CREATE_TRIES) {
4019f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme                Slog.w(TAG, "Cannot create session in " + MAX_SESSION_ID_CREATE_TRIES + " tries");
402eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                return null;
403eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            }
404eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
405eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            sessionId = sRandom.nextInt();
406eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
407eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
4086eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        assertCallerLocked(componentName);
4096eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme
4106fa8a07143d1984ff42750079cf596a868644663Felipe Leme        final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
411134cee27b8a54ff4c8bebda51c5fe4a4e6f1fd8aPhilip P. Moltmann                sessionId, uid, activityToken, appCallbackToken, hasCallback,
4126eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), componentName);
4130aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        mSessions.put(newSession.id, newSession);
414bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
415226309c555b2c8df4a24c745b06fa7e89f3ed53fJason Long        return newSession;
416bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme    }
417bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme
418eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    /**
4196eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme     * Asserts the component is owned by the caller.
4206eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme     */
4216eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme    private void assertCallerLocked(@NonNull ComponentName componentName) {
422160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Leme        final String packageName = componentName.getPackageName();
4236eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        final PackageManager pm = mContext.getPackageManager();
4246eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        final int callingUid = Binder.getCallingUid();
4256eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        final int packageUid;
4266eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        try {
427160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Leme            packageUid = pm.getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
4286eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        } catch (NameNotFoundException e) {
4296eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            throw new SecurityException("Could not verify UID for " + componentName);
4306eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        }
431160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Leme        if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class)
432160b70fa41fdc67c423c235178fde7c481de4cb3Felipe Leme                .hasRunningActivity(callingUid, packageName)) {
4336eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            final String[] packages = pm.getPackagesForUid(callingUid);
4346eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
4356eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
4366eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                    + ") passed component (" + componentName + ") owned by UID " + packageUid);
4376eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT)
4386eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                    .setPackageName(callingPackage)
4396eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
4406eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
4416eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme                            componentName == null ? "null" : componentName.flattenToShortString()));
4426eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme            throw new SecurityException("Invalid component: " + componentName);
4436eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme        }
4446eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme    }
4456eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme
4466eb77633d9fc8996f44b36e11a722e3b729c7588Felipe Leme    /**
447eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * Restores a session after an activity was temporarily destroyed.
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 activityToken The new instance of the activity
452eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     * @param appCallback The callbacks to the activity
453eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann     */
454eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    boolean restoreSession(int sessionId, int uid, @NonNull IBinder activityToken,
455eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            @NonNull IBinder appCallback) {
456eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
457eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
458eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || uid != session.uid) {
459eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return false;
460eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        } else {
461eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            session.switchActivity(activityToken, appCallback);
462eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            return true;
463eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        }
464eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    }
465eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann
4667f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme    /**
4677f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme     * Updates a session and returns whether it should be restarted.
4687f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme     */
4697f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme    boolean updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
4700aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme            AutofillValue value, int action, int flags) {
471eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final Session session = mSessions.get(sessionId);
472eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        if (session == null || session.uid != uid) {
4737f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme            if ((flags & FLAG_MANUAL_REQUEST) != 0) {
4747f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                if (sDebug) {
4757f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                    Slog.d(TAG, "restarting session " + sessionId + " due to manual request on "
4767f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                            + autofillId);
4777f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                }
4787f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                return true;
4797f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme            }
4809f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme            if (sVerbose) {
4817f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                Slog.v(TAG, "updateSessionLocked(): session gone for " + sessionId
4827f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme                        + "(" + uid + ")");
4830ab53dcb31e7ae52cc265c8020df538df90ed2d7Felipe Leme            }
4847f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme            return false;
485bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
486bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
4870aa4c5065d1495ec0b2c6fe15324569f31dcbdb1Felipe Leme        session.updateLocked(autofillId, virtualBounds, value, action, flags);
4887f33cd350be4278ce5d4ef460c11e4dbaf9c473bFelipe Leme        return false;
4890200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme    }
4900200d9ea1509089c0c03b7071aa271e3a9b35c11Felipe Leme
491eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    void removeSessionLocked(int sessionId) {
492eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        mSessions.remove(sessionId);
4936fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
4946fa8a07143d1984ff42750079cf596a868644663Felipe Leme
495eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann    private void handleSessionSave(int sessionId) {
496bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        synchronized (mLock) {
497eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann            final Session session = mSessions.get(sessionId);
498bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            if (session == null) {
499eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                Slog.w(TAG, "handleSessionSave(): already gone: " + sessionId);
500bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
501bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme                return;
502bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            }
503bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme            session.callSaveLocked();
504bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        }
505436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme    }
506436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme
507c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme    void onPendingSaveUi(int operation, @NonNull IBinder token) {
508c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        if (sVerbose) Slog.v(TAG, "onPendingSaveUi(" + operation + "): " + token);
509c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        synchronized (mLock) {
510c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            final int sessionCount = mSessions.size();
511c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            for (int i = sessionCount - 1; i >= 0; i--) {
512c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                final Session session = mSessions.valueAt(i);
513650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme                if (session.isSaveUiPendingForTokenLocked(token)) {
514c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                    session.onPendingSaveUi(operation, token);
515c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                    return;
516c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                }
517c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            }
518c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        }
519c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        if (sDebug) {
520c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            Slog.d(TAG, "No pending Save UI for token " + token + " and operation "
521c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                    + DebugUtils.flagsToString(AutofillManager.class, "PENDING_UI_OPERATION_",
522c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme                            operation));
523c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        }
524c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme    }
525c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme
5260f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void destroyLocked() {
5279f9ee25515591ef33281708c0ab911962f4364a6Felipe Leme        if (sVerbose) Slog.v(TAG, "destroyLocked()");
528bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
529eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
5309b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme        final ArraySet<RemoteFillService> remoteFillServices = new ArraySet<>(numSessions);
531eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
5329b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme            final RemoteFillService remoteFillService = mSessions.valueAt(i).destroyLocked();
5339b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme            if (remoteFillService != null) {
5349b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme                remoteFillServices.add(remoteFillService);
5359b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme            }
5365381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme        }
537bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme        mSessions.clear();
5389b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme        for (int i = 0; i < remoteFillServices.size(); i++) {
5399b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme            remoteFillServices.valueAt(i).destroy();
5409b36dfb2b1377aeb774e1b8090b5b4f29a394df1Felipe Leme        }
54148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
54248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        sendStateToClients(true);
5430f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    }
5445381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
545e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme    @NonNull
5466fa8a07143d1984ff42750079cf596a868644663Felipe Leme    CharSequence getServiceLabel() {
5476fa8a07143d1984ff42750079cf596a868644663Felipe Leme        return mInfo.getServiceInfo().loadLabel(mContext.getPackageManager());
5486fa8a07143d1984ff42750079cf596a868644663Felipe Leme    }
5496fa8a07143d1984ff42750079cf596a868644663Felipe Leme
550e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme    @NonNull
551e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme    Drawable getServiceIcon() {
552e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme        return mInfo.getServiceInfo().loadIcon(mContext.getPackageManager());
553e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme    }
554e11139c73d234efdd672a91830b09c92f6120d5eFelipe Leme
555cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
556cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Initializes the last fill selection after an autofill service returned a new
557cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * {@link FillResponse}.
558cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
559d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme    void setLastResponse(int serviceUid, int sessionId, @NonNull FillResponse response) {
560cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
561d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            mEventHistory = new FillEventHistory(serviceUid, sessionId, response.getClientState());
562cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
563cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
564cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
565cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
5662e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme     * Resets the last fill selection.
5672e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme     */
5682e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme    void resetLastResponse() {
5692e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme        synchronized (mLock) {
5702e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme            mEventHistory = null;
5712e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme        }
5722e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme    }
5732e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme
574d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme    private boolean isValidEventLocked(String method, int sessionId) {
575d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme        if (mEventHistory == null) {
576d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            Slog.w(TAG, method + ": not logging event because history is null");
577d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            return false;
578d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme        }
579d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme        if (sessionId != mEventHistory.getSessionId()) {
580d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            if (sDebug) {
581d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                Slog.d(TAG, method + ": not logging event for session " + sessionId
582d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                        + " because tracked session is " + mEventHistory.getSessionId());
583d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            }
584d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            return false;
585d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme        }
586d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme        return true;
587d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme    }
588d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme
5892e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme    /**
590cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an authentication was selected.
591cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
592d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme    void setAuthenticationSelected(int sessionId) {
593cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
594d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            if (isValidEventLocked("setAuthenticationSelected()", sessionId)) {
595d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                mEventHistory.addEvent(new Event(Event.TYPE_AUTHENTICATION_SELECTED, null));
5962e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme            }
597cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
598cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
599cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
600cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
601cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an dataset authentication was selected.
602cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
60363f7906c1de0f4c88e2a3c6034666dc9cf35a3a7Felipe Leme    void logDatasetAuthenticationSelected(@Nullable String selectedDataset, int sessionId) {
604cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
60563f7906c1de0f4c88e2a3c6034666dc9cf35a3a7Felipe Leme            if (isValidEventLocked("logDatasetAuthenticationSelected()", sessionId)) {
606d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                mEventHistory.addEvent(
607d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                        new Event(Event.TYPE_DATASET_AUTHENTICATION_SELECTED, selectedDataset));
6082e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme            }
609cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
610cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
611cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
612cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
613cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill selection when an save Ui is shown.
614cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
61563f7906c1de0f4c88e2a3c6034666dc9cf35a3a7Felipe Leme    void logSaveShown(int sessionId) {
616cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
61763f7906c1de0f4c88e2a3c6034666dc9cf35a3a7Felipe Leme            if (isValidEventLocked("logSaveShown()", sessionId)) {
618d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                mEventHistory.addEvent(new Event(Event.TYPE_SAVE_SHOWN, null));
6192e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme            }
620cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
621cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
622cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
623cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
624cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Updates the last fill response when a dataset was selected.
625cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
62663f7906c1de0f4c88e2a3c6034666dc9cf35a3a7Felipe Leme    void logDatasetSelected(@Nullable String selectedDataset, int sessionId) {
627cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
628d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme            if (isValidEventLocked("setDatasetSelected()", sessionId)) {
629d013bcea9713d178627cc1d3e8a0f291ccbcd293Felipe Leme                mEventHistory.addEvent(new Event(Event.TYPE_DATASET_SELECTED, selectedDataset));
6302e30c6f371be6211f1fa2b2257084df24a535795Felipe Leme            }
631cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
632cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
633cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
634cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    /**
635cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * Gets the fill event history.
636cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
637cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @param callingUid The calling uid
638cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     *
639cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     * @return The history or {@code null} if there is none.
640cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann     */
641cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    FillEventHistory getFillEventHistory(int callingUid) {
642cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        synchronized (mLock) {
643cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            if (mEventHistory != null && mEventHistory.getServiceUid() == callingUid) {
644cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                return mEventHistory;
645cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
646cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
647cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
648cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        return null;
649cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann    }
650cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
6510f4928f1f73407485d6d94beda1dba1a2360ebbfSvet Ganov    void dumpLocked(String prefix, PrintWriter pw) {
6526d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        final String prefix2 = prefix + "  ";
653bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
65498d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("User: "); pw.println(mUserId);
65598d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component: "); pw.println(mInfo != null
656782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null);
65798d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Component from settings: ");
65898d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme            pw.println(getComponentNameFromSettings());
659ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme        pw.print(prefix); pw.print("Default component: ");
660ff35509ee9ef89f42607d1424fa6b4df8de98a90Felipe Leme            pw.println(mContext.getString(R.string.config_defaultAutofillService));
66198d5c7f6b02a9e4fabce52549f4aab995a67eaa4Felipe Leme        pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
662350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
663f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        pw.print(prefix); pw.print("Last prune: "); pw.println(mLastPrune);
664bab851c7c9dfe6f3d063a1009c4d57cfa2ff005cFelipe Leme
665436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme        final int size = mSessions.size();
6666d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        if (size == 0) {
667436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.println("No sessions");
6686d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        } else {
669436ab6a91d64ef6036c67bb361d807e398fb2c4cFelipe Leme            pw.print(prefix); pw.print(size); pw.println(" sessions:");
6706d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            for (int i = 0; i < size; i++) {
671bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                pw.print(prefix); pw.print("#"); pw.println(i + 1);
672bd00fef41ce38d2c711bd4151997c1cd8964b712Felipe Leme                mSessions.valueAt(i).dumpLocked(prefix2, pw);
6736d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme            }
6746d553874bed06280766ae24ea605f9bbde3f5a4aFelipe Leme        }
675cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
67649e96960d46022c85d1f6d00440242439f2028ecFelipe Leme        if (mEventHistory == null || mEventHistory.getEvents() == null
67749e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                || mEventHistory.getEvents().size() == 0) {
678cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("No event on last fill response");
679cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        } else {
680cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix); pw.println("Events of last fill response:");
681cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            pw.print(prefix);
682cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann
683cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            int numEvents = mEventHistory.getEvents().size();
684cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            for (int i = 0; i < numEvents; i++) {
68549e96960d46022c85d1f6d00440242439f2028ecFelipe Leme                final Event event = mEventHistory.getEvents().get(i);
686cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                pw.println("  " + i + ": eventType=" + event.getType() + " datasetId="
687cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann                        + event.getDatasetId());
688cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann            }
689cc684ed41f17ccdce45a056fd4034efc35b213d5Philip P. Moltmann        }
6905381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
6915381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme
6927ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    void destroySessionsLocked() {
693c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        if (mSessions.size() == 0) {
694f73795f92689d1ab0e341bd5b8af8c5a44f8a2c4Felipe Leme            mUi.destroyAll(null, null, false);
695c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            return;
696c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme        }
697eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        while (mSessions.size() > 0) {
698c24a56ae065bfc4b21f646d0c754b5f4db7c7be5Felipe Leme            mSessions.valueAt(0).forceRemoveSelfLocked();
6997ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov        }
7007ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov    }
7017ad11281378a1248c08c703b14cfc681e37cac1bSvet Ganov
702650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme    // TODO(b/64940307): remove this method if SaveUI is refactored to be attached on activities
703650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme    void destroyFinishedSessionsLocked() {
704650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme        final int sessionCount = mSessions.size();
705650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme        for (int i = sessionCount - 1; i >= 0; i--) {
706650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme            final Session session = mSessions.valueAt(i);
707650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme            if (session.isSavingLocked()) {
708650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme                if (sDebug) Slog.d(TAG, "destroyFinishedSessionsLocked(): " + session.id);
709650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme                session.forceRemoveSelfLocked();
710650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme            }
711650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme        }
712650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme    }
713650f7abc3fb3a7be419124f601a9941f5f7a7d2bFelipe Leme
71469a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    void listSessionsLocked(ArrayList<String> output) {
715eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        final int numSessions = mSessions.size();
716eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann        for (int i = 0; i < numSessions; i++) {
717782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            output.add((mInfo != null ? mInfo.getServiceInfo().getComponentName()
718eab62baabf290ea6671577a66cfc9fdd1b145d0ePhilip P. Moltmann                    : null) + ":" + mSessions.keyAt(i));
719782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
720782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
721782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
72248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    private void sendStateToClients(boolean resetClient) {
723782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final RemoteCallbackList<IAutoFillManagerClient> clients;
724782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        final int userClientCount;
725782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        synchronized (mLock) {
726782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            if (mClients == null) {
727782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                return;
728782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
729782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients = mClients;
730782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            userClientCount = clients.beginBroadcast();
731782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        }
732782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        try {
733782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            for (int i = 0; i < userClientCount; i++) {
73424d5893b25ce62b7bc9ed9f35fa72b9d47f23cddFelipe Leme                final IAutoFillManagerClient client = clients.getBroadcastItem(i);
735782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                try {
73648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    final boolean resetSession;
73748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    synchronized (mLock) {
73848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                        resetSession = resetClient || isClientSessionDestroyedLocked(client);
73948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    }
74048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                    client.setState(isEnabled(), resetSession, resetClient);
741782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                } catch (RemoteException re) {
742782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                    /* ignore */
743782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                }
744782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            }
745782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov        } finally {
746782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov            clients.finishBroadcast();
74769a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme        }
74869a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme    }
74969a1cae41110f080f2e91dafa2f99947f2886b7aFelipe Leme
75048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    private boolean isClientSessionDestroyedLocked(IAutoFillManagerClient client) {
75148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        final int sessionCount = mSessions.size();
75248f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        for (int i = 0; i < sessionCount; i++) {
75348f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            final Session session = mSessions.valueAt(i);
75448f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            if (session.getClient().equals(client)) {
75548f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov                return session.isDestroyed();
75648f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov            }
75748f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        }
75848f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov        return true;
75948f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    }
76048f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov
76148f10a2ab53e415f34d86ac717b4f6412dfc824fSvet Ganov    boolean isEnabled() {
762350b2dca6c252dad099bc8e2d96cbffd6e98dfefFelipe Leme        return mSetupComplete && mInfo != null && !mDisabled;
763782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov    }
764782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov
7655381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    @Override
7665381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    public String toString() {
7672f8fb1f62f2840701e3e16497eb8191f38b72e0bSvet Ganov        return "AutofillManagerServiceImpl: [userId=" + mUserId
768782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                + ", component=" + (mInfo != null
769782043caf81055aa1c331e9cc15b24a10e1bf17aSvet Ganov                ? mInfo.getServiceInfo().getComponentName() : null) + "]";
7705381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme    }
771f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
772f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    /** Task used to prune abandoned session */
773f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    private class PruneTask extends AsyncTask<Void, Void, Void> {
774f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        @Override
775f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        protected Void doInBackground(Void... ignored) {
776f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            int numSessionsToRemove;
777a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann
778a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann            SparseArray<IBinder> sessionsToRemove;
779f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
780f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            synchronized (mLock) {
781f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                numSessionsToRemove = mSessions.size();
782a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                sessionsToRemove = new SparseArray<>(numSessionsToRemove);
783f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
784f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                for (int i = 0; i < numSessionsToRemove; i++) {
785f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                    Session session = mSessions.valueAt(i);
786f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
787a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                    sessionsToRemove.put(session.id, session.getActivityTokenLocked());
788f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                }
789f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            }
790f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
791f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            IActivityManager am = ActivityManager.getService();
792f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
793f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            // Only remove sessions which's activities are not known to the activity manager anymore
794f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            for (int i = 0; i < numSessionsToRemove; i++) {
795f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                try {
796f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                    // The activity manager cannot resolve activities that have been removed
797a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                    if (am.getActivityClassForToken(sessionsToRemove.valueAt(i)) != null) {
798f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        sessionsToRemove.removeAt(i);
799f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        i--;
800f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        numSessionsToRemove--;
801f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                    }
802f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                } catch (RemoteException e) {
803f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                    Slog.w(TAG, "Cannot figure out if activity is finished", e);
804f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                }
805f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            }
806f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
807f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            synchronized (mLock) {
808f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                for (int i = 0; i < numSessionsToRemove; i++) {
809a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                    Session sessionToRemove = mSessions.get(sessionsToRemove.keyAt(i));
810f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
811a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                    if (sessionToRemove != null && sessionsToRemove.valueAt(i)
812a38666bcec2269afb414297ed403fca3a7b6e2b6Philip P. Moltmann                            == sessionToRemove.getActivityTokenLocked()) {
813f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        if (sessionToRemove.isSavingLocked()) {
814f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                            if (sVerbose) {
815f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                                Slog.v(TAG, "Session " + sessionToRemove.id + " is saving");
816f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                            }
817f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        } else {
818f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                            if (sDebug) {
819f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                                Slog.i(TAG, "Prune session " + sessionToRemove.id + " ("
820f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                                    + sessionToRemove.getActivityTokenLocked() + ")");
821f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                            }
822f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                            sessionToRemove.removeSelfLocked();
823f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                        }
824f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                    }
825f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann                }
826f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            }
827f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann
828f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann            return null;
829f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann        }
830f539389ee9ef6e67162965d0a3a8f5220e7cb86aPhilip P. Moltmann    }
8315381aa4b585f3fa2a315d88e910111173e2ef77dFelipe Leme}
832