blob: 11f09d0f13433854d0e7f46416b847e7c746641c [file] [log] [blame]
Tarandeep Singh500a38f2019-09-26 13:36:40 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wm;
18
19import android.view.InsetsSource;
20import android.view.WindowInsets;
21
22/**
23 * Controller for IME inset source on the server. It's called provider as it provides the
24 * {@link InsetsSource} to the client that uses it in {@link InsetsSourceConsumer}.
25 */
26class ImeInsetsSourceProvider extends InsetsSourceProvider {
27
Taran Singhd7fc5862019-10-10 14:45:17 +020028 private WindowState mImeTargetFromIme;
Tarandeep Singh500a38f2019-09-26 13:36:40 -070029 private Runnable mShowImeRunner;
30 private boolean mIsImeLayoutDrawn;
31
32 ImeInsetsSourceProvider(InsetsSource source,
33 InsetsStateController stateController, DisplayContent displayContent) {
34 super(source, stateController, displayContent);
35 }
36
37 /**
38 * Called when a layout pass has occurred.
39 */
40 void onPostLayout() {
41 super.onPostLayout();
42
Taran Singhd7fc5862019-10-10 14:45:17 +020043 if (mImeTargetFromIme != null
44 && isImeTargetFromDisplayContentAndImeSame()
Tarandeep Singh500a38f2019-09-26 13:36:40 -070045 && mWin != null
46 && mWin.isDrawnLw()
47 && !mWin.mGivenInsetsPending) {
48 mIsImeLayoutDrawn = true;
49 }
50 }
51
52 /**
53 * Called when Insets have been dispatched to client.
54 */
55 void onPostInsetsDispatched() {
56 if (mIsImeLayoutDrawn && mShowImeRunner != null) {
57 // Show IME if InputMethodService requested to be shown and it's layout has finished.
58 mShowImeRunner.run();
Tarandeep Singh500a38f2019-09-26 13:36:40 -070059 }
60 }
61
62 /**
63 * Called from {@link WindowManagerInternal#showImePostLayout} when {@link InputMethodService}
64 * requests to show IME on {@param imeTarget}.
Taran Singhd7fc5862019-10-10 14:45:17 +020065 * @param imeTarget imeTarget on which IME request is coming from.
Tarandeep Singh500a38f2019-09-26 13:36:40 -070066 */
67 void scheduleShowImePostLayout(WindowState imeTarget) {
Taran Singhd7fc5862019-10-10 14:45:17 +020068 mImeTargetFromIme = imeTarget;
Tarandeep Singh500a38f2019-09-26 13:36:40 -070069 mShowImeRunner = () -> {
70 // Target should still be the same.
Taran Singhd7fc5862019-10-10 14:45:17 +020071 if (isImeTargetFromDisplayContentAndImeSame()) {
Tarandeep Singh500a38f2019-09-26 13:36:40 -070072 mDisplayContent.mInputMethodTarget.showInsets(
73 WindowInsets.Type.ime(), true /* fromIme */);
74 }
Tarandeep Singhbd24ee72019-10-21 13:17:13 -070075 abortShowImePostLayout();
Tarandeep Singh500a38f2019-09-26 13:36:40 -070076 };
77 }
78
Tarandeep Singhbd24ee72019-10-21 13:17:13 -070079 /**
80 * Abort any pending request to show IME post layout.
81 */
82 void abortShowImePostLayout() {
83 mImeTargetFromIme = null;
84 mIsImeLayoutDrawn = false;
85 mShowImeRunner = null;
86 }
87
Taran Singhd7fc5862019-10-10 14:45:17 +020088 private boolean isImeTargetFromDisplayContentAndImeSame() {
89 // IMMS#mLastImeTargetWindow always considers focused window as
90 // IME target, however DisplayContent#computeImeTarget() can compute
91 // a different IME target.
92 // Refer to WindowManagerService#applyImeVisibility(token, false).
93 // If IMMS's imeTarget is child of DisplayContent's imeTarget and child window
94 // is above the parent, we will consider it as the same target for now.
95 // TODO(b/139861270): Remove the child & sublayer check once IMMS is aware of
96 // actual IME target.
97 return mImeTargetFromIme == mDisplayContent.mInputMethodTarget
98 || (mDisplayContent.mInputMethodTarget.getParentWindow() == mImeTargetFromIme
99 && mDisplayContent.mInputMethodTarget.mSubLayer
100 > mImeTargetFromIme.mSubLayer);
101 }
102
Tarandeep Singh500a38f2019-09-26 13:36:40 -0700103}