Merge "Instrument latency and jank for IME"
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index d55367f..ed6a88f 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -223,11 +223,13 @@
final SomeArgs args = (SomeArgs) msg.obj;
final ImeTracker.Token statsToken = (ImeTracker.Token) args.arg3;
if (isValid(inputMethod, target, "DO_SHOW_SOFT_INPUT")) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
inputMethod.showSoftInputWithToken(
msg.arg1, (ResultReceiver) args.arg2, (IBinder) args.arg1, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
}
args.recycle();
return;
@@ -236,11 +238,13 @@
final SomeArgs args = (SomeArgs) msg.obj;
final ImeTracker.Token statsToken = (ImeTracker.Token) args.arg3;
if (isValid(inputMethod, target, "DO_HIDE_SOFT_INPUT")) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
inputMethod.hideSoftInputWithToken(msg.arg1, (ResultReceiver) args.arg2,
(IBinder) args.arg1, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_IME_WRAPPER_DISPATCH);
}
args.recycle();
return;
@@ -428,7 +432,7 @@
@Override
public void showSoftInput(IBinder showInputToken, @Nullable ImeTracker.Token statsToken,
int flags, ResultReceiver resultReceiver) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
mCaller.executeOrSendMessage(mCaller.obtainMessageIOOO(DO_SHOW_SOFT_INPUT,
flags, showInputToken, resultReceiver, statsToken));
}
@@ -437,7 +441,7 @@
@Override
public void hideSoftInput(IBinder hideInputToken, @Nullable ImeTracker.Token statsToken,
int flags, ResultReceiver resultReceiver) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_WRAPPER);
mCaller.executeOrSendMessage(mCaller.obtainMessageIOOO(DO_HIDE_SOFT_INPUT,
flags, hideInputToken, resultReceiver, statsToken));
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 872414a..ee9d8a4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -896,7 +896,8 @@
@MainThread
@Override
public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
- ImeTracker.get().onProgress(mCurStatsToken, ImeTracker.PHASE_IME_HIDE_SOFT_INPUT);
+ ImeTracker.forLogging().onProgress(
+ mCurStatsToken, ImeTracker.PHASE_IME_HIDE_SOFT_INPUT);
if (DEBUG) Log.v(TAG, "hideSoftInput()");
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R
&& !mSystemCallingHideSoftInput) {
@@ -950,7 +951,8 @@
@MainThread
@Override
public void showSoftInput(int flags, ResultReceiver resultReceiver) {
- ImeTracker.get().onProgress(mCurStatsToken, ImeTracker.PHASE_IME_SHOW_SOFT_INPUT);
+ ImeTracker.forLogging().onProgress(
+ mCurStatsToken, ImeTracker.PHASE_IME_SHOW_SOFT_INPUT);
if (DEBUG) Log.v(TAG, "showSoftInput()");
// TODO(b/148086656): Disallow IME developers from calling InputMethodImpl methods.
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R
@@ -966,11 +968,11 @@
null /* icProto */);
final boolean wasVisible = isInputViewShown();
if (dispatchOnShowInputRequested(flags, false)) {
- ImeTracker.get().onProgress(mCurStatsToken,
+ ImeTracker.forLogging().onProgress(mCurStatsToken,
ImeTracker.PHASE_IME_ON_SHOW_SOFT_INPUT_TRUE);
showWindow(true);
} else {
- ImeTracker.get().onFailed(mCurStatsToken,
+ ImeTracker.forLogging().onFailed(mCurStatsToken,
ImeTracker.PHASE_IME_ON_SHOW_SOFT_INPUT_TRUE);
}
setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
@@ -2979,7 +2981,7 @@
ImeTracing.getInstance().triggerServiceDump(
"InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", mDumper,
null /* icProto */);
- ImeTracker.get().onProgress(mCurStatsToken,
+ ImeTracker.forLogging().onProgress(mCurStatsToken,
ImeTracker.PHASE_IME_APPLY_VISIBILITY_INSETS_CONSUMER);
mPrivOps.applyImeVisibilityAsync(setVisible
? mCurShowInputToken : mCurHideInputToken, setVisible, mCurStatsToken);
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 289a5b6..4a3b8ac 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -123,7 +123,7 @@
// TODO: ResultReceiver for IME.
// TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag.
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_REQUEST_SHOW);
if (getControl() == null) {
@@ -165,12 +165,13 @@
// - we do already have one, but we have control and use the passed in token
// for the insets animation already.
if (statsToken == null || getControl() != null) {
- statsToken = ImeTracker.get().onRequestHide(null /* component */, Process.myUid(),
+ statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
+ Process.myUid(),
ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
}
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);
getImm().notifyImeHidden(mController.getHost().getWindowToken(), statsToken);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 1c00e5f..d8bff1c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -26,6 +26,7 @@
import static android.view.WindowInsets.Type.all;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.ime;
+import static android.view.inputmethod.ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL;
import android.animation.AnimationHandler;
import android.animation.Animator;
@@ -35,6 +36,8 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.graphics.Insets;
import android.graphics.Rect;
@@ -59,6 +62,7 @@
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
import android.view.inputmethod.ImeTracker;
+import android.view.inputmethod.ImeTracker.InputMethodJankContext;
import android.view.inputmethod.InputMethodManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -185,6 +189,14 @@
@Nullable
String getRootViewTitle();
+ /**
+ * @return the context related to the rootView.
+ */
+ @Nullable
+ default Context getRootViewContext() {
+ return null;
+ }
+
/** @see ViewRootImpl#dipToPx */
int dipToPx(int dips);
@@ -308,7 +320,7 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {ANIMATION_TYPE_NONE, ANIMATION_TYPE_SHOW, ANIMATION_TYPE_HIDE,
ANIMATION_TYPE_USER, ANIMATION_TYPE_RESIZE})
- @interface AnimationType {
+ public @interface AnimationType {
}
/**
@@ -323,6 +335,25 @@
/** Logging listener. */
private WindowInsetsAnimationControlListener mLoggingListener;
+ /** Context for {@link android.view.inputmethod.ImeTracker.ImeJankTracker} to monitor jank. */
+ private final InputMethodJankContext mJankContext = new InputMethodJankContext() {
+ @Override
+ public Context getDisplayContext() {
+ return mHost != null ? mHost.getRootViewContext() : null;
+ }
+
+ @Override
+ public SurfaceControl getTargetSurfaceControl() {
+ final InsetsSourceControl imeSourceControl = getImeSourceConsumer().getControl();
+ return imeSourceControl != null ? imeSourceControl.getLeash() : null;
+ }
+
+ @Override
+ public String getHostPackageName() {
+ return mHost != null ? mHost.getRootViewContext().getPackageName() : null;
+ }
+ };
+
/**
* The default implementation of listener, to be used by InsetsController and InsetsPolicy to
* animate insets.
@@ -340,6 +371,7 @@
private final boolean mDisable;
private final int mFloatingImeBottomInset;
private final WindowInsetsAnimationControlListener mLoggingListener;
+ private final InputMethodJankContext mInputMethodJankContext;
private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
new ThreadLocal<AnimationHandler>() {
@@ -353,7 +385,8 @@
public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
@InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
- int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener) {
+ int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener,
+ @Nullable InputMethodJankContext jankContext) {
mShow = show;
mHasAnimationCallbacks = hasAnimationCallbacks;
mRequestedTypes = requestedTypes;
@@ -362,6 +395,7 @@
mDisable = disable;
mFloatingImeBottomInset = floatingImeBottomInset;
mLoggingListener = loggingListener;
+ mInputMethodJankContext = jankContext;
}
@Override
@@ -408,10 +442,26 @@
+ insetsFraction);
});
mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (mInputMethodJankContext == null) return;
+ ImeTracker.forJank().onRequestAnimation(
+ mInputMethodJankContext,
+ mShow ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
+ !mHasAnimationCallbacks);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (mInputMethodJankContext == null) return;
+ ImeTracker.forJank().onCancelAnimation();
+ }
@Override
public void onAnimationEnd(Animator animation) {
onAnimationFinish();
+ if (mInputMethodJankContext == null) return;
+ ImeTracker.forJank().onFinishAnimation();
}
});
if (!mHasAnimationCallbacks) {
@@ -897,7 +947,7 @@
/**
* @see InsetsState#calculateInsets(Rect, InsetsState, boolean, boolean, int, int, int, int,
- * int, SparseIntArray)
+ * int, android.util.SparseIntArray)
*/
@VisibleForTesting
public WindowInsets calculateInsets(boolean isScreenRound, boolean alwaysConsumeSystemBars,
@@ -1005,7 +1055,7 @@
public void show(@InsetsType int types) {
ImeTracker.Token statsToken = null;
if ((types & ime()) != 0) {
- statsToken = ImeTracker.get().onRequestShow(null /* component */,
+ statsToken = ImeTracker.forLogging().onRequestShow(null /* component */,
Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API);
}
@@ -1030,6 +1080,9 @@
}
// Handle pending request ready in case there was one set.
if (fromIme && mPendingImeControlRequest != null) {
+ if ((types & Type.ime()) != 0) {
+ ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
+ }
handlePendingControlRequest(statsToken);
return;
}
@@ -1052,7 +1105,7 @@
"show ignored for type: %d animType: %d requestedVisible: %s",
type, animationType, requestedVisible));
if (isImeAnimation) {
- ImeTracker.get().onCancelled(statsToken,
+ ImeTracker.forLogging().onCancelled(statsToken,
ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
}
continue;
@@ -1060,16 +1113,21 @@
if (fromIme && animationType == ANIMATION_TYPE_USER) {
// App is already controlling the IME, don't cancel it.
if (isImeAnimation) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
}
continue;
}
if (isImeAnimation) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
}
typesReady |= type;
}
if (DEBUG) Log.d(TAG, "show typesReady: " + typesReady);
+ if (fromIme && (typesReady & Type.ime()) != 0) {
+ ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication);
+ }
applyAnimation(typesReady, true /* show */, fromIme, statsToken);
}
@@ -1098,7 +1156,7 @@
public void hide(@InsetsType int types) {
ImeTracker.Token statsToken = null;
if ((types & ime()) != 0) {
- statsToken = ImeTracker.get().onRequestHide(null /* component */,
+ statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
}
@@ -1147,13 +1205,14 @@
// no-op: already hidden or animating out (because window visibility is
// applied before starting animation).
if (isImeAnimation) {
- ImeTracker.get().onCancelled(statsToken,
+ ImeTracker.forLogging().onCancelled(statsToken,
ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
}
continue;
}
if (isImeAnimation) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_CLIENT_APPLY_ANIMATION);
}
typesReady |= type;
}
@@ -1225,8 +1284,19 @@
@AnimationType int animationType,
@LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION);
if ((types & mTypesBeingCancelled) != 0) {
+ final boolean monitoredAnimation =
+ animationType == ANIMATION_TYPE_SHOW || animationType == ANIMATION_TYPE_HIDE;
+ if (monitoredAnimation && (types & Type.ime()) != 0) {
+ if (animationType == ANIMATION_TYPE_SHOW) {
+ ImeTracker.forLatency().onShowCancelled(statsToken,
+ PHASE_CLIENT_ANIMATION_CANCEL, ActivityThread::currentApplication);
+ } else {
+ ImeTracker.forLatency().onHideCancelled(statsToken,
+ PHASE_CLIENT_ANIMATION_CANCEL, ActivityThread::currentApplication);
+ }
+ }
throw new IllegalStateException("Cannot start a new insets animation of "
+ Type.toString(types)
+ " while an existing " + Type.toString(mTypesBeingCancelled)
@@ -1238,7 +1308,7 @@
types &= ~mDisabledUserAnimationInsetsTypes;
if ((disabledTypes & ime()) != 0) {
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
if (fromIme
@@ -1260,7 +1330,8 @@
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);
if (DEBUG) Log.d(TAG, "controlAnimation types: " + types);
mLastStartedAnimTypes |= types;
@@ -1327,8 +1398,11 @@
if ((typesReady & WindowInsets.Type.ime()) != 0) {
ImeTracing.getInstance().triggerClientDump("InsetsAnimationControlImpl",
mHost.getInputMethodManager(), null /* icProto */);
+ if (animationType == ANIMATION_TYPE_HIDE) {
+ ImeTracker.forLatency().onHidden(statsToken, ActivityThread::currentApplication);
+ }
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
mRunningAnimations.add(new RunningAnimation(runner, animationType));
if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
+ useInsetsAnimationThread);
@@ -1368,7 +1442,8 @@
private Pair<Integer, Boolean> collectSourceControls(boolean fromIme, @InsetsType int types,
SparseArray<InsetsSourceControl> controls, @AnimationType int animationType,
@Nullable ImeTracker.Token statsToken) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_COLLECT_SOURCE_CONTROLS);
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_COLLECT_SOURCE_CONTROLS);
int typesReady = 0;
boolean imeReady = true;
@@ -1471,13 +1546,13 @@
}
final ImeTracker.Token statsToken = runner.getStatsToken();
if (shown) {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_SHOW);
- ImeTracker.get().onShown(statsToken);
+ ImeTracker.forLogging().onShown(statsToken);
} else {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_HIDE);
- ImeTracker.get().onHidden(statsToken);
+ ImeTracker.forLogging().onHidden(statsToken);
}
reportRequestedVisibleTypes();
}
@@ -1503,13 +1578,13 @@
private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) {
if (invokeCallback) {
- ImeTracker.get().onCancelled(control.getStatsToken(),
- ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL);
+ ImeTracker.forLogging().onCancelled(control.getStatsToken(),
+ PHASE_CLIENT_ANIMATION_CANCEL);
control.cancel();
} else {
// Succeeds if invokeCallback is false (i.e. when called from notifyFinished).
- ImeTracker.get().onProgress(control.getStatsToken(),
- ImeTracker.PHASE_CLIENT_ANIMATION_CANCEL);
+ ImeTracker.forLogging().onProgress(control.getStatsToken(),
+ PHASE_CLIENT_ANIMATION_CANCEL);
}
if (DEBUG) {
Log.d(TAG, TextUtils.formatSimple(
@@ -1674,7 +1749,7 @@
final InternalAnimationControlListener listener = new InternalAnimationControlListener(
show, hasAnimationCallbacks, types, mHost.getSystemBarsBehavior(),
skipAnim || mAnimationsDisabled, mHost.dipToPx(FLOATING_IME_BOTTOM_INSET_DP),
- mLoggingListener);
+ mLoggingListener, mJankContext);
// We are about to playing the default animation (show/hide). Passing a null frame indicates
// the controlled types should be animated regardless of the frame.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d603de2..e49e5c2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5815,7 +5815,7 @@
}
case MSG_SHOW_INSETS: {
final ImeTracker.Token statsToken = (ImeTracker.Token) msg.obj;
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_HANDLE_SHOW_INSETS);
if (mView == null) {
Log.e(TAG,
@@ -5828,7 +5828,7 @@
}
case MSG_HIDE_INSETS: {
final ImeTracker.Token statsToken = (ImeTracker.Token) msg.obj;
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_HANDLE_HIDE_INSETS);
mInsetsController.hide(msg.arg1, msg.arg2 == 1, statsToken);
break;
@@ -10407,10 +10407,10 @@
null /* icProto */);
}
if (viewAncestor != null) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
viewAncestor.showInsets(types, fromIme, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_SHOW_INSETS);
}
}
@@ -10424,10 +10424,10 @@
null /* icProto */);
}
if (viewAncestor != null) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
viewAncestor.hideInsets(types, fromIme, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_HIDE_INSETS);
}
}
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index c59d83e..a2708ee 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -21,6 +21,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
import android.annotation.NonNull;
+import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.os.Handler;
import android.os.IBinder;
@@ -246,6 +247,11 @@
}
@Override
+ public Context getRootViewContext() {
+ return mViewRoot != null ? mViewRoot.mContext : null;
+ }
+
+ @Override
public int dipToPx(int dips) {
if (mViewRoot != null) {
return mViewRoot.dipToPx(dips);
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 3b6ec80..e5a99ff 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -16,24 +16,36 @@
package android.view.inputmethod;
+import static com.android.internal.inputmethod.InputMethodDebug.softInputDisplayReasonToString;
+import static com.android.internal.jank.InteractionJankMonitor.CUJ_IME_INSETS_ANIMATION;
+import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_HIDDEN;
+import static com.android.internal.util.LatencyTracker.ACTION_REQUEST_IME_SHOWN;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
+import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemProperties;
import android.util.Log;
+import android.view.InsetsController.AnimationType;
+import android.view.SurfaceControl;
import com.android.internal.inputmethod.InputMethodDebug;
import com.android.internal.inputmethod.SoftInputShowHideReason;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.jank.InteractionJankMonitor.Configuration;
+import com.android.internal.util.LatencyTracker;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.util.Arrays;
+import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
@@ -385,15 +397,35 @@
void onHidden(@Nullable Token token);
/**
- * Get the singleton instance of this class.
+ * Get the singleton request tracker instance.
*
- * @return the singleton instance of this class
+ * @return the singleton request tracker instance
*/
@NonNull
- static ImeTracker get() {
+ static ImeTracker forLogging() {
return LOGGER;
}
+ /**
+ * Get the singleton jank tracker instance.
+ *
+ * @return the singleton jank tracker instance
+ */
+ @NonNull
+ static ImeJankTracker forJank() {
+ return JANK_TRACKER;
+ }
+
+ /**
+ * Get the singleton latency tracker instance.
+ *
+ * @return the singleton latency tracker instance
+ */
+ @NonNull
+ static ImeLatencyTracker forLatency() {
+ return LATENCY_TRACKER;
+ }
+
/** The singleton IME tracker instance. */
@NonNull
ImeTracker LOGGER = new ImeTracker() {
@@ -489,6 +521,12 @@
}
};
+ /** The singleton IME tracker instance for instrumenting jank metrics. */
+ ImeJankTracker JANK_TRACKER = new ImeJankTracker();
+
+ /** The singleton IME tracker instance for instrumenting latency metrics. */
+ ImeLatencyTracker LATENCY_TRACKER = new ImeLatencyTracker();
+
/** A token that tracks the progress of an IME request. */
class Token implements Parcelable {
@@ -592,4 +630,162 @@
}
}
}
+
+ /**
+ * Context related to {@link InteractionJankMonitor}.
+ */
+ interface InputMethodJankContext {
+ /**
+ * @return a context associated with a display
+ */
+ Context getDisplayContext();
+
+ /**
+ * @return a SurfaceControl that is going to be monitored
+ */
+ SurfaceControl getTargetSurfaceControl();
+
+ /**
+ * @return the package name of the host
+ */
+ String getHostPackageName();
+ }
+
+ /**
+ * Context related to {@link LatencyTracker}.
+ */
+ interface InputMethodLatencyContext {
+ /**
+ * @return a context associated with current application
+ */
+ Context getAppContext();
+ }
+
+ /**
+ * A tracker instance which is in charge of communicating with {@link InteractionJankMonitor}.
+ * This class disallows instantiating from outside, use {@link #forJank()} to get the singleton.
+ */
+ final class ImeJankTracker {
+
+ /**
+ * This class disallows instantiating from outside.
+ */
+ private ImeJankTracker() {
+ }
+
+ /**
+ * Called when the animation, which is going to be monitored, starts.
+ *
+ * @param jankContext context which is needed by {@link InteractionJankMonitor}
+ * @param animType {@link AnimationType}
+ * @param useSeparatedThread {@code true} if the animation is handled by the app,
+ * {@code false} if the animation will be scheduled on the
+ * {@link android.view.InsetsAnimationThread}
+ */
+ public void onRequestAnimation(@NonNull InputMethodJankContext jankContext,
+ @AnimationType int animType, boolean useSeparatedThread) {
+ if (jankContext.getDisplayContext() == null
+ || jankContext.getTargetSurfaceControl() == null) {
+ return;
+ }
+ final Configuration.Builder builder = Configuration.Builder.withSurface(
+ CUJ_IME_INSETS_ANIMATION,
+ jankContext.getDisplayContext(),
+ jankContext.getTargetSurfaceControl())
+ .setTag(String.format(Locale.US, "%d@%d@%s", animType,
+ useSeparatedThread ? 0 : 1, jankContext.getHostPackageName()));
+ InteractionJankMonitor.getInstance().begin(builder);
+ }
+
+ /**
+ * Called when the animation, which is going to be monitored, cancels.
+ */
+ public void onCancelAnimation() {
+ InteractionJankMonitor.getInstance().cancel(CUJ_IME_INSETS_ANIMATION);
+ }
+
+ /**
+ * Called when the animation, which is going to be monitored, ends.
+ */
+ public void onFinishAnimation() {
+ InteractionJankMonitor.getInstance().end(CUJ_IME_INSETS_ANIMATION);
+ }
+ }
+
+ /**
+ * A tracker instance which is in charge of communicating with {@link LatencyTracker}.
+ * This class disallows instantiating from outside, use {@link #forLatency()}
+ * to get the singleton.
+ */
+ final class ImeLatencyTracker {
+
+ /**
+ * This class disallows instantiating from outside.
+ */
+ private ImeLatencyTracker() {
+ }
+
+ private boolean shouldMonitorLatency(@SoftInputShowHideReason int reason) {
+ return reason == SoftInputShowHideReason.SHOW_SOFT_INPUT
+ || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT
+ || reason == SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API
+ || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API
+ || reason == SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME
+ || reason == SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME;
+ }
+
+ public void onRequestShow(@Nullable Token token, @Origin int origin,
+ @SoftInputShowHideReason int reason,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ if (!shouldMonitorLatency(reason)) return;
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionStart(
+ ACTION_REQUEST_IME_SHOWN,
+ softInputDisplayReasonToString(reason));
+ }
+
+ public void onRequestHide(@Nullable Token token, @Origin int origin,
+ @SoftInputShowHideReason int reason,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ if (!shouldMonitorLatency(reason)) return;
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionStart(
+ ACTION_REQUEST_IME_HIDDEN,
+ softInputDisplayReasonToString(reason));
+ }
+
+ public void onShowFailed(@Nullable Token token, @Phase int phase,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ onShowCancelled(token, phase, latencyContext);
+ }
+
+ public void onHideFailed(@Nullable Token token, @Phase int phase,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ onHideCancelled(token, phase, latencyContext);
+ }
+
+ public void onShowCancelled(@Nullable Token token, @Phase int phase,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionCancel(ACTION_REQUEST_IME_SHOWN);
+ }
+
+ public void onHideCancelled(@Nullable Token token, @Phase int phase,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionCancel(ACTION_REQUEST_IME_HIDDEN);
+ }
+
+ public void onShown(@Nullable Token token,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionEnd(ACTION_REQUEST_IME_SHOWN);
+ }
+
+ public void onHidden(@Nullable Token token,
+ @NonNull InputMethodLatencyContext latencyContext) {
+ LatencyTracker.getInstance(latencyContext.getAppContext())
+ .onActionEnd(ACTION_REQUEST_IME_HIDDEN);
+ }
+ }
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 99bd02d..642182b 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2045,10 +2045,11 @@
private boolean showSoftInput(View view, @Nullable ImeTracker.Token statsToken, int flags,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
if (statsToken == null) {
- statsToken = ImeTracker.get().onRequestShow(null /* component */,
+ statsToken = ImeTracker.forLogging().onRequestShow(null /* component */,
Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT, reason);
}
-
+ ImeTracker.forLatency().onRequestShow(statsToken, ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
+ reason, ActivityThread::currentApplication);
ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this,
null /* icProto */);
// Re-dispatch if there is a context mismatch.
@@ -2060,12 +2061,15 @@
checkFocus();
synchronized (mH) {
if (!hasServedByInputMethodLocked(view)) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLatency().onShowFailed(
+ statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED,
+ ActivityThread::currentApplication);
Log.w(TAG, "Ignoring showSoftInput() as view=" + view + " is not served.");
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
// Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
// TODO(b/229426865): call WindowInsetsController#show instead.
@@ -2095,20 +2099,20 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768499)
public void showSoftInputUnchecked(int flags, ResultReceiver resultReceiver) {
synchronized (mH) {
- final ImeTracker.Token statsToken = ImeTracker.get().onRequestShow(null /* component */,
- Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
+ final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestShow(
+ null /* component */, Process.myUid(), ImeTracker.ORIGIN_CLIENT_SHOW_SOFT_INPUT,
SoftInputShowHideReason.SHOW_SOFT_INPUT);
Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be"
+ " removed soon. If you are using androidx.appcompat.widget.SearchView,"
+ " please update to version 26.0 or newer version.");
if (mCurRootView == null || mCurRootView.getView() == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
Log.w(TAG, "No current root view, ignoring showSoftInputUnchecked()");
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
// Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread.
// TODO(b/229426865): call WindowInsetsController#show instead.
@@ -2186,20 +2190,24 @@
private boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
- final ImeTracker.Token statsToken = ImeTracker.get().onRequestHide(null /* component */,
- Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT, reason);
-
+ final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestHide(
+ null /* component */, Process.myUid(),
+ ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT, reason);
+ ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+ reason, ActivityThread::currentApplication);
ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
this, null /* icProto */);
checkFocus();
synchronized (mH) {
final View servedView = getServedViewLocked();
if (servedView == null || servedView.getWindowToken() != windowToken) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLatency().onHideFailed(statsToken,
+ ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken, statsToken,
flags, resultReceiver, reason);
@@ -2835,18 +2843,22 @@
@UnsupportedAppUsage
void closeCurrentInput() {
- final ImeTracker.Token statsToken = ImeTracker.get().onRequestHide(null /* component */,
- Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+ final ImeTracker.Token statsToken = ImeTracker.forLogging().onRequestHide(
+ null /* component */, Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT);
+ ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+ SoftInputShowHideReason.HIDE_SOFT_INPUT, ActivityThread::currentApplication);
synchronized (mH) {
if (mCurRootView == null || mCurRootView.getView() == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLatency().onHideFailed(statsToken,
+ ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
Log.w(TAG, "No current root view, ignoring closeCurrentInput()");
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
IInputMethodManagerGlobalInvoker.hideSoftInput(
mClient,
@@ -2905,11 +2917,13 @@
synchronized (mH) {
final View servedView = getServedViewLocked();
if (servedView == null || servedView.getWindowToken() != windowToken) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
+ ImeTracker.forLogging().onFailed(statsToken,
+ ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
+ ImeTracker.forLogging().onProgress(statsToken,
+ ImeTracker.PHASE_CLIENT_REQUEST_IME_SHOW);
showSoftInput(servedView, statsToken, 0 /* flags */, null /* resultReceiver */,
SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API);
@@ -2927,21 +2941,25 @@
*/
public void notifyImeHidden(IBinder windowToken, @Nullable ImeTracker.Token statsToken) {
if (statsToken == null) {
- statsToken = ImeTracker.get().onRequestHide(null /* component */,
+ statsToken = ImeTracker.forLogging().onRequestHide(null /* component */,
Process.myUid(), ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
}
-
+ ImeTracker.forLatency().onRequestHide(statsToken, ImeTracker.ORIGIN_CLIENT_HIDE_SOFT_INPUT,
+ SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API,
+ ActivityThread::currentApplication);
ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this,
null /* icProto */);
synchronized (mH) {
if (!isImeSessionAvailableLocked() || mCurRootView == null
|| mCurRootView.getWindowToken() != windowToken) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLatency().onHideFailed(statsToken,
+ ImeTracker.PHASE_CLIENT_VIEW_SERVED, ActivityThread::currentApplication);
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_VIEW_SERVED);
IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken, statsToken,
0 /* flags */, null /* resultReceiver */,
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index d6cc611..62f1599 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -16,11 +16,15 @@
package com.android.internal.jank;
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NORMAL;
import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
import static com.android.internal.jank.FrameTracker.REASON_END_NORMAL;
import static com.android.internal.jank.FrameTracker.REASON_END_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__BIOMETRIC_PROMPT_TRANSITION;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_PIP;
@@ -89,10 +93,13 @@
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__VOLUME_CONTROL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;
+import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.UiThread;
import android.annotation.WorkerThread;
+import android.app.ActivityThread;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
@@ -100,7 +107,6 @@
import android.os.HandlerThread;
import android.os.SystemClock;
import android.provider.DeviceConfig;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@@ -233,6 +239,7 @@
public static final int CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS = 66;
public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE = 67;
public static final int CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME = 68;
+ public static final int CUJ_IME_INSETS_ANIMATION = 69;
private static final int NO_STATSD_LOGGING = -1;
@@ -310,6 +317,7 @@
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_SWIPE_TO_RECENTS,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_SWIPE,
UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+ UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__IME_INSETS_ANIMATION,
};
private static class InstanceHolder {
@@ -402,7 +410,8 @@
CUJ_RECENTS_SCROLLING,
CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS,
CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE,
- CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME
+ CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME,
+ CUJ_IME_INSETS_ANIMATION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -423,29 +432,37 @@
* @param worker the worker thread for the callbacks
*/
@VisibleForTesting
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
public InteractionJankMonitor(@NonNull HandlerThread worker) {
- // Check permission early.
- Settings.Config.enforceReadPermission(
- DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR);
-
mRunningTrackers = new SparseArray<>();
mTimeoutActions = new SparseArray<>();
mWorker = worker;
mWorker.start();
- mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
mDisplayResolutionTracker = new DisplayResolutionTracker(worker.getThreadHandler());
-
- // Post initialization to the background in case we're running on the main
- // thread.
- mWorker.getThreadHandler().post(
- () -> mPropertiesChangedListener.onPropertiesChanged(
- DeviceConfig.getProperties(
- DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
- DeviceConfig.addOnPropertiesChangedListener(
- DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
- new HandlerExecutor(mWorker.getThreadHandler()),
- mPropertiesChangedListener);
+ mSamplingInterval = DEFAULT_SAMPLING_INTERVAL;
mEnabled = DEFAULT_ENABLED;
+
+ final Context context = ActivityThread.currentApplication();
+ if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
+ // Post initialization to the background in case we're running on the main thread.
+ mWorker.getThreadHandler().post(
+ () -> mPropertiesChangedListener.onPropertiesChanged(
+ DeviceConfig.getProperties(
+ DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
+ DeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
+ new HandlerExecutor(mWorker.getThreadHandler()),
+ mPropertiesChangedListener);
+ } else {
+ if (DEBUG) {
+ Log.d(TAG, "Initialized the InteractionJankMonitor."
+ + " (No READ_DEVICE_CONFIG permission to change configs)"
+ + " enabled=" + mEnabled + ", interval=" + mSamplingInterval
+ + ", missedFrameThreshold=" + mTraceThresholdMissedFrames
+ + ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
+ + ", package=" + context.getPackageName());
+ }
+ }
}
/**
@@ -927,6 +944,8 @@
return "LAUNCHER_CLOSE_ALL_APPS_SWIPE";
case CUJ_LAUNCHER_CLOSE_ALL_APPS_TO_HOME:
return "LAUNCHER_CLOSE_ALL_APPS_TO_HOME";
+ case CUJ_IME_INSETS_ANIMATION:
+ return "IME_INSETS_ANIMATION";
}
return "UNKNOWN";
}
@@ -1182,7 +1201,7 @@
*/
@VisibleForTesting
public int getDisplayId() {
- return (mSurfaceOnly ? mContext.getDisplay() : mView.getDisplay()).getDisplayId();
+ return (mSurfaceOnly ? mContext : mView.getContext()).getDisplayId();
}
}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index afb526a..2d5bb6c 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -14,7 +14,10 @@
package com.android.internal.util;
+import static android.Manifest.permission.READ_DEVICE_CONFIG;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Trace.TRACE_TAG_APP;
+import static android.provider.DeviceConfig.NAMESPACE_LATENCY_TRACKER;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
@@ -24,6 +27,8 @@
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR;
@@ -42,9 +47,12 @@
import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX;
import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX;
+import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.ActivityThread;
import android.content.Context;
import android.os.Build;
import android.os.ConditionVariable;
@@ -187,6 +195,16 @@
*/
public static final int ACTION_SHOW_VOICE_INTERACTION = 19;
+ /**
+ * Time it takes to request IME shown animation.
+ */
+ public static final int ACTION_REQUEST_IME_SHOWN = 20;
+
+ /**
+ * Time it takes to request IME hidden animation.
+ */
+ public static final int ACTION_REQUEST_IME_HIDDEN = 21;
+
private static final int[] ACTIONS_ALL = {
ACTION_EXPAND_PANEL,
ACTION_TOGGLE_RECENTS,
@@ -208,6 +226,8 @@
ACTION_SHOW_SELECTION_TOOLBAR,
ACTION_FOLD_TO_AOD,
ACTION_SHOW_VOICE_INTERACTION,
+ ACTION_REQUEST_IME_SHOWN,
+ ACTION_REQUEST_IME_HIDDEN,
};
/** @hide */
@@ -232,6 +252,8 @@
ACTION_SHOW_SELECTION_TOOLBAR,
ACTION_FOLD_TO_AOD,
ACTION_SHOW_VOICE_INTERACTION,
+ ACTION_REQUEST_IME_SHOWN,
+ ACTION_REQUEST_IME_HIDDEN,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Action {
@@ -259,6 +281,8 @@
UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION,
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN,
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN,
};
private static LatencyTracker sLatencyTracker;
@@ -284,15 +308,30 @@
return sLatencyTracker;
}
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
@VisibleForTesting
public LatencyTracker() {
mEnabled = DEFAULT_ENABLED;
- // Post initialization to the background in case we're running on the main thread.
- BackgroundThread.getHandler().post(() -> this.updateProperties(
- DeviceConfig.getProperties(DeviceConfig.NAMESPACE_LATENCY_TRACKER)));
- DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- BackgroundThread.getExecutor(), this::updateProperties);
+ final Context context = ActivityThread.currentApplication();
+ if (context != null
+ && context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
+ // Post initialization to the background in case we're running on the main thread.
+ BackgroundThread.getHandler().post(() -> this.updateProperties(
+ DeviceConfig.getProperties(NAMESPACE_LATENCY_TRACKER)));
+ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_LATENCY_TRACKER,
+ BackgroundThread.getExecutor(), this::updateProperties);
+ } else {
+ if (DEBUG) {
+ if (context == null) {
+ Log.d(TAG, "No application for " + ActivityThread.currentActivityThread());
+ } else {
+ Log.d(TAG, "Initialized the LatencyTracker."
+ + " (No READ_DEVICE_CONFIG permission to change configs)"
+ + " enabled=" + mEnabled + ", package=" + context.getPackageName());
+ }
+ }
+ }
}
private void updateProperties(DeviceConfig.Properties properties) {
@@ -368,6 +407,10 @@
return "ACTION_FOLD_TO_AOD";
case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION:
return "ACTION_SHOW_VOICE_INTERACTION";
+ case UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_SHOWN:
+ return "ACTION_REQUEST_IME_SHOWN";
+ case UIACTION_LATENCY_REPORTED__ACTION__ACTION_REQUEST_IME_HIDDEN:
+ return "ACTION_REQUEST_IME_HIDDEN";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
index a775db9..2ea4316 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java
@@ -387,7 +387,7 @@
@Nullable ImeTracker.Token statsToken) {
final InsetsSource imeSource = mInsetsState.peekSource(InsetsSource.ID_IME);
if (imeSource == null || mImeSourceControl == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
return;
}
final Rect newFrame = imeSource.getFrame();
@@ -410,7 +410,8 @@
}
if ((!forceRestart && (mAnimationDirection == DIRECTION_SHOW && show))
|| (mAnimationDirection == DIRECTION_HIDE && !show)) {
- ImeTracker.get().onCancelled(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+ ImeTracker.forLogging().onCancelled(
+ statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
return;
}
boolean seek = false;
@@ -454,7 +455,7 @@
mTransactionPool.release(t);
});
mAnimation.setInterpolator(INTERPOLATOR);
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_WM_ANIMATION_CREATE);
mAnimation.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled = false;
@Nullable
@@ -477,7 +478,7 @@
: 1.f;
t.setAlpha(mImeSourceControl.getLeash(), alpha);
if (mAnimationDirection == DIRECTION_SHOW) {
- ImeTracker.get().onProgress(mStatsToken,
+ ImeTracker.forLogging().onProgress(mStatsToken,
ImeTracker.PHASE_WM_ANIMATION_RUNNING);
t.show(mImeSourceControl.getLeash());
}
@@ -514,15 +515,15 @@
}
dispatchEndPositioning(mDisplayId, mCancelled, t);
if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
- ImeTracker.get().onProgress(mStatsToken,
+ ImeTracker.forLogging().onProgress(mStatsToken,
ImeTracker.PHASE_WM_ANIMATION_RUNNING);
t.hide(mImeSourceControl.getLeash());
removeImeSurface();
- ImeTracker.get().onHidden(mStatsToken);
+ ImeTracker.forLogging().onHidden(mStatsToken);
} else if (mAnimationDirection == DIRECTION_SHOW && !mCancelled) {
- ImeTracker.get().onShown(mStatsToken);
+ ImeTracker.forLogging().onShown(mStatsToken);
} else if (mCancelled) {
- ImeTracker.get().onCancelled(mStatsToken,
+ ImeTracker.forLogging().onCancelled(mStatsToken,
ImeTracker.PHASE_WM_ANIMATION_RUNNING);
}
if (DEBUG_IME_VISIBILITY) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
index 8759301..9bdda14 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayInsetsController.java
@@ -162,10 +162,12 @@
@Nullable ImeTracker.Token statsToken) {
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
if (listeners == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
for (OnInsetsChangedListener listener : listeners) {
listener.showInsets(types, fromIme, statsToken);
}
@@ -175,10 +177,12 @@
@Nullable ImeTracker.Token statsToken) {
CopyOnWriteArrayList<OnInsetsChangedListener> listeners = mListeners.get(mDisplayId);
if (listeners == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
return;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
+ ImeTracker.forLogging().onProgress(
+ statsToken, ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROLLER);
for (OnInsetsChangedListener listener : listeners) {
listener.hideInsets(types, fromIme, statsToken);
}
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 298f6ad..9f7ff31 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -130,14 +130,14 @@
@ImeVisibilityStateComputer.VisibilityState int state, int reason) {
switch (state) {
case STATE_SHOW_IME:
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
// Send to window manager to show IME after IME layout finishes.
mWindowManagerInternal.showImePostLayout(windowToken, statsToken);
break;
case STATE_HIDE_IME:
if (mService.mCurFocusedWindowClient != null) {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
// IMMS only knows of focused window, not the actual IME target.
// e.g. it isn't aware of any window that has both
@@ -148,7 +148,7 @@
mWindowManagerInternal.hideIme(windowToken,
mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
}
break;
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index eaca842..ceb9706 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -183,10 +183,10 @@
*/
boolean onImeShowFlags(@NonNull ImeTracker.Token statsToken, int showFlags) {
if (mPolicy.mA11yRequestingNoSoftKeyboard || mPolicy.mImeHiddenByDisplayPolicy) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_ACCESSIBILITY);
if ((showFlags & InputMethodManager.SHOW_FORCED) != 0) {
mRequestedShowExplicitly = true;
mShowForced = true;
@@ -207,15 +207,15 @@
if ((hideFlags & InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
&& (mRequestedShowExplicitly || mShowForced)) {
if (DEBUG) Slog.v(TAG, "Not hiding: explicit show not cancelled by non-explicit hide");
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_IMPLICIT);
return false;
}
if (mShowForced && (hideFlags & InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide");
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HIDE_NOT_ALWAYS);
return true;
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 27daceb..233e285 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2293,7 +2293,7 @@
mCurClient.mSessionRequestedForAccessibility = false;
mCurClient = null;
mCurVirtualDisplayToScreenMatrix = null;
- ImeTracker.get().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+ ImeTracker.forLogging().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
mCurStatsToken = null;
mMenuController.hideInputMethodMenuLocked();
@@ -3279,7 +3279,8 @@
"InputMethodManagerService#showSoftInput");
synchronized (ImfLock.class) {
if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken)) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
return false;
}
final long ident = Binder.clearCallingIdentity();
@@ -3375,7 +3376,7 @@
// TODO(b/261565259): to avoid using null, add package name in ClientState
final String packageName = (mCurEditorInfo != null) ? mCurEditorInfo.packageName : null;
final int uid = mCurClient != null ? mCurClient.mUid : -1;
- statsToken = ImeTracker.get().onRequestShow(packageName, uid,
+ statsToken = ImeTracker.forLogging().onRequestShow(packageName, uid,
ImeTracker.ORIGIN_SERVER_START_INPUT, reason);
}
@@ -3384,19 +3385,19 @@
}
if (!mSystemReady) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
return false;
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);
mVisibilityStateComputer.requestImeVisibility(windowToken, true);
// Ensure binding the connection when IME is going to show.
mBindingController.setCurrentMethodVisible();
final IInputMethodInvoker curMethod = getCurMethodLocked();
- ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+ ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
if (curMethod != null) {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
mCurStatsToken = null;
if (lastClickToolType != MotionEvent.TOOL_TYPE_UNKNOWN) {
@@ -3407,7 +3408,7 @@
mVisibilityStateComputer.setInputShown(true);
return true;
} else {
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
mCurStatsToken = statsToken;
}
return false;
@@ -3423,9 +3424,10 @@
synchronized (ImfLock.class) {
if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken)) {
if (isInputShown()) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+ ImeTracker.forLogging().onFailed(
+ statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
} else {
- ImeTracker.get().onCancelled(statsToken,
+ ImeTracker.forLogging().onCancelled(statsToken,
ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
}
return false;
@@ -3458,7 +3460,7 @@
} else {
uid = -1;
}
- statsToken = ImeTracker.get().onRequestHide(packageName, uid,
+ statsToken = ImeTracker.forLogging().onRequestHide(packageName, uid,
ImeTracker.ORIGIN_SERVER_HIDE_INPUT, reason);
}
@@ -3484,15 +3486,15 @@
// delivered to the IME process as an IPC. Hence the inconsistency between
// IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
// the final state.
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason);
} else {
- ImeTracker.get().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
+ ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
}
mBindingController.setCurrentMethodNotVisible();
mVisibilityStateComputer.clearImeShowFlags();
// Cancel existing statsToken for show IME as we got a hide request.
- ImeTracker.get().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+ ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
mCurStatsToken = null;
return shouldHideSoftInput;
}
@@ -3764,16 +3766,16 @@
// be made before input is started in it.
final ClientState cs = mClients.get(client.asBinder());
if (cs == null) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
+ ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
throw new IllegalArgumentException("unknown client " + client.asBinder());
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
if (!isImeClientFocused(mCurFocusedWindow, cs)) {
Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
return false;
}
}
- ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
+ ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
return true;
}
@@ -4550,7 +4552,8 @@
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
synchronized (ImfLock.class) {
if (!calledWithValidTokenLocked(token)) {
- ImeTracker.get().onFailed(statsToken, ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
+ ImeTracker.forLogging().onFailed(statsToken,
+ ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
return;
}
final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(windowToken);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7d89c32..9060456 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6850,12 +6850,12 @@
public void showInsets(@WindowInsets.Type.InsetsType int types, boolean fromIme,
@Nullable ImeTracker.Token statsToken) {
try {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SHOW_INSETS);
mRemoteInsetsController.showInsets(types, fromIme, statsToken);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver showInsets", e);
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SHOW_INSETS);
}
}
@@ -6864,12 +6864,12 @@
public void hideInsets(@InsetsType int types, boolean fromIme,
@Nullable ImeTracker.Token statsToken) {
try {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_HIDE_INSETS);
mRemoteInsetsController.hideInsets(types, fromIme, statsToken);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver hideInsets", e);
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_HIDE_INSETS);
}
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index f38ae3f..4be98a3 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -182,7 +182,8 @@
boolean targetChanged = isTargetChangedWithinActivity(imeTarget);
mImeRequester = imeTarget;
// There was still a stats token, so that request presumably failed.
- ImeTracker.get().onFailed(mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
+ ImeTracker.forLogging().onFailed(
+ mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
mImeRequesterStatsToken = statsToken;
if (targetChanged) {
// target changed, check if new target can show IME.
@@ -197,12 +198,12 @@
ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeRequester.getWindow() == null
? mImeRequester : mImeRequester.getWindow().getName());
mShowImeRunner = () -> {
- ImeTracker.get().onProgress(mImeRequesterStatsToken,
+ ImeTracker.forLogging().onProgress(mImeRequesterStatsToken,
ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
ProtoLog.d(WM_DEBUG_IME, "Run showImeRunner");
// Target should still be the same.
if (isReadyToShowIme()) {
- ImeTracker.get().onProgress(mImeRequesterStatsToken,
+ ImeTracker.forLogging().onProgress(mImeRequesterStatsToken,
ImeTracker.PHASE_WM_SHOW_IME_READY);
final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
@@ -219,7 +220,7 @@
? mImeRequester.getWindow().getName() : ""));
}
} else {
- ImeTracker.get().onFailed(mImeRequesterStatsToken,
+ ImeTracker.forLogging().onFailed(mImeRequesterStatsToken,
ImeTracker.PHASE_WM_SHOW_IME_READY);
}
// Clear token here so we don't report an error in abortShowImePostLayout().
@@ -258,7 +259,8 @@
mImeRequester = null;
mIsImeLayoutDrawn = false;
mShowImeRunner = null;
- ImeTracker.get().onCancelled(mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
+ ImeTracker.forLogging().onCancelled(
+ mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
mImeRequesterStatsToken = null;
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 5c5eadc..0b8af4a 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -718,7 +718,8 @@
InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) {
super(show, false /* hasCallbacks */, types, BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE,
- false /* disable */, 0 /* floatingImeBottomInsets */, null);
+ false /* disable */, 0 /* floatingImeBottomInsets */,
+ null /* loggingListener */, null /* jankContext */);
mFinishCallback = finishCallback;
mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 23d3637..5f49aeb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8127,14 +8127,14 @@
dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
}
if (dc != null && dc.getImeTarget(IME_TARGET_CONTROL) != null) {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
ProtoLog.d(WM_DEBUG_IME, "hideIme Control target: %s ",
dc.getImeTarget(IME_TARGET_CONTROL));
dc.getImeTarget(IME_TARGET_CONTROL).hideInsets(WindowInsets.Type.ime(),
true /* fromIme */, statsToken);
} else {
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_WM_HAS_IME_INSETS_CONTROL_TARGET);
}
if (dc != null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d8ac0ff..bf6bab3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -4016,12 +4016,12 @@
public void showInsets(@InsetsType int types, boolean fromIme,
@Nullable ImeTracker.Token statsToken) {
try {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_SHOW_INSETS);
mClient.showInsets(types, fromIme, statsToken);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver showInsets", e);
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_SHOW_INSETS);
}
}
@@ -4030,12 +4030,12 @@
public void hideInsets(@InsetsType int types, boolean fromIme,
@Nullable ImeTracker.Token statsToken) {
try {
- ImeTracker.get().onProgress(statsToken,
+ ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_HIDE_INSETS);
mClient.hideInsets(types, fromIme, statsToken);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to deliver hideInsets", e);
- ImeTracker.get().onFailed(statsToken,
+ ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_WM_WINDOW_INSETS_CONTROL_TARGET_HIDE_INSETS);
}
}