summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PREUPLOAD.cfg2
-rw-r--r--core/java/android/app/ApplicationExitInfo.java2
-rw-r--r--core/java/android/content/IntentFilter.java7
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java2
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java3
-rw-r--r--core/java/android/net/MacAddress.java14
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java12
-rw-r--r--core/java/android/view/InsetsController.java26
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java3
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java30
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java16
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl3
-rw-r--r--core/res/res/values-es/strings.xml2
-rw-r--r--core/res/res/values-eu/strings.xml2
-rw-r--r--core/res/res/values-gl/strings.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-kk/strings.xml2
-rw-r--r--core/res/res/values-ky/strings.xml4
-rw-r--r--core/res/res/values-uz/strings.xml2
-rw-r--r--core/res/res/values-zh-rTW/strings.xml10
-rw-r--r--core/tests/coretests/src/android/view/InsetsControllerTest.java41
-rw-r--r--core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java26
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java15
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java9
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java37
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java14
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java16
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java18
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java48
-rw-r--r--services/core/java/com/android/server/wm/InsetsControlTarget.java4
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java20
37 files changed, 358 insertions, 119 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 2fd2e33bbc37..9b290c6a4760 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -12,8 +12,6 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
services/incremental/
[Hook Scripts]
-checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
-
strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index cfe0aff05d4a..e7b3e14bfda7 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -502,7 +502,7 @@ public final class ApplicationExitInfo implements Parcelable {
* Return the defining kernel user identifier, maybe different from {@link #getRealUid} and
* {@link #getPackageUid}, if an external service has the
* {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set
- * to <code>true<code> and was bound with the flag
+ * to <code>true</code> and was bound with the flag
* {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here will
* be the kernel user identifier of the external service provider.
*/
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 79da1f6ab282..ee9bd3d259fb 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1168,7 +1168,12 @@ public class IntentFilter implements Parcelable {
public int match(Uri data, boolean wildcardSupported) {
String host = data.getHost();
if (host == null) {
- return NO_MATCH_DATA;
+ if (wildcardSupported && mWild) {
+ // special case, if no host is provided, but the Authority is wildcard, match
+ return MATCH_CATEGORY_HOST;
+ } else {
+ return NO_MATCH_DATA;
+ }
}
if (false) Log.v("IntentFilter",
"Match host " + host + ": " + mHost);
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index bc9c71e7a68e..ab0ed51fb909 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -1510,7 +1510,7 @@ public class ParsingPackageUtils {
Uri data = null;
String dataType = null;
- String host = IntentFilter.WILDCARD;
+ String host = null;
final int numActions = intentInfo.countActions();
final int numSchemes = intentInfo.countDataSchemes();
final int numTypes = intentInfo.countDataTypes();
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 5647bf90d2fb..c5a11abe1136 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -605,9 +605,6 @@ public class InputMethodService extends AbstractInputMethodService {
if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
+ " ic=" + mInputConnection);
// Unbind input is per process per display.
- // TODO(b/150902448): free-up IME surface when target is changing.
- // e.g. DisplayContent#setInputMethodTarget()
- removeImeSurface();
onUnbindInput();
mInputBinding = null;
mInputConnection = null;
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 0e10c42e61db..0eb3c1e8ad01 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -38,7 +38,9 @@ import java.util.Arrays;
* Representation of a MAC address.
*
* This class only supports 48 bits long addresses and does not support 64 bits long addresses.
- * Instances of this class are immutable.
+ * Instances of this class are immutable. This class provides implementations of hashCode()
+ * and equals() that make it suitable for use as keys in standard implementations of
+ * {@link java.util.Map}.
*/
public final class MacAddress implements Parcelable {
@@ -122,12 +124,22 @@ public final class MacAddress implements Parcelable {
}
/**
+ * Convert this MacAddress to a byte array.
+ *
+ * The returned array is in network order. For example, if this MacAddress is 1:2:3:4:5:6,
+ * the returned array is [1, 2, 3, 4, 5, 6].
+ *
* @return a byte array representation of this MacAddress.
*/
public @NonNull byte[] toByteArray() {
return byteAddrFromLongAddr(mAddr);
}
+ /**
+ * Returns a human-readable representation of this MacAddress.
+ * The exact format is implementation-dependent and should not be assumed to have any
+ * particular format.
+ */
@Override
public @NonNull String toString() {
return stringAddrFromLongAddr(mAddr);
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index ef9d990168d2..c1998c6009cf 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -119,11 +119,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
// If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
// this code here means that we now got control, so we can start the animation immediately.
// If client window is trying to control IME and IME is already visible, it is immediate.
- if (fromIme || mState.getSource(getType()).isVisible()) {
+ if (fromIme || mState.getSource(getType()).isVisible() && getControl() != null) {
return ShowResult.SHOW_IMMEDIATELY;
}
- return getImm().requestImeShow(null /* resultReceiver */)
+ return getImm().requestImeShow(mController.getHost().getWindowToken())
? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED;
}
@@ -132,12 +132,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
*/
@Override
void notifyHidden() {
- getImm().notifyImeHidden();
+ getImm().notifyImeHidden(mController.getHost().getWindowToken());
}
@Override
public void removeSurface() {
- getImm().removeImeSurface();
+ final IBinder window = mController.getHost().getWindowToken();
+ if (window != null) {
+ getImm().removeImeSurface(window);
+ }
}
@Override
@@ -146,6 +149,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
super.setControl(control, showTypes, hideTypes);
if (control == null && !mIsRequestedVisibleAwaitingControl) {
hide();
+ removeSurface();
}
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c6be91fa1bf5..a679b3740fd9 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -737,7 +737,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
}
- final boolean hasControl = mTmpControlArray.size() > 0;
+ boolean requestedStateStale = false;
final int[] showTypes = new int[1];
final int[] hideTypes = new int[1];
@@ -754,9 +754,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
// Ensure to create source consumers if not available yet.
for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = mTmpControlArray.valueAt(i);
- InsetsSourceConsumer consumer = getSourceConsumer(control.getType());
+ final @InternalInsetsType int type = control.getType();
+ final InsetsSourceConsumer consumer = getSourceConsumer(type);
consumer.setControl(control, showTypes, hideTypes);
+ if (!requestedStateStale) {
+ final boolean requestedVisible = consumer.isRequestedVisible();
+
+ // We might have changed our requested visibilities while we don't have the control,
+ // so we need to update our requested state once we have control. Otherwise, our
+ // requested state at the server side might be incorrect.
+ final boolean requestedVisibilityChanged =
+ requestedVisible != mRequestedState.getSourceOrDefaultVisibility(type);
+
+ // The IME client visibility will be reset by insets source provider while updating
+ // control, so if IME is requested visible, we need to send the request to server.
+ final boolean imeRequestedVisible = type == ITYPE_IME && requestedVisible;
+
+ requestedStateStale = requestedVisibilityChanged || imeRequestedVisible;
+ }
+
}
mTmpControlArray.clear();
@@ -772,10 +789,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
if (hideTypes[0] != 0) {
applyAnimation(hideTypes[0], false /* show */, false /* fromIme */);
}
- if (hasControl && mRequestedState.hasSources()) {
- // We might have changed our requested visibilities while we don't have the control,
- // so we need to update our requested state once we have control. Otherwise, our
- // requested state at the server side might be incorrect.
+ if (requestedStateStale) {
updateRequestedState();
}
}
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 40e6f4b2fce8..700dc66fab55 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -153,6 +153,9 @@ public class InsetsSourceConsumer {
if (oldLeash == null || newLeash == null || !oldLeash.isSameSurface(newLeash)) {
applyHiddenToControl();
}
+ if (!requestedVisible && !mIsAnimationPending) {
+ removeSurface();
+ }
}
}
if (lastControl != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a58642517a20..2b7044d0c67e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2725,7 +2725,6 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mThreadedRenderer.isEnabled()) {
mAttachInfo.mThreadedRenderer.destroy();
}
- notifySurfaceDestroyed();
} else if ((surfaceReplaced
|| surfaceSizeChanged || windowRelayoutWasForced || colorModeChanged)
&& mSurfaceHolder == null
@@ -2956,6 +2955,10 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ if (surfaceDestroyed) {
+ notifySurfaceDestroyed();
+ }
+
if (triggerGlobalLayoutListener) {
mAttachInfo.mRecomputeGlobalAttributes = false;
mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
@@ -9377,6 +9380,11 @@ public final class ViewRootImpl implements ViewParent,
return mInputEventReceiver.getToken();
}
+ @NonNull
+ public IBinder getWindowToken() {
+ return mAttachInfo.mWindowToken;
+ }
+
/**
* Class for managing the accessibility interaction connection
* based on the global accessibility state.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index aedb59bfee42..3be0a4d39a56 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2109,28 +2109,36 @@ public final class InputMethodManager {
/**
* Call showSoftInput with currently focused view.
- * @return {@code true} if IME can be shown.
+ *
+ * @param windowToken the window from which this request originates. If this doesn't match the
+ * currently served view, the request is ignored and returns {@code false}.
+ *
+ * @return {@code true} if IME can (eventually) be shown, {@code false} otherwise.
* @hide
*/
- public boolean requestImeShow(ResultReceiver resultReceiver) {
+ public boolean requestImeShow(IBinder windowToken) {
synchronized (mH) {
final View servedView = getServedViewLocked();
- if (servedView == null) {
+ if (servedView == null || servedView.getWindowToken() != windowToken) {
return false;
}
- showSoftInput(servedView, 0 /* flags */, resultReceiver);
+ showSoftInput(servedView, 0 /* flags */, null /* resultReceiver */);
return true;
}
}
/**
* Notify IME directly that it is no longer visible.
+ *
+ * @param windowToken the window from which this request originates. If this doesn't match the
+ * currently served view, the request is ignored.
* @hide
*/
- public void notifyImeHidden() {
+ public void notifyImeHidden(IBinder windowToken) {
synchronized (mH) {
try {
- if (mCurMethod != null) {
+ if (mCurMethod != null && mCurRootView != null
+ && mCurRootView.getWindowToken() == windowToken) {
mCurMethod.notifyImeHidden();
}
} catch (RemoteException re) {
@@ -2140,15 +2148,15 @@ public final class InputMethodManager {
/**
* Notify IME directly to remove surface as it is no longer visible.
+ * @param windowToken The client window token that requests the IME to remove its surface.
* @hide
*/
- public void removeImeSurface() {
+ public void removeImeSurface(IBinder windowToken) {
synchronized (mH) {
try {
- if (mCurMethod != null) {
- mCurMethod.removeImeSurface();
- }
- } catch (RemoteException re) {
+ mService.removeImeSurfaceFromWindow(windowToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index c5729b05c587..046981cf2e8f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -21,8 +21,6 @@ import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COM
import static android.view.View.SYSTEM_UI_LAYOUT_FLAGS;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.view.WindowInsets.Type.ime;
-import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -34,8 +32,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -146,17 +142,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if ((view.getWindowSystemUiVisibility() & SYSTEM_UI_LAYOUT_FLAGS) != 0) {
return new Pair<>(Insets.NONE, insets);
}
-
- boolean includeIme = (view.getViewRootImpl().mWindowAttributes.softInputMode
- & SOFT_INPUT_MASK_ADJUST)
- == SOFT_INPUT_ADJUST_RESIZE;
- Insets insetsToApply;
- if (ViewRootImpl.sNewInsetsMode == 0) {
- insetsToApply = insets.getSystemWindowInsets();
- } else {
- insetsToApply = insets.getInsets(systemBars() | (includeIme ? ime() : 0));
- }
- insets = insets.inset(insetsToApply);
+ Insets insetsToApply = insets.getSystemWindowInsets();
return new Pair<>(insetsToApply,
insets.inset(insetsToApply).consumeSystemWindowInsets());
};
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 8ec51b89d240..a1cbd3fcae79 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -73,5 +73,8 @@ interface IInputMethodManager {
in float[] matrixValues);
oneway void reportPerceptible(in IBinder windowToken, boolean perceptible);
+ /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */
void removeImeSurface();
+ /** Remove the IME surface. Requires passing the currently focused window. */
+ void removeImeSurfaceFromWindow(in IBinder windowToken);
}
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4640e4b699d6..5e245de3376e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1149,7 +1149,7 @@
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Capturar imagen con %1$s"</string>
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Capturar imagen"</string>
<string name="alwaysUse" msgid="3153558199076112903">"Usar siempre para esta acción"</string>
- <string name="use_a_different_app" msgid="4987790276170972776">"Utiliza otra aplicación"</string>
+ <string name="use_a_different_app" msgid="4987790276170972776">"Usar otra aplicación"</string>
<string name="clearDefaultHintMsg" msgid="1325866337702524936">"Para borrar los valores predeterminados, accede a Ajustes del sistema &gt; Aplicaciones &gt; Descargadas."</string>
<string name="chooseActivity" msgid="8563390197659779956">"Selecciona una acción"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"Elegir una aplicación para el dispositivo USB"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index c26cc66dbab4..cf08d242e635 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1926,7 +1926,7 @@
<string name="time_picker_header_text" msgid="9073802285051516688">"Ezarri ordua"</string>
<string name="time_picker_input_error" msgid="8386271930742451034">"Idatzi balio duen ordu bat"</string>
<string name="time_picker_prompt_label" msgid="303588544656363889">"Idatzi ordua"</string>
- <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Aldatu testu modura ordua zehazteko."</string>
+ <string name="time_picker_text_input_mode_description" msgid="4761160667516611576">"Ordua idazteko, aldatu testua idazteko metodora."</string>
<string name="time_picker_radial_mode_description" msgid="1222342577115016953">"Aldatu erloju modura ordua zehazteko."</string>
<string name="autofill_picker_accessibility_title" msgid="4425806874792196599">"Betetze automatikoaren aukerak"</string>
<string name="autofill_save_accessibility_title" msgid="1523225776218450005">"Gorde betetze automatikoarekin erabiltzeko"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 77a1fec768d7..1732d0846961 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -854,7 +854,7 @@
<string name="emergency_calls_only" msgid="3057351206678279851">"Só chamadas de emerxencia"</string>
<string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Bloqueada pola rede"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"A tarxeta SIM está bloqueada con código PUK."</string>
- <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Consulta a guía do usuario ou ponte en contacto co servizo de asistencia ao cliente."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Consulta a guía para usuarios ou ponte en contacto co servizo de asistencia ao cliente."</string>
<string name="lockscreen_sim_locked_message" msgid="3160196135801185938">"A tarxeta SIM está bloqueada."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="2286497117428409709">"Desbloqueando tarxeta SIM…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Debuxaches incorrectamente o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. \n\nTéntao de novo en <xliff:g id="NUMBER_1">%2$d</xliff:g> segundos."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f5686c2ec12d..1604bea1e763 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1149,7 +1149,7 @@
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"「%1$s」を使用して画像をキャプチャ"</string>
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"画像をキャプチャ"</string>
<string name="alwaysUse" msgid="3153558199076112903">"常にこの操作で使用する"</string>
- <string name="use_a_different_app" msgid="4987790276170972776">"別のアプリの使用"</string>
+ <string name="use_a_different_app" msgid="4987790276170972776">"別のアプリを使用"</string>
<string name="clearDefaultHintMsg" msgid="1325866337702524936">"[システム設定]&gt;[アプリ]&gt;[ダウンロード済み]でデフォルト設定をクリアします。"</string>
<string name="chooseActivity" msgid="8563390197659779956">"操作の選択"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"USBデバイス用アプリを選択"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 28409e019a59..c55946e88ae9 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1547,7 +1547,7 @@
<string name="sending" msgid="206925243621664438">"Жіберілуде..."</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"Браузер қосылсын ба?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Қоңырауды қабылдау?"</string>
- <string name="activity_resolver_use_always" msgid="5575222334666843269">"Үнемі"</string>
+ <string name="activity_resolver_use_always" msgid="5575222334666843269">"Әрқашан"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"Бір рет қана"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s жұмыс профилін қолдамайды"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Планшет"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index a86636218292..5908475eec04 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -536,7 +536,7 @@
<string name="permdesc_imagesWrite" msgid="5195054463269193317">"Колдонмого сүрөт жыйнагыңызды өзгөртүүгө мүмкүнчүлүк берет."</string>
<string name="permlab_mediaLocation" msgid="7368098373378598066">"медиа жыйнагыңыз сакталган жерлерди окуу"</string>
<string name="permdesc_mediaLocation" msgid="597912899423578138">"Колдонмого медиа жыйнагыңыз сакталган жерлерди окууга мүмкүнчүлүк берет."</string>
- <string name="biometric_dialog_default_title" msgid="55026799173208210">"Сиз экениңизди ырастаңыз"</string>
+ <string name="biometric_dialog_default_title" msgid="55026799173208210">"Өзүңүздү ырастаңыз"</string>
<string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометрикалык аппарат жеткиликсиз"</string>
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Аныктыгын текшерүү жокко чыгарылды"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Таанылган жок"</string>
@@ -1547,7 +1547,7 @@
<string name="sending" msgid="206925243621664438">"Жөнөтүлүүдө…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"Серепчи иштетилсинби?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Чалуу кабыл алынсынбы?"</string>
- <string name="activity_resolver_use_always" msgid="5575222334666843269">"Дайыма"</string>
+ <string name="activity_resolver_use_always" msgid="5575222334666843269">"Ар дайым"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"Бир жолу гана"</string>
<string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s жумуш профилин колдоого албайт"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"Планшет"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 05337584d774..e07a81d5892a 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1090,7 +1090,7 @@
<string name="elapsed_time_short_format_mm_ss" msgid="8689459651807876423">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="2302144714803345056">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll" msgid="1532369154488982046">"Hammasini belgilash"</string>
- <string name="cut" msgid="2561199725874745819">"Kesish"</string>
+ <string name="cut" msgid="2561199725874745819">"Kesib olish"</string>
<string name="copy" msgid="5472512047143665218">"Nusxa olish"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Vaqtinchalik xotiraga nusxalab bo‘lmadi"</string>
<string name="paste" msgid="461843306215520225">"Joylash"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 69358d44d737..72dd4581e8fe 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1792,8 +1792,8 @@
<string name="package_updated_device_owner" msgid="7560272363805506941">"已由你的管理員更新"</string>
<string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
<string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string>
- <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"為了延長電池續航力,節約耗電量功能會執行以下動作:\n\n•開啟深色主題\n•關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
- <string name="battery_saver_description" msgid="8587408568232177204">"為了延長電池續航力,節約耗電量功能會執行以下動作:\n\n•開啟深色主題\n•關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞"</string>
+ <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"為了延長電池續航力,省電模式會執行以下動作:\n\n•開啟深色主題\n•關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞\n\n"<annotation id="url">"瞭解詳情"</annotation></string>
+ <string name="battery_saver_description" msgid="8587408568232177204">"為了延長電池續航力,省電模式會執行以下動作:\n\n•開啟深色主題\n•關閉或限制背景活動、部分視覺效果和其他功能,例如「Hey Google」啟動字詞"</string>
<string name="data_saver_description" msgid="4995164271550590517">"「數據節省模式」可防止部分應用程式在背景收發資料,以節省數據用量。你目前使用的應用程式可以存取資料,但存取頻率可能不如平時高。舉例來說,圖片可能不會自動顯示,在你輕觸後才會顯示。"</string>
<string name="data_saver_enable_title" msgid="7080620065745260137">"要開啟數據節省模式嗎?"</string>
<string name="data_saver_enable_button" msgid="4399405762586419726">"開啟"</string>
@@ -1999,9 +1999,9 @@
<string name="notification_appops_overlay_active" msgid="5571732753262836481">"顯示在畫面上的其他應用程式上層"</string>
<string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式資訊通知"</string>
<string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電池電力可能會在你平常的充電時間前耗盡"</string>
- <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用節約耗電量模式以延長電池續航力"</string>
- <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"節約耗電量"</string>
- <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"節約耗電量模式已關閉"</string>
+ <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用省電模式以延長電池續航力"</string>
+ <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"省電模式"</string>
+ <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"省電模式已關閉"</string>
<string name="battery_saver_charged_notification_summary" product="default" msgid="5544457317418624367">"手機電力充足,各項功能不再受到限制。"</string>
<string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"平板電腦電力充足,各項功能不再受到限制。"</string>
<string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"裝置電力充足,各項功能不再受到限制。"</string>
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 702f2fa65487..c36f1067149e 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -691,18 +691,57 @@ public class InsetsControllerTest {
@Test
public void testRequestedState() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+
+ // The modified state can be controlled when we have control.
mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
mController.hide(statusBars());
assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
- mController.onControlsChanged(new InsetsSourceControl[0]);
+
+ // The modified state won't be changed while losing control.
+ mController.onControlsChanged(null /* activeControls */);
assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+ // The modified state won't be changed while state changed while we don't have control.
InsetsState newState = new InsetsState(mController.getState(), true /* copySource */);
mController.onStateChanged(newState);
assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+ // The modified state won't be changed while controlling an insets without having the
+ // control.
mController.show(statusBars());
assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+ // The modified state can be updated while gaining control.
mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
assertTrue(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+ // The modified state can still be updated if the local state and the requested state
+ // are the same.
+ mController.onControlsChanged(null /* activeControls */);
+ mController.hide(statusBars());
+ newState = new InsetsState(mController.getState(), true /* copySource */);
+ newState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+ mController.onStateChanged(newState);
+ mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
+ assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+ // The modified state will always be updated while receiving IME control if IME is
+ // requested visible.
+ mController.getSourceConsumer(ITYPE_IME).show(false /* fromIme */);
+ newState = new InsetsState(mController.getState(), true /* copySource */);
+ newState.getSource(ITYPE_IME).setVisible(true);
+ newState.getSource(ITYPE_IME).setFrame(1, 2, 3, 4);
+ mController.onStateChanged(newState);
+ mController.onControlsChanged(createSingletonControl(ITYPE_IME));
+ assertEquals(newState.getSource(ITYPE_IME),
+ mTestHost.getModifiedState().peekSource(ITYPE_IME));
+ newState = new InsetsState(mController.getState(), true /* copySource */);
+ newState.getSource(ITYPE_IME).setVisible(true);
+ newState.getSource(ITYPE_IME).setFrame(5, 6, 7, 8);
+ mController.onStateChanged(newState);
+ mController.onControlsChanged(createSingletonControl(ITYPE_IME));
+ assertEquals(newState.getSource(ITYPE_IME),
+ mTestHost.getModifiedState().peekSource(ITYPE_IME));
});
}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 1b3272572db0..7efd616c5607 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -71,6 +71,9 @@ public class InsetsSourceConsumerTest {
private SurfaceControl mLeash;
@Mock Transaction mMockTransaction;
private InsetsSource mSpyInsetsSource;
+ private boolean mRemoveSurfaceCalled = false;
+ private InsetsController mController;
+ private InsetsState mState;
@Before
public void setup() {
@@ -89,13 +92,19 @@ public class InsetsSourceConsumerTest {
} catch (BadTokenException e) {
// activity isn't running, lets ignore BadTokenException.
}
- InsetsState state = new InsetsState();
+ mState = new InsetsState();
mSpyInsetsSource = Mockito.spy(new InsetsSource(ITYPE_STATUS_BAR));
- state.addSource(mSpyInsetsSource);
-
- mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, state,
- () -> mMockTransaction,
- new InsetsController(new ViewRootInsetsControllerHost(viewRootImpl)));
+ mState.addSource(mSpyInsetsSource);
+
+ mController = new InsetsController(new ViewRootInsetsControllerHost(viewRootImpl));
+ mConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, mState,
+ () -> mMockTransaction, mController) {
+ @Override
+ public void removeSurface() {
+ super.removeSurface();
+ mRemoveSurfaceCalled = true;
+ }
+ };
});
instrumentation.waitForIdleSync();
@@ -171,6 +180,25 @@ public class InsetsSourceConsumerTest {
mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()),
new int[1], hideTypes);
assertEquals(statusBars(), hideTypes[0]);
+ assertFalse(mRemoveSurfaceCalled);
+ });
+ }
+
+ @Test
+ public void testRestore_noAnimation() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mConsumer.hide();
+ mController.onStateChanged(mState);
+ mConsumer.setControl(null, new int[1], new int[1]);
+ reset(mMockTransaction);
+ verifyZeroInteractions(mMockTransaction);
+ mRemoveSurfaceCalled = false;
+ int[] hideTypes = new int[1];
+ mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()),
+ new int[1], hideTypes);
+ assertTrue(mRemoveSurfaceCalled);
+ assertEquals(0, hideTypes[0]);
});
+
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
index 8ba5b9951c54..c0089e53f8b6 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
@@ -226,6 +226,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
if (!activeControl.getSurfacePosition().equals(lastSurfacePosition)
&& mAnimation != null) {
startAnimation(mImeShowing, true /* forceRestart */);
+ } else if (!mImeShowing) {
+ removeImeSurface();
}
});
}
@@ -370,16 +372,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
dispatchEndPositioning(mDisplayId, mCancelled, t);
if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
t.hide(mImeSourceControl.getLeash());
- final IInputMethodManager imms = getImms();
- if (imms != null) {
- try {
- // Remove the IME surface to make the insets invisible for
- // non-client controlled insets.
- imms.removeImeSurface();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to remove IME surface.", e);
- }
- }
+ removeImeSurface();
}
t.apply();
mTransactionPool.release(t);
@@ -402,6 +395,19 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
}
}
+ void removeImeSurface() {
+ final IInputMethodManager imms = getImms();
+ if (imms != null) {
+ try {
+ // Remove the IME surface to make the insets invisible for
+ // non-client controlled insets.
+ imms.removeImeSurface();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to remove IME surface.", e);
+ }
+ }
+ }
+
/**
* Allows other things to synchronize with the ime position
*/
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 5124c4a4797e..a2eea1348d5c 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -470,22 +470,23 @@ public final class BroadcastQueue {
// if this receiver was slow, impose deferral policy on the app. This will kick in
// when processNextBroadcastLocked() next finds this uid as a receiver identity.
if (!r.timeoutExempt) {
- if (mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
+ // r.curApp can be null if finish has raced with process death - benign
+ // edge case, and we just ignore it because we're already cleaning up
+ // as expected.
+ if (r.curApp != null
+ && mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
// Core system packages are exempt from deferral policy
if (!UserHandle.isCore(r.curApp.uid)) {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
+ " was slow: " + receiver + " br=" + r);
}
- if (r.curApp != null) {
- mDispatcher.startDeferring(r.curApp.uid);
- } else {
- Slog.d(TAG_BROADCAST, "finish receiver curApp is null? " + r);
- }
+ mDispatcher.startDeferring(r.curApp.uid);
} else {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
- + " receiver was slow but not deferring: " + receiver + " br=" + r);
+ + " receiver was slow but not deferring: "
+ + receiver + " br=" + r);
}
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 70f0399d1070..05cf40a091b6 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -120,6 +120,11 @@ public abstract class InputMethodManagerInternal {
public abstract void reportImeControl(@Nullable IBinder windowToken);
/**
+ * Destroys the IME surface.
+ */
+ public abstract void removeImeSurface();
+
+ /**
* Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/
private static final InputMethodManagerInternal NOP =
@@ -166,6 +171,10 @@ public abstract class InputMethodManagerInternal {
@Override
public void reportImeControl(@Nullable IBinder windowToken) {
}
+
+ @Override
+ public void removeImeSurface() {
+ }
};
/**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index c027ebcfd568..d8ee32e7bd74 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -211,6 +211,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
static final int MSG_INITIALIZE_IME = 1040;
static final int MSG_CREATE_SESSION = 1050;
static final int MSG_REMOVE_IME_SURFACE = 1060;
+ static final int MSG_REMOVE_IME_SURFACE_FROM_WINDOW = 1061;
static final int MSG_START_INPUT = 2000;
@@ -4005,6 +4006,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE));
}
+ @Override
+ public void removeImeSurfaceFromWindow(IBinder windowToken) {
+ // No permission check, because we'll only execute the request if the calling window is
+ // also the current IME client.
+ mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE_FROM_WINDOW, windowToken).sendToTarget();
+ }
+
@BinderThread
private void notifyUserAction(@NonNull IBinder token) {
if (DEBUG) {
@@ -4278,11 +4286,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return true;
}
case MSG_REMOVE_IME_SURFACE: {
- try {
- if (mEnabledSession != null && mEnabledSession.session != null) {
- mEnabledSession.session.removeImeSurface();
+ synchronized (mMethodMap) {
+ try {
+ if (mEnabledSession != null && mEnabledSession.session != null
+ && !mShowRequested) {
+ mEnabledSession.session.removeImeSurface();
+ }
+ } catch (RemoteException e) {
+ }
+ }
+ return true;
+ }
+ case MSG_REMOVE_IME_SURFACE_FROM_WINDOW: {
+ IBinder windowToken = (IBinder) msg.obj;
+ synchronized (mMethodMap) {
+ try {
+ if (windowToken == mCurFocusedWindow
+ && mEnabledSession != null && mEnabledSession.session != null) {
+ mEnabledSession.session.removeImeSurface();
+ }
+ } catch (RemoteException e) {
}
- } catch (RemoteException e) {
}
return true;
}
@@ -5116,6 +5140,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
public void reportImeControl(@Nullable IBinder windowToken) {
mService.reportImeControl(windowToken);
}
+
+ @Override
+ public void removeImeSurface() {
+ mService.mHandler.sendMessage(mService.mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE));
+ }
}
@BinderThread
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 2e3d3963c9df..19dff9807075 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -225,6 +225,11 @@ public final class MultiClientInputMethodManagerService {
@Override
public void reportImeControl(@Nullable IBinder windowToken) {
}
+
+ @Override
+ public void removeImeSurface() {
+ reportNotSupported();
+ }
});
}
@@ -1473,6 +1478,12 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
+ public void removeImeSurfaceFromWindow(IBinder windowToken) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
public boolean showSoftInput(
IInputMethodClient client, IBinder token, int flags,
ResultReceiver resultReceiver) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 91b2ea1853fa..08cdd8f05292 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -589,12 +589,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
}
- if (mBypassNextStagedInstallerCheck) {
- mBypassNextStagedInstallerCheck = false;
- } else if (params.isStaged
- && !isCalledBySystemOrShell(callingUid)
- && !isWhitelistedStagedInstaller(requestedInstallerPackageName)) {
- throw new SecurityException("Installer not allowed to commit staged install");
+ if (params.isStaged && !isCalledBySystemOrShell(callingUid)) {
+ if (mBypassNextStagedInstallerCheck) {
+ mBypassNextStagedInstallerCheck = false;
+ } else if (!isStagedInstallerAllowed(requestedInstallerPackageName)) {
+ throw new SecurityException("Installer not allowed to commit staged install");
+ }
}
if (!params.isMultiPackage) {
@@ -725,7 +725,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|| callingUid == Process.SHELL_UID;
}
- private boolean isWhitelistedStagedInstaller(String installerName) {
+ private boolean isStagedInstallerAllowed(String installerName) {
return SystemConfig.getInstance().getWhitelistedStagedInstallers().contains(installerName);
}
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index c38d649ada9b..4b3ddd856c61 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -114,7 +114,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
private static final boolean DEBUG = false;
private static final String TAG = "UriGrantsManagerService";
// Maximum number of persisted Uri grants a package is allowed
- private static final int MAX_PERSISTED_URI_GRANTS = 128;
+ private static final int MAX_PERSISTED_URI_GRANTS = 512;
private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
private final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e8a4234f44a7..b94fb0471af4 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3574,12 +3574,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
- private void updateImeControlTarget() {
+ void updateImeControlTarget() {
mInputMethodControlTarget = computeImeControlTarget();
mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget);
- final WindowState win = mInputMethodControlTarget != null
- ? mInputMethodControlTarget.getWindow() : null;
+ final WindowState win = InsetsControlTarget.asWindowOrNull(mInputMethodControlTarget);
final IBinder token = win != null ? win.mClient.asBinder() : null;
// Note: not allowed to call into IMMS with the WM lock held, hence the post.
mWmService.mH.post(() ->
@@ -3603,6 +3602,17 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) {
return mRemoteInsetsControlTarget;
} else {
+ // Now, a special case -- if the last target's window is in the process of exiting, but
+ // not removed, keep on the last target to avoid IME flicker.
+ final WindowState cur = InsetsControlTarget.asWindowOrNull(mInputMethodControlTarget);
+ if (cur != null && !cur.mRemoved && cur.isDisplayedLw() && cur.isClosing()
+ && !cur.isActivityTypeHome()) {
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, "Not changing control while current window"
+ + " is closing and not removed");
+ }
+ return cur;
+ }
// Otherwise, we just use the ime target as received from IME.
return mInputMethodInputTarget;
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 8298763c1392..99ee5e121b7a 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -18,13 +18,14 @@ package com.android.server.wm;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME;
-import android.graphics.PixelFormat;
import android.view.InsetsSource;
import android.view.WindowInsets;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.protolog.common.ProtoLog;
+import java.io.PrintWriter;
+
/**
* Controller for IME inset source on the server. It's called provider as it provides the
* {@link InsetsSource} to the client that uses it in {@link InsetsSourceConsumer}.
@@ -132,8 +133,17 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
|| (mImeTargetFromIme != null && dcTarget.getParentWindow() == mImeTargetFromIme
&& dcTarget.mSubLayer > mImeTargetFromIme.mSubLayer)
|| mImeTargetFromIme == mDisplayContent.getImeFallback()
- // If IME target is transparent but control target matches requesting window.
- || (controlTarget == mImeTargetFromIme
- && PixelFormat.formatHasAlpha(dcTarget.mAttrs.format));
+ || (!mImeTargetFromIme.isClosing() && controlTarget == mImeTargetFromIme);
+ }
+
+ @Override
+ public void dump(PrintWriter pw, String prefix) {
+ super.dump(pw, prefix);
+ if (mImeTargetFromIme != null) {
+ pw.print(prefix);
+ pw.print("showImePostLayout pending for mImeTargetFromIme=");
+ pw.print(mImeTargetFromIme);
+ pw.println();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8734b5efa45d..0216db471843 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,13 +16,14 @@
package com.android.server.wm;
-import static android.os.Process.myPid;
-import static android.os.Process.myUid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
@@ -477,12 +478,18 @@ final class InputMonitor {
mService.getRecentsAnimationController();
final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null
&& recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord);
+ final int type = w.mAttrs.type;
+ final boolean isVisible = w.isVisibleLw();
if (inputChannel == null || inputWindowHandle == null || w.mRemoved
|| (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
if (w.mWinAnimator.hasSurface()) {
+ // Assign an InputInfo with type to the overlay window which can't receive input
+ // event. This is used to omit Surfaces from occlusion detection.
+ populateOverlayInputInfo(mInvalidInputWindow, w.getName(), type, isVisible);
mInputTransaction.setInputWindowInfo(
- w.mWinAnimator.mSurfaceController.getClientViewRootSurface(),
- mInvalidInputWindow);
+ w.mWinAnimator.mSurfaceController.getClientViewRootSurface(),
+ mInvalidInputWindow);
+ return;
}
// Skip this window because it cannot possibly receive input.
return;
@@ -490,9 +497,7 @@ final class InputMonitor {
final int flags = w.mAttrs.flags;
final int privateFlags = w.mAttrs.privateFlags;
- final int type = w.mAttrs.type;
final boolean hasFocus = w.isFocused();
- final boolean isVisible = w.isVisibleLw();
if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) {
if (recentsAnimationController.updateInputConsumerForApp(
@@ -555,6 +560,26 @@ final class InputMonitor {
}
}
+ // This would reset InputWindowHandle fields to prevent it could be found by input event.
+ // We need to check if any new field of InputWindowHandle could impact the result.
+ private static void populateOverlayInputInfo(final InputWindowHandle inputWindowHandle,
+ final String name, final int type, final boolean isVisible) {
+ inputWindowHandle.name = name;
+ inputWindowHandle.layoutParamsType = type;
+ inputWindowHandle.dispatchingTimeoutNanos =
+ WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ inputWindowHandle.visible = isVisible;
+ inputWindowHandle.canReceiveKeys = false;
+ inputWindowHandle.hasFocus = false;
+ inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL;
+ inputWindowHandle.scaleFactor = 1;
+ inputWindowHandle.layoutParamsFlags =
+ FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE;
+ inputWindowHandle.portalToDisplayId = INVALID_DISPLAY;
+ inputWindowHandle.touchableRegion.setEmpty();
+ inputWindowHandle.setTouchableRegionCrop(null);
+ }
+
/**
* Helper function to generate an InputInfo with type SECURE_SYSTEM_OVERLAY. This input
* info will not have an input channel or be touchable, but is used to omit Surfaces
@@ -564,16 +589,7 @@ final class InputMonitor {
static void setTrustedOverlayInputInfo(SurfaceControl sc, SurfaceControl.Transaction t,
int displayId, String name) {
InputWindowHandle inputWindowHandle = new InputWindowHandle(null, displayId);
- inputWindowHandle.name = name;
- inputWindowHandle.layoutParamsType = TYPE_SECURE_SYSTEM_OVERLAY;
- inputWindowHandle.dispatchingTimeoutNanos = -1;
- inputWindowHandle.visible = true;
- inputWindowHandle.canReceiveKeys = false;
- inputWindowHandle.hasFocus = false;
- inputWindowHandle.ownerPid = myPid();
- inputWindowHandle.ownerUid = myUid();
- inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL;
- inputWindowHandle.scaleFactor = 1;
+ populateOverlayInputInfo(inputWindowHandle, name, TYPE_SECURE_SYSTEM_OVERLAY, true);
t.setInputWindowInfo(sc, inputWindowHandle);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index c50f296504fc..3ffc26a7a8ad 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -62,4 +62,8 @@ interface InsetsControlTarget {
return false;
}
+ /** Returns {@code target.getWindow()}, or null if {@code target} is {@code null}. */
+ static WindowState asWindowOrNull(InsetsControlTarget target) {
+ return target != null ? target.getWindow() : null;
+ }
}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 63083faaddb1..77bd4a47a884 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -44,6 +44,7 @@ import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.WindowManager;
+import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
@@ -74,7 +75,21 @@ class InsetsStateController {
w.notifyInsetsChanged();
}
};
- private final InsetsControlTarget mEmptyImeControlTarget = new InsetsControlTarget() { };
+ private final InsetsControlTarget mEmptyImeControlTarget = new InsetsControlTarget() {
+ @Override
+ public void notifyInsetsControlChanged() {
+ InsetsSourceControl[] controls = getControlsForDispatch(this);
+ if (controls == null) {
+ return;
+ }
+ for (InsetsSourceControl control : controls) {
+ if (control.getType() == ITYPE_IME) {
+ mDisplayContent.mWmService.mH.post(() ->
+ InputMethodManagerInternal.get().removeImeSurface());
+ }
+ }
+ }
+ };
InsetsStateController(DisplayContent displayContent) {
mDisplayContent = displayContent;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 837fafec1634..00be75fddf04 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2170,6 +2170,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (isInputMethodTarget()) {
dc.computeImeTarget(true /* updateImeTarget */);
}
+ if (dc.mInputMethodControlTarget == this) {
+ dc.updateImeControlTarget();
+ }
final int type = mAttrs.type;
if (WindowManagerService.excludeWindowTypeFromTapOutTask(type)) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 77e3c597311c..d64fdb81107c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -898,6 +898,26 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testComputeImeControlTarget_exitingApp() throws Exception {
+ final DisplayContent dc = createNewDisplay();
+
+ WindowState exitingWin = createWindow(null, TYPE_BASE_APPLICATION, "exiting app");
+ makeWindowVisible(exitingWin);
+ exitingWin.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ exitingWin.mAnimatingExit = true;
+
+ dc.mInputMethodControlTarget = exitingWin;
+ dc.mInputMethodTarget = dc.mInputMethodInputTarget =
+ createWindow(null, TYPE_BASE_APPLICATION, "starting app");
+
+ assertEquals(exitingWin, dc.computeImeControlTarget());
+
+ exitingWin.removeImmediately();
+
+ assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
+ }
+
+ @Test
public void testComputeImeControlTarget_splitscreen() throws Exception {
final DisplayContent dc = createNewDisplay();
dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");