Add logs for ImeTrackerService#History#setFinished

This enables tracking which token timed out.

Bug: 269089722
Test: Open Keyboard in any app, observe logcat for new log entries, manually decrease timeout threshold
Change-Id: I3e3bc09765871b7d71975df4692351be8ace462e
This commit is contained in:
Cosmin Băieș
2023-01-11 17:21:31 +01:00
parent c83f836674
commit 136bb67be4
5 changed files with 166 additions and 111 deletions

View File

@@ -25,6 +25,7 @@ import android.annotation.RequiresNoPermission;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -547,51 +548,57 @@ final class IInputMethodManagerGlobalInvoker {
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onRequestShow */
@AnyThread
@Nullable
static IBinder onRequestShow(int uid, @ImeTracker.Origin int origin,
@SoftInputShowHideReason int reason) {
@NonNull
static ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
final IImeTracker service = getImeTrackerService();
if (service == null) {
return null;
// Create token with "fake" binder if the service was not found.
return new ImeTracker.Token(new Binder(), tag);
}
try {
return service.onRequestShow(uid, origin, reason);
return service.onRequestShow(tag, uid, origin, reason);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onRequestHide */
@AnyThread
@Nullable
static IBinder onRequestHide(int uid, @ImeTracker.Origin int origin,
@SoftInputShowHideReason int reason) {
@NonNull
static ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
final IImeTracker service = getImeTrackerService();
if (service == null) {
return null;
// Create token with "fake" binder if the service was not found.
return new ImeTracker.Token(new Binder(), tag);
}
try {
return service.onRequestHide(uid, origin, reason);
return service.onRequestHide(tag, uid, origin, reason);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onProgress */
@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();
if (service == null) {
return;
}
try {
service.onProgress(statsToken, phase);
service.onProgress(binder, phase);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onFailed */
@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();
if (service == null) {
return;
@@ -603,8 +610,9 @@ final class IInputMethodManagerGlobalInvoker {
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onCancelled */
@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();
if (service == null) {
return;
@@ -616,8 +624,9 @@ final class IInputMethodManagerGlobalInvoker {
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onShown */
@AnyThread
static void onShown(@NonNull IBinder statsToken) {
static void onShown(@NonNull ImeTracker.Token statsToken) {
final IImeTracker service = getImeTrackerService();
if (service == null) {
return;
@@ -629,8 +638,9 @@ final class IInputMethodManagerGlobalInvoker {
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#onHidden */
@AnyThread
static void onHidden(@NonNull IBinder statsToken) {
static void onHidden(@NonNull ImeTracker.Token statsToken) {
final IImeTracker service = getImeTrackerService();
if (service == null) {
return;
@@ -642,6 +652,7 @@ final class IInputMethodManagerGlobalInvoker {
}
}
/** @see com.android.server.inputmethod.ImeTrackerService#hasPendingImeVisibilityRequests */
@AnyThread
@RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
static boolean hasPendingImeVisibilityRequests() {

View File

@@ -26,7 +26,6 @@ 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;
@@ -47,7 +46,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
/** @hide */
@@ -321,9 +320,8 @@ public interface ImeTracker {
/**
* Creates an IME show request tracking token.
*
* @param component the component name where the IME show request was created,
* or {@code null} otherwise
* (defaulting to {@link ActivityThread#currentProcessName()}).
* @param component the component name where the IME request was created, or {@code null}
* otherwise (defaulting to {@link ActivityThread#currentProcessName()}).
* @param uid the uid of the client that requested the IME.
* @param origin the origin of the IME show request.
* @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.
*
* @param component the component name where the IME hide request was created,
* or {@code null} otherwise
* (defaulting to {@link ActivityThread#currentProcessName()}).
* @param component the component name where the IME request was created, or {@code null}
* otherwise (defaulting to {@link ActivityThread#currentProcessName()}).
* @param uid the uid of the client that requested the IME.
* @param origin the origin of the IME hide request.
* @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);
// Update logging flag dynamically.
SystemProperties.addChangeCallback(() ->
mLogProgress =
SystemProperties.getBoolean("persist.debug.imetracker", false));
mLogProgress = SystemProperties.getBoolean("persist.debug.imetracker", false));
}
/** Whether progress should be logged. */
@@ -446,10 +442,9 @@ public interface ImeTracker {
@Override
public Token onRequestShow(@Nullable String component, int uid, @Origin int origin,
@SoftInputShowHideReason int reason) {
IBinder binder = IInputMethodManagerGlobalInvoker.onRequestShow(uid, origin, reason);
if (binder == null) binder = new Binder();
final Token token = Token.build(binder, component);
final var tag = getTag(component);
final var token = IInputMethodManagerGlobalInvoker.onRequestShow(tag, uid, origin,
reason);
Log.i(TAG, token.mTag + ": onRequestShow at " + Debug.originToString(origin)
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
@@ -461,10 +456,9 @@ public interface ImeTracker {
@Override
public Token onRequestHide(@Nullable String component, int uid, @Origin int origin,
@SoftInputShowHideReason int reason) {
IBinder binder = IInputMethodManagerGlobalInvoker.onRequestHide(uid, origin, reason);
if (binder == null) binder = new Binder();
final Token token = Token.build(binder, component);
final var tag = getTag(component);
final var token = IInputMethodManagerGlobalInvoker.onRequestHide(tag, uid, origin,
reason);
Log.i(TAG, token.mTag + ": onRequestHide at " + Debug.originToString(origin)
+ " reason " + InputMethodDebug.softInputDisplayReasonToString(reason));
@@ -485,7 +479,7 @@ public interface ImeTracker {
@Override
public void onFailed(@Nullable Token token, @Phase int phase) {
if (token == null) return;
IInputMethodManagerGlobalInvoker.onFailed(token.mBinder, phase);
IInputMethodManagerGlobalInvoker.onFailed(token, phase);
Log.i(TAG, token.mTag + ": onFailed at " + Debug.phaseToString(phase));
}
@@ -499,7 +493,7 @@ public interface ImeTracker {
@Override
public void onCancelled(@Nullable Token token, @Phase int phase) {
if (token == null) return;
IInputMethodManagerGlobalInvoker.onCancelled(token.mBinder, phase);
IInputMethodManagerGlobalInvoker.onCancelled(token, phase);
Log.i(TAG, token.mTag + ": onCancelled at " + Debug.phaseToString(phase));
}
@@ -507,7 +501,7 @@ public interface ImeTracker {
@Override
public void onShown(@Nullable Token token) {
if (token == null) return;
IInputMethodManagerGlobalInvoker.onShown(token.mBinder);
IInputMethodManagerGlobalInvoker.onShown(token);
Log.i(TAG, token.mTag + ": onShown");
}
@@ -515,10 +509,24 @@ public interface ImeTracker {
@Override
public void onHidden(@Nullable Token token) {
if (token == null) return;
IInputMethodManagerGlobalInvoker.onHidden(token.mBinder);
IInputMethodManagerGlobalInvoker.onHidden(token);
Log.i(TAG, token.mTag + ": onHidden");
}
/**
* Returns a logging tag using the given component name.
*
* @param component the component name where the IME request was created, 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. */
@@ -528,28 +536,31 @@ public interface ImeTracker {
ImeLatencyTracker LATENCY_TRACKER = new ImeLatencyTracker();
/** 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
public final IBinder mBinder;
private final IBinder mBinder;
/** The logging tag. */
@NonNull
private final String mTag;
@NonNull
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) {
public Token(@NonNull IBinder binder, @NonNull String tag) {
mBinder = binder;
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
public String getTag() {
return mTag;
@@ -562,7 +573,7 @@ public interface ImeTracker {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeStrongBinder(mBinder);
dest.writeString8(mTag);
}
@@ -571,12 +582,11 @@ public interface ImeTracker {
public static final Creator<Token> CREATOR = new Creator<>() {
@NonNull
@Override
public Token createFromParcel(Parcel source) {
final IBinder binder = source.readStrongBinder();
final String tag = source.readString8();
return new Token(binder, tag);
public Token createFromParcel(@NonNull Parcel in) {
return new Token(in);
}
@NonNull
@Override
public Token[] newArray(int 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.
*/
class Debug {
final class Debug {
@NonNull
private static final Map<Integer, String> sTypes =
getFieldMapping(ImeTracker.class, "TYPE_");
@NonNull
private static final Map<Integer, String> sStatus =
getFieldMapping(ImeTracker.class, "STATUS_");
@NonNull
private static final Map<Integer, String> sOrigins =
getFieldMapping(ImeTracker.class, "ORIGIN_");
@NonNull
private static final Map<Integer, String> sPhases =
getFieldMapping(ImeTracker.class, "PHASE_");
@NonNull
public static String typeToString(@Type int type) {
return sTypes.getOrDefault(type, "TYPE_" + type);
}
@NonNull
public static String statusToString(@Status int status) {
return sStatus.getOrDefault(status, "STATUS_" + status);
}
@NonNull
public static String originToString(@Origin int origin) {
return sOrigins.getOrDefault(origin, "ORIGIN_" + origin);
}
@NonNull
public static String phaseToString(@Phase int 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())
.filter(field -> field.getName().startsWith(fieldPrefix))
.collect(Collectors.toMap(Debug::getFieldValue, Field::getName));
}
private static int getFieldValue(Field field) {
private static int getFieldValue(@NonNull Field field) {
try {
return field.getInt(null);
} catch (IllegalAccessException e) {

View File

@@ -19,38 +19,40 @@ package com.android.internal.view;
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}
*/
interface IImeTracker {
/**
* Called when an IME show request is created,
* returns a new Binder to be associated with the IME tracking token.
* Called when an IME show request is created.
*
* @param tag the logging tag.
* @param uid the uid of the client that requested the IME.
* @param origin the origin of the IME show request.
* @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,
* returns a new Binder to be associated with the IME tracking token.
* Called when an IME hide request is created.
*
* @param tag the logging tag.
* @param uid the uid of the client that requested the IME.
* @param origin the origin of the IME hide request.
* @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.
*
* @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.
*/
oneway void onProgress(in IBinder statsToken, int phase);
oneway void onProgress(in IBinder binder, int phase);
/**
* Called when the IME request fails.
@@ -58,7 +60,7 @@ interface IImeTracker {
* @param statsToken the token tracking the current IME request.
* @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.
@@ -66,21 +68,21 @@ interface IImeTracker {
* @param statsToken the token tracking the current IME request.
* @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.
*
* @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.
*
* @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.

View File

@@ -24,6 +24,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.inputmethod.ImeTracker;
import com.android.internal.annotations.GuardedBy;
@@ -53,7 +54,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@SuppressWarnings("GuardedBy")
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. */
private static final long TIMEOUT_MS = 10_000;
@@ -71,67 +72,71 @@ public final class ImeTrackerService extends IImeTracker.Stub {
@NonNull
@Override
public synchronized IBinder onRequestShow(int uid, @ImeTracker.Origin int origin,
@SoftInputShowHideReason int reason) {
final IBinder binder = new Binder();
final History.Entry entry = new History.Entry(uid, ImeTracker.TYPE_SHOW,
ImeTracker.STATUS_RUN, origin, reason);
public synchronized ImeTracker.Token onRequestShow(@NonNull String tag, int uid,
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
final var binder = new Binder();
final var token = new ImeTracker.Token(binder, tag);
final var entry = new History.Entry(uid, ImeTracker.TYPE_SHOW, ImeTracker.STATUS_RUN,
origin, reason);
mHistory.addEntry(binder, entry);
// Register a delayed task to handle the case where the new entry times out.
mHandler.postDelayed(() -> {
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);
return binder;
return token;
}
@NonNull
@Override
public synchronized IBinder onRequestHide(int uid, @ImeTracker.Origin int origin,
@SoftInputShowHideReason int reason) {
final IBinder binder = new Binder();
final History.Entry entry = new History.Entry(uid, ImeTracker.TYPE_HIDE,
ImeTracker.STATUS_RUN, origin, reason);
public synchronized ImeTracker.Token onRequestHide(@NonNull String tag, int uid,
@ImeTracker.Origin int origin, @SoftInputShowHideReason int reason) {
final var binder = new Binder();
final var token = new ImeTracker.Token(binder, tag);
final var entry = new History.Entry(uid, ImeTracker.TYPE_HIDE, ImeTracker.STATUS_RUN,
origin, reason);
mHistory.addEntry(binder, entry);
// Register a delayed task to handle the case where the new entry times out.
mHandler.postDelayed(() -> {
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);
return binder;
return token;
}
@Override
public synchronized void onProgress(@NonNull IBinder statsToken, @ImeTracker.Phase int phase) {
final History.Entry entry = mHistory.getEntry(statsToken);
public synchronized void onProgress(@NonNull IBinder binder, @ImeTracker.Phase int phase) {
final var entry = mHistory.getEntry(binder);
if (entry == null) return;
entry.mPhase = phase;
}
@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);
}
@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);
}
@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);
}
@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);
}
@@ -141,9 +146,9 @@ public final class ImeTrackerService extends IImeTracker.Stub {
* @param statsToken the token corresponding to the current 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) {
final History.Entry entry = mHistory.getEntry(statsToken);
final var entry = mHistory.getEntry(statsToken.getBinder());
if (entry == null) return;
entry.mRequestWindowName = requestWindowName;
@@ -181,17 +186,17 @@ public final class ImeTrackerService extends IImeTracker.Stub {
/** Latest entry sequence number. */
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")
private void addEntry(@NonNull IBinder statsToken, @NonNull Entry entry) {
mLiveEntries.put(statsToken, entry);
private void addEntry(@NonNull IBinder binder, @NonNull Entry 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
@GuardedBy("ImeTrackerService.this")
private Entry getEntry(@NonNull IBinder statsToken) {
return mLiveEntries.get(statsToken);
private Entry getEntry(@NonNull IBinder binder) {
return mLiveEntries.get(binder);
}
/**
@@ -204,10 +209,21 @@ public final class ImeTrackerService extends IImeTracker.Stub {
* (or {@link ImeTracker#PHASE_NOT_SET} otherwise).
*/
@GuardedBy("ImeTrackerService.this")
private void setFinished(@NonNull IBinder statsToken, @ImeTracker.Status int status,
@ImeTracker.Phase int phase) {
final Entry entry = mLiveEntries.remove(statsToken);
if (entry == null) return;
private void setFinished(@NonNull ImeTracker.Token statsToken,
@ImeTracker.Status int status, @ImeTracker.Phase int phase) {
final var entry = mLiveEntries.remove(statsToken.getBinder());
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.mStatus = status;
@@ -216,6 +232,13 @@ public final class ImeTrackerService extends IImeTracker.Stub {
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).
while (mEntries.size() >= CAPACITY) {
mEntries.remove();
@@ -232,21 +255,20 @@ public final class ImeTrackerService extends IImeTracker.Stub {
/** Dumps the contents of the circular buffer. */
@GuardedBy("ImeTrackerService.this")
private void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
.withZone(ZoneId.systemDefault());
final var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
.withZone(ZoneId.systemDefault());
pw.print(prefix);
pw.println("ImeTrackerService#History.mLiveEntries:");
for (final Entry entry: mLiveEntries.values()) {
for (final var entry: mLiveEntries.values()) {
dumpEntry(entry, pw, prefix, formatter);
}
pw.print(prefix);
pw.println("ImeTrackerService#History.mEntries:");
for (final Entry entry: mEntries) {
for (final var entry: mEntries) {
dumpEntry(entry, pw, prefix, formatter);
}
}
@@ -323,7 +345,7 @@ public final class ImeTrackerService extends IImeTracker.Stub {
/**
* 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
private String mRequestWindowName = "not set";

View File

@@ -4629,7 +4629,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
info.imeSurfaceParentName));
if (statsToken != null) {
mImeTrackerService.onImmsUpdate(statsToken.mBinder, info.requestWindowName);
mImeTrackerService.onImmsUpdate(statsToken, info.requestWindowName);
}
}