Merge changes I59db19c5,I49ceeefd,I3e3bc097 into udc-dev
* changes: Move IImeTracker from view to inputmethod Fix ImeTrackerService dump formatting Add logs for ImeTrackerService#History#setFinished
This commit is contained in:
@@ -25,6 +25,7 @@ import android.annotation.RequiresNoPermission;
|
|||||||
import android.annotation.RequiresPermission;
|
import android.annotation.RequiresPermission;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
@@ -33,6 +34,7 @@ import android.view.WindowManager;
|
|||||||
import android.window.ImeOnBackInvokedDispatcher;
|
import android.window.ImeOnBackInvokedDispatcher;
|
||||||
|
|
||||||
import com.android.internal.inputmethod.DirectBootAwareness;
|
import com.android.internal.inputmethod.DirectBootAwareness;
|
||||||
|
import com.android.internal.inputmethod.IImeTracker;
|
||||||
import com.android.internal.inputmethod.IInputMethodClient;
|
import com.android.internal.inputmethod.IInputMethodClient;
|
||||||
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
|
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
|
||||||
import com.android.internal.inputmethod.IRemoteInputConnection;
|
import com.android.internal.inputmethod.IRemoteInputConnection;
|
||||||
@@ -40,7 +42,6 @@ import com.android.internal.inputmethod.InputBindResult;
|
|||||||
import com.android.internal.inputmethod.SoftInputShowHideReason;
|
import com.android.internal.inputmethod.SoftInputShowHideReason;
|
||||||
import com.android.internal.inputmethod.StartInputFlags;
|
import com.android.internal.inputmethod.StartInputFlags;
|
||||||
import com.android.internal.inputmethod.StartInputReason;
|
import com.android.internal.inputmethod.StartInputReason;
|
||||||
import com.android.internal.view.IImeTracker;
|
|
||||||
import com.android.internal.view.IInputMethodManager;
|
import com.android.internal.view.IInputMethodManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -581,51 +582,57 @@ final class IInputMethodManagerGlobalInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onRequestShow */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
@Nullable
|
@NonNull
|
||||||
static IBinder onRequestShow(int uid, @ImeTracker.Origin int origin,
|
static ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
|
||||||
@SoftInputShowHideReason int reason) {
|
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return null;
|
// Create token with "fake" binder if the service was not found.
|
||||||
|
return new ImeTracker.Token(new Binder(), tag);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return service.onRequestShow(uid, origin, reason);
|
return service.onRequestShow(tag, uid, origin, reason);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onRequestHide */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
@Nullable
|
@NonNull
|
||||||
static IBinder onRequestHide(int uid, @ImeTracker.Origin int origin,
|
static ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
|
||||||
@SoftInputShowHideReason int reason) {
|
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return null;
|
// Create token with "fake" binder if the service was not found.
|
||||||
|
return new ImeTracker.Token(new Binder(), tag);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return service.onRequestHide(uid, origin, reason);
|
return service.onRequestHide(tag, uid, origin, reason);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onProgress */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
static void onProgress(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
static void onProgress(@NonNull IBinder binder, @ImeTracker.Phase int phase) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
service.onProgress(statsToken, phase);
|
service.onProgress(binder, phase);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onFailed */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
static void onFailed(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
static void onFailed(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return;
|
return;
|
||||||
@@ -637,8 +644,9 @@ final class IInputMethodManagerGlobalInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onCancelled */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
static void onCancelled(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
static void onCancelled(@NonNull ImeTracker.Token statsToken, @ImeTracker.Phase int phase) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return;
|
return;
|
||||||
@@ -650,8 +658,9 @@ final class IInputMethodManagerGlobalInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onShown */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
static void onShown(@NonNull IBinder statsToken) {
|
static void onShown(@NonNull ImeTracker.Token statsToken) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return;
|
return;
|
||||||
@@ -663,8 +672,9 @@ final class IInputMethodManagerGlobalInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#onHidden */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
static void onHidden(@NonNull IBinder statsToken) {
|
static void onHidden(@NonNull ImeTracker.Token statsToken) {
|
||||||
final IImeTracker service = getImeTrackerService();
|
final IImeTracker service = getImeTrackerService();
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
return;
|
return;
|
||||||
@@ -676,6 +686,7 @@ final class IInputMethodManagerGlobalInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @see com.android.server.inputmethod.ImeTrackerService#hasPendingImeVisibilityRequests */
|
||||||
@AnyThread
|
@AnyThread
|
||||||
@RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
|
@RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
|
||||||
static boolean hasPendingImeVisibilityRequests() {
|
static boolean hasPendingImeVisibilityRequests() {
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityThread;
|
import android.app.ActivityThread;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Binder;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
@@ -47,7 +46,7 @@ import java.lang.reflect.Field;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -321,9 +320,8 @@ public interface ImeTracker {
|
|||||||
/**
|
/**
|
||||||
* Creates an IME show request tracking token.
|
* Creates an IME show request tracking token.
|
||||||
*
|
*
|
||||||
* @param component the component name where the IME show request was created,
|
* @param component the name of the component that created the IME request, or {@code null}
|
||||||
* or {@code null} otherwise
|
* otherwise (defaulting to {@link ActivityThread#currentProcessName()}).
|
||||||
* (defaulting to {@link ActivityThread#currentProcessName()}).
|
|
||||||
* @param uid the uid of the client that requested the IME.
|
* @param uid the uid of the client that requested the IME.
|
||||||
* @param origin the origin of the IME show request.
|
* @param origin the origin of the IME show request.
|
||||||
* @param reason the reason why the IME show request was created.
|
* @param reason the reason why the IME show request was created.
|
||||||
@@ -337,9 +335,8 @@ public interface ImeTracker {
|
|||||||
/**
|
/**
|
||||||
* Creates an IME hide request tracking token.
|
* Creates an IME hide request tracking token.
|
||||||
*
|
*
|
||||||
* @param component the component name where the IME hide request was created,
|
* @param component the name of the component that created the IME request, or {@code null}
|
||||||
* or {@code null} otherwise
|
* otherwise (defaulting to {@link ActivityThread#currentProcessName()}).
|
||||||
* (defaulting to {@link ActivityThread#currentProcessName()}).
|
|
||||||
* @param uid the uid of the client that requested the IME.
|
* @param uid the uid of the client that requested the IME.
|
||||||
* @param origin the origin of the IME hide request.
|
* @param origin the origin of the IME hide request.
|
||||||
* @param reason the reason why the IME hide request was created.
|
* @param reason the reason why the IME hide request was created.
|
||||||
@@ -435,8 +432,7 @@ public interface ImeTracker {
|
|||||||
mLogProgress = SystemProperties.getBoolean("persist.debug.imetracker", false);
|
mLogProgress = SystemProperties.getBoolean("persist.debug.imetracker", false);
|
||||||
// Update logging flag dynamically.
|
// Update logging flag dynamically.
|
||||||
SystemProperties.addChangeCallback(() ->
|
SystemProperties.addChangeCallback(() ->
|
||||||
mLogProgress =
|
mLogProgress = SystemProperties.getBoolean("persist.debug.imetracker", false));
|
||||||
SystemProperties.getBoolean("persist.debug.imetracker", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether progress should be logged. */
|
/** Whether progress should be logged. */
|
||||||
@@ -446,10 +442,9 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public Token onRequestShow(@Nullable String component, int uid, @Origin int origin,
|
public Token onRequestShow(@Nullable String component, int uid, @Origin int origin,
|
||||||
@SoftInputShowHideReason int reason) {
|
@SoftInputShowHideReason int reason) {
|
||||||
IBinder binder = IInputMethodManagerGlobalInvoker.onRequestShow(uid, origin, reason);
|
final var tag = getTag(component);
|
||||||
if (binder == null) binder = new Binder();
|
final var token = IInputMethodManagerGlobalInvoker.onRequestShow(tag, uid, origin,
|
||||||
|
reason);
|
||||||
final Token token = Token.build(binder, component);
|
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onRequestShow at " + Debug.originToString(origin)
|
Log.i(TAG, token.mTag + ": onRequestShow at " + Debug.originToString(origin)
|
||||||
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
|
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
|
||||||
@@ -461,10 +456,9 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public Token onRequestHide(@Nullable String component, int uid, @Origin int origin,
|
public Token onRequestHide(@Nullable String component, int uid, @Origin int origin,
|
||||||
@SoftInputShowHideReason int reason) {
|
@SoftInputShowHideReason int reason) {
|
||||||
IBinder binder = IInputMethodManagerGlobalInvoker.onRequestHide(uid, origin, reason);
|
final var tag = getTag(component);
|
||||||
if (binder == null) binder = new Binder();
|
final var token = IInputMethodManagerGlobalInvoker.onRequestHide(tag, uid, origin,
|
||||||
|
reason);
|
||||||
final Token token = Token.build(binder, component);
|
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onRequestHide at " + Debug.originToString(origin)
|
Log.i(TAG, token.mTag + ": onRequestHide at " + Debug.originToString(origin)
|
||||||
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
|
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
|
||||||
@@ -485,7 +479,7 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public void onFailed(@Nullable Token token, @Phase int phase) {
|
public void onFailed(@Nullable Token token, @Phase int phase) {
|
||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
IInputMethodManagerGlobalInvoker.onFailed(token.mBinder, phase);
|
IInputMethodManagerGlobalInvoker.onFailed(token, phase);
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onFailed at " + Debug.phaseToString(phase));
|
Log.i(TAG, token.mTag + ": onFailed at " + Debug.phaseToString(phase));
|
||||||
}
|
}
|
||||||
@@ -499,7 +493,7 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public void onCancelled(@Nullable Token token, @Phase int phase) {
|
public void onCancelled(@Nullable Token token, @Phase int phase) {
|
||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
IInputMethodManagerGlobalInvoker.onCancelled(token.mBinder, phase);
|
IInputMethodManagerGlobalInvoker.onCancelled(token, phase);
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onCancelled at " + Debug.phaseToString(phase));
|
Log.i(TAG, token.mTag + ": onCancelled at " + Debug.phaseToString(phase));
|
||||||
}
|
}
|
||||||
@@ -507,7 +501,7 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public void onShown(@Nullable Token token) {
|
public void onShown(@Nullable Token token) {
|
||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
IInputMethodManagerGlobalInvoker.onShown(token.mBinder);
|
IInputMethodManagerGlobalInvoker.onShown(token);
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onShown");
|
Log.i(TAG, token.mTag + ": onShown");
|
||||||
}
|
}
|
||||||
@@ -515,10 +509,24 @@ public interface ImeTracker {
|
|||||||
@Override
|
@Override
|
||||||
public void onHidden(@Nullable Token token) {
|
public void onHidden(@Nullable Token token) {
|
||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
IInputMethodManagerGlobalInvoker.onHidden(token.mBinder);
|
IInputMethodManagerGlobalInvoker.onHidden(token);
|
||||||
|
|
||||||
Log.i(TAG, token.mTag + ": onHidden");
|
Log.i(TAG, token.mTag + ": onHidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a logging tag using the given component name.
|
||||||
|
*
|
||||||
|
* @param component the name of the component that created the IME request, or {@code null}
|
||||||
|
* otherwise (defaulting to {@link ActivityThread#currentProcessName()}).
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private String getTag(@Nullable String component) {
|
||||||
|
if (component == null) {
|
||||||
|
component = ActivityThread.currentProcessName();
|
||||||
|
}
|
||||||
|
return component + ":" + Integer.toHexString(ThreadLocalRandom.current().nextInt());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The singleton IME tracker instance for instrumenting jank metrics. */
|
/** The singleton IME tracker instance for instrumenting jank metrics. */
|
||||||
@@ -528,28 +536,31 @@ public interface ImeTracker {
|
|||||||
ImeLatencyTracker LATENCY_TRACKER = new ImeLatencyTracker();
|
ImeLatencyTracker LATENCY_TRACKER = new ImeLatencyTracker();
|
||||||
|
|
||||||
/** A token that tracks the progress of an IME request. */
|
/** A token that tracks the progress of an IME request. */
|
||||||
class Token implements Parcelable {
|
final class Token implements Parcelable {
|
||||||
|
|
||||||
|
/** The binder used to identify this token. */
|
||||||
@NonNull
|
@NonNull
|
||||||
public final IBinder mBinder;
|
private final IBinder mBinder;
|
||||||
|
|
||||||
|
/** Logging tag, of the shape "component:random_hexadecimal". */
|
||||||
@NonNull
|
@NonNull
|
||||||
private final String mTag;
|
private final String mTag;
|
||||||
|
|
||||||
@NonNull
|
public Token(@NonNull IBinder binder, @NonNull String tag) {
|
||||||
private static Token build(@NonNull IBinder binder, @Nullable String component) {
|
|
||||||
if (component == null) component = ActivityThread.currentProcessName();
|
|
||||||
final String tag = component + ":" + Integer.toHexString((new Random().nextInt()));
|
|
||||||
|
|
||||||
return new Token(binder, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Token(@NonNull IBinder binder, @NonNull String tag) {
|
|
||||||
mBinder = binder;
|
mBinder = binder;
|
||||||
mTag = tag;
|
mTag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the {@link Token#mTag} */
|
private Token(@NonNull Parcel in) {
|
||||||
|
mBinder = in.readStrongBinder();
|
||||||
|
mTag = in.readString8();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public IBinder getBinder() {
|
||||||
|
return mBinder;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String getTag() {
|
public String getTag() {
|
||||||
return mTag;
|
return mTag;
|
||||||
@@ -562,7 +573,7 @@ public interface ImeTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
dest.writeStrongBinder(mBinder);
|
dest.writeStrongBinder(mBinder);
|
||||||
dest.writeString8(mTag);
|
dest.writeString8(mTag);
|
||||||
}
|
}
|
||||||
@@ -571,12 +582,11 @@ public interface ImeTracker {
|
|||||||
public static final Creator<Token> CREATOR = new Creator<>() {
|
public static final Creator<Token> CREATOR = new Creator<>() {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Token createFromParcel(Parcel source) {
|
public Token createFromParcel(@NonNull Parcel in) {
|
||||||
final IBinder binder = source.readStrongBinder();
|
return new Token(in);
|
||||||
final String tag = source.readString8();
|
|
||||||
return new Token(binder, tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Token[] newArray(int size) {
|
public Token[] newArray(int size) {
|
||||||
return new Token[size];
|
return new Token[size];
|
||||||
@@ -589,40 +599,50 @@ public interface ImeTracker {
|
|||||||
*
|
*
|
||||||
* Note: This is held in a separate class so that it only gets initialized when actually needed.
|
* Note: This is held in a separate class so that it only gets initialized when actually needed.
|
||||||
*/
|
*/
|
||||||
class Debug {
|
final class Debug {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private static final Map<Integer, String> sTypes =
|
private static final Map<Integer, String> sTypes =
|
||||||
getFieldMapping(ImeTracker.class, "TYPE_");
|
getFieldMapping(ImeTracker.class, "TYPE_");
|
||||||
|
@NonNull
|
||||||
private static final Map<Integer, String> sStatus =
|
private static final Map<Integer, String> sStatus =
|
||||||
getFieldMapping(ImeTracker.class, "STATUS_");
|
getFieldMapping(ImeTracker.class, "STATUS_");
|
||||||
|
@NonNull
|
||||||
private static final Map<Integer, String> sOrigins =
|
private static final Map<Integer, String> sOrigins =
|
||||||
getFieldMapping(ImeTracker.class, "ORIGIN_");
|
getFieldMapping(ImeTracker.class, "ORIGIN_");
|
||||||
|
@NonNull
|
||||||
private static final Map<Integer, String> sPhases =
|
private static final Map<Integer, String> sPhases =
|
||||||
getFieldMapping(ImeTracker.class, "PHASE_");
|
getFieldMapping(ImeTracker.class, "PHASE_");
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public static String typeToString(@Type int type) {
|
public static String typeToString(@Type int type) {
|
||||||
return sTypes.getOrDefault(type, "TYPE_" + type);
|
return sTypes.getOrDefault(type, "TYPE_" + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public static String statusToString(@Status int status) {
|
public static String statusToString(@Status int status) {
|
||||||
return sStatus.getOrDefault(status, "STATUS_" + status);
|
return sStatus.getOrDefault(status, "STATUS_" + status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public static String originToString(@Origin int origin) {
|
public static String originToString(@Origin int origin) {
|
||||||
return sOrigins.getOrDefault(origin, "ORIGIN_" + origin);
|
return sOrigins.getOrDefault(origin, "ORIGIN_" + origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public static String phaseToString(@Phase int phase) {
|
public static String phaseToString(@Phase int phase) {
|
||||||
return sPhases.getOrDefault(phase, "PHASE_" + phase);
|
return sPhases.getOrDefault(phase, "PHASE_" + phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Integer, String> getFieldMapping(Class<?> cls, String fieldPrefix) {
|
@NonNull
|
||||||
|
private static Map<Integer, String> getFieldMapping(Class<?> cls,
|
||||||
|
@NonNull String fieldPrefix) {
|
||||||
return Arrays.stream(cls.getDeclaredFields())
|
return Arrays.stream(cls.getDeclaredFields())
|
||||||
.filter(field -> field.getName().startsWith(fieldPrefix))
|
.filter(field -> field.getName().startsWith(fieldPrefix))
|
||||||
.collect(Collectors.toMap(Debug::getFieldValue, Field::getName));
|
.collect(Collectors.toMap(Debug::getFieldValue, Field::getName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getFieldValue(Field field) {
|
private static int getFieldValue(@NonNull Field field) {
|
||||||
try {
|
try {
|
||||||
return field.getInt(null);
|
return field.getInt(null);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
|
|||||||
@@ -14,43 +14,45 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.internal.view;
|
package com.android.internal.inputmethod;
|
||||||
|
|
||||||
import android.view.inputmethod.ImeTracker;
|
import android.view.inputmethod.ImeTracker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to the global Ime tracker, used by all client applications.
|
* Interface to the global IME tracker service, used by all client applications.
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
interface IImeTracker {
|
interface IImeTracker {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an IME show request is created,
|
* Called when an IME show request is created.
|
||||||
* returns a new Binder to be associated with the IME tracking token.
|
|
||||||
*
|
*
|
||||||
|
* @param tag the logging tag.
|
||||||
* @param uid the uid of the client that requested the IME.
|
* @param uid the uid of the client that requested the IME.
|
||||||
* @param origin the origin of the IME show request.
|
* @param origin the origin of the IME show request.
|
||||||
* @param reason the reason why the IME show request was created.
|
* @param reason the reason why the IME show request was created.
|
||||||
|
* @return A new IME tracking token.
|
||||||
*/
|
*/
|
||||||
IBinder onRequestShow(int uid, int origin, int reason);
|
ImeTracker.Token onRequestShow(String tag, int uid, int origin, int reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an IME hide request is created,
|
* Called when an IME hide request is created.
|
||||||
* returns a new Binder to be associated with the IME tracking token.
|
|
||||||
*
|
*
|
||||||
|
* @param tag the logging tag.
|
||||||
* @param uid the uid of the client that requested the IME.
|
* @param uid the uid of the client that requested the IME.
|
||||||
* @param origin the origin of the IME hide request.
|
* @param origin the origin of the IME hide request.
|
||||||
* @param reason the reason why the IME hide request was created.
|
* @param reason the reason why the IME hide request was created.
|
||||||
|
* @return A new IME tracking token.
|
||||||
*/
|
*/
|
||||||
IBinder onRequestHide(int uid, int origin, int reason);
|
ImeTracker.Token onRequestHide(String tag, int uid, int origin, int reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the IME request progresses to a further phase.
|
* Called when the IME request progresses to a further phase.
|
||||||
*
|
*
|
||||||
* @param statsToken the token tracking the current IME request.
|
* @param binder the binder of token tracking the current IME request.
|
||||||
* @param phase the new phase the IME request reached.
|
* @param phase the new phase the IME request reached.
|
||||||
*/
|
*/
|
||||||
oneway void onProgress(in IBinder statsToken, int phase);
|
oneway void onProgress(in IBinder binder, int phase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the IME request fails.
|
* Called when the IME request fails.
|
||||||
@@ -58,7 +60,7 @@ interface IImeTracker {
|
|||||||
* @param statsToken the token tracking the current IME request.
|
* @param statsToken the token tracking the current IME request.
|
||||||
* @param phase the phase the IME request failed at.
|
* @param phase the phase the IME request failed at.
|
||||||
*/
|
*/
|
||||||
oneway void onFailed(in IBinder statsToken, int phase);
|
oneway void onFailed(in ImeTracker.Token statsToken, int phase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the IME request is cancelled.
|
* Called when the IME request is cancelled.
|
||||||
@@ -66,21 +68,21 @@ interface IImeTracker {
|
|||||||
* @param statsToken the token tracking the current IME request.
|
* @param statsToken the token tracking the current IME request.
|
||||||
* @param phase the phase the IME request was cancelled at.
|
* @param phase the phase the IME request was cancelled at.
|
||||||
*/
|
*/
|
||||||
oneway void onCancelled(in IBinder statsToken, int phase);
|
oneway void onCancelled(in ImeTracker.Token statsToken, int phase);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the IME show request is successful.
|
* Called when the IME show request is successful.
|
||||||
*
|
*
|
||||||
* @param statsToken the token tracking the current IME request.
|
* @param statsToken the token tracking the current IME request.
|
||||||
*/
|
*/
|
||||||
oneway void onShown(in IBinder statsToken);
|
oneway void onShown(in ImeTracker.Token statsToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the IME hide request is successful.
|
* Called when the IME hide request is successful.
|
||||||
*
|
*
|
||||||
* @param statsToken the token tracking the current IME request.
|
* @param statsToken the token tracking the current IME request.
|
||||||
*/
|
*/
|
||||||
oneway void onHidden(in IBinder statsToken);
|
oneway void onHidden(in ImeTracker.Token statsToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether there are any pending IME visibility requests.
|
* Checks whether there are any pending IME visibility requests.
|
||||||
@@ -23,11 +23,11 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.window.ImeOnBackInvokedDispatcher;
|
import android.window.ImeOnBackInvokedDispatcher;
|
||||||
|
|
||||||
|
import com.android.internal.inputmethod.IImeTracker;
|
||||||
import com.android.internal.inputmethod.IInputMethodClient;
|
import com.android.internal.inputmethod.IInputMethodClient;
|
||||||
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
|
import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
|
||||||
import com.android.internal.inputmethod.IRemoteInputConnection;
|
import com.android.internal.inputmethod.IRemoteInputConnection;
|
||||||
import com.android.internal.inputmethod.InputBindResult;
|
import com.android.internal.inputmethod.InputBindResult;
|
||||||
import com.android.internal.view.IImeTracker;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public interface to the global input method manager, used by all client
|
* Public interface to the global input method manager, used by all client
|
||||||
|
|||||||
@@ -24,13 +24,14 @@ import android.os.Binder;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.inputmethod.ImeTracker;
|
import android.view.inputmethod.ImeTracker;
|
||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
import com.android.internal.inputmethod.IImeTracker;
|
||||||
import com.android.internal.inputmethod.InputMethodDebug;
|
import com.android.internal.inputmethod.InputMethodDebug;
|
||||||
import com.android.internal.inputmethod.SoftInputShowHideReason;
|
import com.android.internal.inputmethod.SoftInputShowHideReason;
|
||||||
import com.android.internal.util.FrameworkStatsLog;
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.internal.view.IImeTracker;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -53,7 +54,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
@SuppressWarnings("GuardedBy")
|
@SuppressWarnings("GuardedBy")
|
||||||
public final class ImeTrackerService extends IImeTracker.Stub {
|
public final class ImeTrackerService extends IImeTracker.Stub {
|
||||||
|
|
||||||
static final String TAG = "ImeTrackerService";
|
private static final String TAG = ImeTracker.TAG;
|
||||||
|
|
||||||
/** The threshold in milliseconds after which a history entry is considered timed out. */
|
/** The threshold in milliseconds after which a history entry is considered timed out. */
|
||||||
private static final long TIMEOUT_MS = 10_000;
|
private static final long TIMEOUT_MS = 10_000;
|
||||||
@@ -71,67 +72,71 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public synchronized IBinder onRequestShow(int uid, @ImeTracker.Origin int origin,
|
public synchronized ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
|
||||||
@SoftInputShowHideReason int reason) {
|
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
|
||||||
final IBinder binder = new Binder();
|
final var binder = new Binder();
|
||||||
final History.Entry entry = new History.Entry(uid, ImeTracker.TYPE_SHOW,
|
final var token = new ImeTracker.Token(binder, tag);
|
||||||
ImeTracker.STATUS_RUN, origin, reason);
|
final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_SHOW, ImeTracker.STATUS_RUN,
|
||||||
|
origin, reason);
|
||||||
mHistory.addEntry(binder, entry);
|
mHistory.addEntry(binder, entry);
|
||||||
|
|
||||||
// Register a delayed task to handle the case where the new entry times out.
|
// Register a delayed task to handle the case where the new entry times out.
|
||||||
mHandler.postDelayed(() -> {
|
mHandler.postDelayed(() -> {
|
||||||
synchronized (ImeTrackerService.this) {
|
synchronized (ImeTrackerService.this) {
|
||||||
mHistory.setFinished(binder, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
|
mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
|
||||||
}
|
}
|
||||||
}, TIMEOUT_MS);
|
}, TIMEOUT_MS);
|
||||||
|
|
||||||
return binder;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public synchronized IBinder onRequestHide(int uid, @ImeTracker.Origin int origin,
|
public synchronized ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
|
||||||
@SoftInputShowHideReason int reason) {
|
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
|
||||||
final IBinder binder = new Binder();
|
final var binder = new Binder();
|
||||||
final History.Entry entry = new History.Entry(uid, ImeTracker.TYPE_HIDE,
|
final var token = new ImeTracker.Token(binder, tag);
|
||||||
ImeTracker.STATUS_RUN, origin, reason);
|
final var entry = new History.Entry(tag, uid, ImeTracker.TYPE_HIDE, ImeTracker.STATUS_RUN,
|
||||||
|
origin, reason);
|
||||||
mHistory.addEntry(binder, entry);
|
mHistory.addEntry(binder, entry);
|
||||||
|
|
||||||
// Register a delayed task to handle the case where the new entry times out.
|
// Register a delayed task to handle the case where the new entry times out.
|
||||||
mHandler.postDelayed(() -> {
|
mHandler.postDelayed(() -> {
|
||||||
synchronized (ImeTrackerService.this) {
|
synchronized (ImeTrackerService.this) {
|
||||||
mHistory.setFinished(binder, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
|
mHistory.setFinished(token, ImeTracker.STATUS_TIMEOUT, ImeTracker.PHASE_NOT_SET);
|
||||||
}
|
}
|
||||||
}, TIMEOUT_MS);
|
}, TIMEOUT_MS);
|
||||||
|
|
||||||
return binder;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onProgress(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
public synchronized void onProgress(@NonNull IBinder binder, @ImeTracker.Phase int phase) {
|
||||||
final History.Entry entry = mHistory.getEntry(statsToken);
|
final var entry = mHistory.getEntry(binder);
|
||||||
if (entry == null) return;
|
if (entry == null) return;
|
||||||
|
|
||||||
entry.mPhase = phase;
|
entry.mPhase = phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onFailed(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
public synchronized void onFailed(@NonNull ImeTracker.Token statsToken,
|
||||||
|
@ImeTracker.Phase int phase) {
|
||||||
mHistory.setFinished(statsToken, ImeTracker.STATUS_FAIL, phase);
|
mHistory.setFinished(statsToken, ImeTracker.STATUS_FAIL, phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onCancelled(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
|
public synchronized void onCancelled(@NonNull ImeTracker.Token statsToken,
|
||||||
|
@ImeTracker.Phase int phase) {
|
||||||
mHistory.setFinished(statsToken, ImeTracker.STATUS_CANCEL, phase);
|
mHistory.setFinished(statsToken, ImeTracker.STATUS_CANCEL, phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onShown(@NonNull IBinder statsToken) {
|
public synchronized void onShown(@NonNull ImeTracker.Token statsToken) {
|
||||||
mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
|
mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onHidden(@NonNull IBinder statsToken) {
|
public synchronized void onHidden(@NonNull ImeTracker.Token statsToken) {
|
||||||
mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
|
mHistory.setFinished(statsToken, ImeTracker.STATUS_SUCCESS, ImeTracker.PHASE_NOT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,9 +146,9 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
* @param statsToken the token corresponding to the current IME request.
|
* @param statsToken the token corresponding to the current IME request.
|
||||||
* @param requestWindowName the name of the window that created the IME request.
|
* @param requestWindowName the name of the window that created the IME request.
|
||||||
*/
|
*/
|
||||||
public synchronized void onImmsUpdate(@NonNull IBinder statsToken,
|
public synchronized void onImmsUpdate(@NonNull ImeTracker.Token statsToken,
|
||||||
@NonNull String requestWindowName) {
|
@NonNull String requestWindowName) {
|
||||||
final History.Entry entry = mHistory.getEntry(statsToken);
|
final var entry = mHistory.getEntry(statsToken.getBinder());
|
||||||
if (entry == null) return;
|
if (entry == null) return;
|
||||||
|
|
||||||
entry.mRequestWindowName = requestWindowName;
|
entry.mRequestWindowName = requestWindowName;
|
||||||
@@ -181,17 +186,17 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
/** Latest entry sequence number. */
|
/** Latest entry sequence number. */
|
||||||
private static final AtomicInteger sSequenceNumber = new AtomicInteger(0);
|
private static final AtomicInteger sSequenceNumber = new AtomicInteger(0);
|
||||||
|
|
||||||
/** Adds a live entry. */
|
/** Adds a live entry corresponding to the given IME tracking token's binder. */
|
||||||
@GuardedBy("ImeTrackerService.this")
|
@GuardedBy("ImeTrackerService.this")
|
||||||
private void addEntry(@NonNull IBinder statsToken, @NonNull Entry entry) {
|
private void addEntry(@NonNull IBinder binder, @NonNull Entry entry) {
|
||||||
mLiveEntries.put(statsToken, entry);
|
mLiveEntries.put(binder, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the entry corresponding to the given IME tracking token, if it exists. */
|
/** Gets the entry corresponding to the given IME tracking token's binder, if it exists. */
|
||||||
@Nullable
|
@Nullable
|
||||||
@GuardedBy("ImeTrackerService.this")
|
@GuardedBy("ImeTrackerService.this")
|
||||||
private Entry getEntry(@NonNull IBinder statsToken) {
|
private Entry getEntry(@NonNull IBinder binder) {
|
||||||
return mLiveEntries.get(statsToken);
|
return mLiveEntries.get(binder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,10 +209,21 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
* (or {@link ImeTracker#PHASE_NOT_SET} otherwise).
|
* (or {@link ImeTracker#PHASE_NOT_SET} otherwise).
|
||||||
*/
|
*/
|
||||||
@GuardedBy("ImeTrackerService.this")
|
@GuardedBy("ImeTrackerService.this")
|
||||||
private void setFinished(@NonNull IBinder statsToken, @ImeTracker.Status int status,
|
private void setFinished(@NonNull ImeTracker.Token statsToken,
|
||||||
@ImeTracker.Phase int phase) {
|
@ImeTracker.Status int status, @ImeTracker.Phase int phase) {
|
||||||
final Entry entry = mLiveEntries.remove(statsToken);
|
final var entry = mLiveEntries.remove(statsToken.getBinder());
|
||||||
if (entry == null) return;
|
if (entry == null) {
|
||||||
|
// This will be unconditionally called through the postDelayed above to handle
|
||||||
|
// potential timeouts, and is thus intentionally dropped to avoid having to manually
|
||||||
|
// save and remove the registered callback. Only timeout calls are expected.
|
||||||
|
if (status != ImeTracker.STATUS_TIMEOUT) {
|
||||||
|
Log.i(TAG, statsToken.getTag()
|
||||||
|
+ ": setFinished on previously finished token at "
|
||||||
|
+ ImeTracker.Debug.phaseToString(phase) + " with "
|
||||||
|
+ ImeTracker.Debug.statusToString(status));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
entry.mDuration = System.currentTimeMillis() - entry.mStartTime;
|
entry.mDuration = System.currentTimeMillis() - entry.mStartTime;
|
||||||
entry.mStatus = status;
|
entry.mStatus = status;
|
||||||
@@ -216,6 +232,13 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
entry.mPhase = phase;
|
entry.mPhase = phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status == ImeTracker.STATUS_TIMEOUT) {
|
||||||
|
// All events other than timeouts are already logged in the client-side ImeTracker.
|
||||||
|
Log.i(TAG, statsToken.getTag() + ": setFinished at "
|
||||||
|
+ ImeTracker.Debug.phaseToString(entry.mPhase) + " with "
|
||||||
|
+ ImeTracker.Debug.statusToString(status));
|
||||||
|
}
|
||||||
|
|
||||||
// Remove excess entries overflowing capacity (plus one for the new entry).
|
// Remove excess entries overflowing capacity (plus one for the new entry).
|
||||||
while (mEntries.size() >= CAPACITY) {
|
while (mEntries.size() >= CAPACITY) {
|
||||||
mEntries.remove();
|
mEntries.remove();
|
||||||
@@ -232,21 +255,22 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
/** Dumps the contents of the circular buffer. */
|
/** Dumps the contents of the circular buffer. */
|
||||||
@GuardedBy("ImeTrackerService.this")
|
@GuardedBy("ImeTrackerService.this")
|
||||||
private void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
|
private void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
|
||||||
final DateTimeFormatter formatter =
|
final var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
|
.withZone(ZoneId.systemDefault());
|
||||||
.withZone(ZoneId.systemDefault());
|
|
||||||
|
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.println("ImeTrackerService#History.mLiveEntries:");
|
pw.println("ImeTrackerService#History.mLiveEntries: "
|
||||||
|
+ mLiveEntries.size() + " elements");
|
||||||
|
|
||||||
for (final Entry entry: mLiveEntries.values()) {
|
for (final var entry: mLiveEntries.values()) {
|
||||||
dumpEntry(entry, pw, prefix, formatter);
|
dumpEntry(entry, pw, prefix, formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.println("ImeTrackerService#History.mEntries:");
|
pw.println("ImeTrackerService#History.mEntries: "
|
||||||
|
+ mEntries.size() + " elements");
|
||||||
|
|
||||||
for (final Entry entry: mEntries) {
|
for (final var entry: mEntries) {
|
||||||
dumpEntry(entry, pw, prefix, formatter);
|
dumpEntry(entry, pw, prefix, formatter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,34 +279,22 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
private void dumpEntry(@NonNull Entry entry, @NonNull PrintWriter pw,
|
private void dumpEntry(@NonNull Entry entry, @NonNull PrintWriter pw,
|
||||||
@NonNull String prefix, @NonNull DateTimeFormatter formatter) {
|
@NonNull String prefix, @NonNull DateTimeFormatter formatter) {
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.println("ImeTrackerService#History #" + entry.mSequenceNumber + ":");
|
pw.print(" #" + entry.mSequenceNumber);
|
||||||
|
pw.print(" " + ImeTracker.Debug.typeToString(entry.mType));
|
||||||
|
pw.print(" - " + ImeTracker.Debug.statusToString(entry.mStatus));
|
||||||
|
pw.print(" - " + entry.mTag);
|
||||||
|
pw.println(" (" + entry.mDuration + "ms):");
|
||||||
|
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.println(" startTime=" + formatter.format(Instant.ofEpochMilli(entry.mStartTime)));
|
pw.print(" startTime=" + formatter.format(Instant.ofEpochMilli(entry.mStartTime)));
|
||||||
|
pw.println(" " + ImeTracker.Debug.originToString(entry.mOrigin));
|
||||||
|
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.println(" duration=" + entry.mDuration + "ms");
|
pw.print(" reason=" + InputMethodDebug.softInputDisplayReasonToString(entry.mReason));
|
||||||
|
pw.println(" " + ImeTracker.Debug.phaseToString(entry.mPhase));
|
||||||
|
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.print(" type=" + ImeTracker.Debug.typeToString(entry.mType));
|
pw.println(" requestWindowName=" + entry.mRequestWindowName);
|
||||||
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print(" status=" + ImeTracker.Debug.statusToString(entry.mStatus));
|
|
||||||
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print(" origin="
|
|
||||||
+ ImeTracker.Debug.originToString(entry.mOrigin));
|
|
||||||
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print(" reason="
|
|
||||||
+ InputMethodDebug.softInputDisplayReasonToString(entry.mReason));
|
|
||||||
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print(" phase="
|
|
||||||
+ ImeTracker.Debug.phaseToString(entry.mPhase));
|
|
||||||
|
|
||||||
pw.print(prefix);
|
|
||||||
pw.print(" requestWindowName=" + entry.mRequestWindowName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A history entry. */
|
/** A history entry. */
|
||||||
@@ -291,6 +303,10 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
/** The entry's sequence number in the history. */
|
/** The entry's sequence number in the history. */
|
||||||
private final int mSequenceNumber = sSequenceNumber.getAndIncrement();
|
private final int mSequenceNumber = sSequenceNumber.getAndIncrement();
|
||||||
|
|
||||||
|
/** Logging tag, of the shape "component:random_hexadecimal". */
|
||||||
|
@NonNull
|
||||||
|
private final String mTag;
|
||||||
|
|
||||||
/** Uid of the client that requested the IME. */
|
/** Uid of the client that requested the IME. */
|
||||||
private final int mUid;
|
private final int mUid;
|
||||||
|
|
||||||
@@ -323,13 +339,15 @@ public final class ImeTrackerService extends IImeTracker.Stub {
|
|||||||
/**
|
/**
|
||||||
* Name of the window that created the IME request.
|
* Name of the window that created the IME request.
|
||||||
*
|
*
|
||||||
* Note: This is later set through {@link #onImmsUpdate(IBinder, String)}.
|
* Note: This is later set through {@link #onImmsUpdate}.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private String mRequestWindowName = "not set";
|
private String mRequestWindowName = "not set";
|
||||||
|
|
||||||
private Entry(int uid, @ImeTracker.Type int type, @ImeTracker.Status int status,
|
private Entry(@NonNull String tag, int uid, @ImeTracker.Type int type,
|
||||||
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
|
@ImeTracker.Status int status, @ImeTracker.Origin int origin,
|
||||||
|
@SoftInputShowHideReason int reason) {
|
||||||
|
mTag = tag;
|
||||||
mUid = uid;
|
mUid = uid;
|
||||||
mType = type;
|
mType = type;
|
||||||
mStatus = status;
|
mStatus = status;
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ import com.android.internal.content.PackageMonitor;
|
|||||||
import com.android.internal.infra.AndroidFuture;
|
import com.android.internal.infra.AndroidFuture;
|
||||||
import com.android.internal.inputmethod.DirectBootAwareness;
|
import com.android.internal.inputmethod.DirectBootAwareness;
|
||||||
import com.android.internal.inputmethod.IAccessibilityInputMethodSession;
|
import com.android.internal.inputmethod.IAccessibilityInputMethodSession;
|
||||||
|
import com.android.internal.inputmethod.IImeTracker;
|
||||||
import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback;
|
import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback;
|
||||||
import com.android.internal.inputmethod.IInputContentUriToken;
|
import com.android.internal.inputmethod.IInputContentUriToken;
|
||||||
import com.android.internal.inputmethod.IInputMethod;
|
import com.android.internal.inputmethod.IInputMethod;
|
||||||
@@ -168,7 +169,6 @@ import com.android.internal.os.TransferPipe;
|
|||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.internal.util.ConcurrentUtils;
|
import com.android.internal.util.ConcurrentUtils;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.internal.view.IImeTracker;
|
|
||||||
import com.android.internal.view.IInputMethodManager;
|
import com.android.internal.view.IInputMethodManager;
|
||||||
import com.android.server.AccessibilityManagerInternal;
|
import com.android.server.AccessibilityManagerInternal;
|
||||||
import com.android.server.EventLogTags;
|
import com.android.server.EventLogTags;
|
||||||
@@ -4715,7 +4715,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
|
|||||||
info.imeSurfaceParentName));
|
info.imeSurfaceParentName));
|
||||||
|
|
||||||
if (statsToken != null) {
|
if (statsToken != null) {
|
||||||
mImeTrackerService.onImmsUpdate(statsToken.mBinder, info.requestWindowName);
|
mImeTrackerService.onImmsUpdate(statsToken, info.requestWindowName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user