Improved autofill logging and dumping.
Bug: 76027553
Test: adb shell dumpsys autofill
Change-Id: I19ef88c71334c62292ed982e43d7a7e89b35f10e
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index f32dee1..ccec483 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -149,24 +149,33 @@
public String toString() {
if (!sDebug) return super.toString();
- final StringBuilder builder = new StringBuilder("Dataset[id=");
+ final StringBuilder builder = new StringBuilder("Dataset[");
if (mId == null) {
- builder.append("null");
+ builder.append("noId");
} else {
// Cannot disclose id because it could contain PII.
- builder.append(mId.length()).append("_chars");
+ builder.append("id=").append(mId.length()).append("_chars");
}
+ if (mFieldIds != null) {
+ builder.append(", fieldIds=").append(mFieldIds);
+ }
+ if (mFieldValues != null) {
+ builder.append(", fieldValues=").append(mFieldValues);
+ }
+ if (mFieldPresentations != null) {
+ builder.append(", fieldPresentations=").append(mFieldPresentations.size());
- return builder
- .append(", fieldIds=").append(mFieldIds)
- .append(", fieldValues=").append(mFieldValues)
- .append(", fieldPresentations=")
- .append(mFieldPresentations == null ? 0 : mFieldPresentations.size())
- .append(", fieldFilters=")
- .append(mFieldFilters == null ? 0 : mFieldFilters.size())
- .append(", hasPresentation=").append(mPresentation != null)
- .append(", hasAuthentication=").append(mAuthentication != null)
- .append(']').toString();
+ }
+ if (mFieldFilters != null) {
+ builder.append(", fieldFilters=").append(mFieldFilters.size());
+ }
+ if (mPresentation != null) {
+ builder.append(", hasPresentation");
+ }
+ if (mAuthentication != null) {
+ builder.append(", hasAuthentication");
+ }
+ return builder.append(']').toString();
}
/**
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 3a4b6bb..25239b6 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -554,23 +554,40 @@
if (!sDebug) return super.toString();
// TODO: create a dump() method instead
- return new StringBuilder(
- "FillResponse : [mRequestId=" + mRequestId)
- .append(", datasets=").append(mDatasets == null ? "N/A" : mDatasets.getList())
- .append(", saveInfo=").append(mSaveInfo)
- .append(", clientState=").append(mClientState != null)
- .append(", hasPresentation=").append(mPresentation != null)
- .append(", hasHeader=").append(mHeader != null)
- .append(", hasFooter=").append(mFooter != null)
- .append(", hasAuthentication=").append(mAuthentication != null)
- .append(", authenticationIds=").append(Arrays.toString(mAuthenticationIds))
- .append(", ignoredIds=").append(Arrays.toString(mIgnoredIds))
- .append(", disableDuration=").append(mDisableDuration)
- .append(", flags=").append(mFlags)
- .append(", fieldClassificationIds=")
- .append(Arrays.toString(mFieldClassificationIds))
- .append("]")
- .toString();
+ final StringBuilder builder = new StringBuilder(
+ "FillResponse : [mRequestId=" + mRequestId);
+ if (mDatasets != null) {
+ builder.append(", datasets=").append(mDatasets.getList());
+ }
+ if (mSaveInfo != null) {
+ builder.append(", saveInfo=").append(mSaveInfo);
+ }
+ if (mClientState != null) {
+ builder.append(", hasClientState");
+ }
+ if (mPresentation != null) {
+ builder.append(", hasPresentation");
+ }
+ if (mHeader != null) {
+ builder.append(", hasHeader");
+ }
+ if (mFooter != null) {
+ builder.append(", hasFooter");
+ }
+ if (mAuthentication != null) {
+ builder.append(", hasAuthentication");
+ }
+ if (mAuthenticationIds != null) {
+ builder.append(", authenticationIds=").append(Arrays.toString(mAuthenticationIds));
+ }
+ builder.append(", disableDuration=").append(mDisableDuration);
+ if (mFlags != 0) {
+ builder.append(", flags=").append(mFlags);
+ }
+ if (mFieldClassificationIds != null) {
+ builder.append(Arrays.toString(mFieldClassificationIds));
+ }
+ return builder.append("]").toString();
}
/////////////////////////////////////
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index a5a6177..d3067a9 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -699,22 +699,37 @@
public String toString() {
if (!sDebug) return super.toString();
- return new StringBuilder("SaveInfo: [type=")
+ final StringBuilder builder = new StringBuilder("SaveInfo: [type=")
.append(DebugUtils.flagsToString(SaveInfo.class, "SAVE_DATA_TYPE_", mType))
.append(", requiredIds=").append(Arrays.toString(mRequiredIds))
- .append(", optionalIds=").append(Arrays.toString(mOptionalIds))
- .append(", description=").append(mDescription)
- .append(DebugUtils.flagsToString(SaveInfo.class, "NEGATIVE_BUTTON_STYLE_",
- mNegativeButtonStyle))
- .append(", flags=").append(mFlags)
- .append(", customDescription=").append(mCustomDescription)
- .append(", validator=").append(mValidator)
- .append(", sanitizerKeys=")
- .append(mSanitizerKeys == null ? "N/A:" : mSanitizerKeys.length)
- .append(", sanitizerValues=")
- .append(mSanitizerValues == null ? "N/A:" : mSanitizerValues.length)
- .append(", triggerId=").append(mTriggerId)
- .append("]").toString();
+ .append(", style=").append(DebugUtils.flagsToString(SaveInfo.class,
+ "NEGATIVE_BUTTON_STYLE_", mNegativeButtonStyle));
+ if (mOptionalIds != null) {
+ builder.append(", optionalIds=").append(Arrays.toString(mOptionalIds));
+ }
+ if (mDescription != null) {
+ builder.append(", description=").append(mDescription);
+ }
+ if (mFlags != 0) {
+ builder.append(", flags=").append(mFlags);
+ }
+ if (mCustomDescription != null) {
+ builder.append(", customDescription=").append(mCustomDescription);
+ }
+ if (mValidator != null) {
+ builder.append(", validator=").append(mValidator);
+ }
+ if (mSanitizerKeys != null) {
+ builder.append(", sanitizerKeys=").append(mSanitizerKeys.length);
+ }
+ if (mSanitizerValues != null) {
+ builder.append(", sanitizerValues=").append(mSanitizerValues.length);
+ }
+ if (mTriggerId != null) {
+ builder.append(", triggerId=").append(mTriggerId);
+ }
+
+ return builder.append("]").toString();
}
/////////////////////////////////////
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 69938cb..abc19d0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2882,9 +2882,8 @@
/**
* @hide
*/
- public String toString(String prefix) {
- StringBuilder sb = new StringBuilder(256);
- sb.append("{(");
+ public void dumpDimensions(StringBuilder sb) {
+ sb.append('(');
sb.append(x);
sb.append(',');
sb.append(y);
@@ -2895,6 +2894,15 @@
sb.append((height == MATCH_PARENT ? "fill" : (height == WRAP_CONTENT
? "wrap" : String.valueOf(height))));
sb.append(")");
+ }
+
+ /**
+ * @hide
+ */
+ public String toString(String prefix) {
+ StringBuilder sb = new StringBuilder(256);
+ sb.append('{');
+ dumpDimensions(sb);
if (horizontalMargin != 0) {
sb.append(" hm=");
sb.append(horizontalMargin);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 7409ec2..4d66674 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -80,6 +80,7 @@
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.autofill.AutofillManagerService.PackageCompatState;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.FileDescriptor;
@@ -655,7 +656,7 @@
/**
* Compatibility mode metadata per package.
*/
- private static final class PackageCompatState {
+ static final class PackageCompatState {
private final long maxVersionCode;
private final String[] urlBarResourceIds;
@@ -666,8 +667,8 @@
@Override
public String toString() {
- return "PackageCompatState: [maxVersionCode=" + maxVersionCode
- + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds) + "]";
+ return "maxVersionCode=" + maxVersionCode
+ + ", urlBarResourceIds=" + Arrays.toString(urlBarResourceIds);
}
}
@@ -756,6 +757,25 @@
}
}
}
+
+ private void dump(String prefix, PrintWriter pw) {
+ if (mUserSpecs == null) {
+ pw.println("N/A");
+ return;
+ }
+ pw.println();
+ final String prefix2 = prefix + " ";
+ for (int i = 0; i < mUserSpecs.size(); i++) {
+ final int user = mUserSpecs.keyAt(i);
+ pw.print(prefix); pw.print("User: "); pw.println(user);
+ final ArrayMap<String,PackageCompatState> perUser = mUserSpecs.get(i);
+ for (int j = 0; j < perUser.size(); j++) {
+ final String packageName = perUser.keyAt(j);
+ final PackageCompatState state = perUser.valueAt(j);
+ pw.print(prefix2); pw.print(packageName); pw.print(": "); pw.println(state);
+ }
+ }
+ }
}
final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
@@ -1121,6 +1141,7 @@
boolean oldDebug = sDebug;
final String prefix = " ";
+ final String prefix2 = " ";
try {
synchronized (mLock) {
oldDebug = sDebug;
@@ -1145,8 +1166,8 @@
}
mUi.dump(pw);
pw.print("Autofill Compat State: ");
- pw.println(mAutofillCompatState.mUserSpecs);
- pw.print(prefix); pw.print("from settings: ");
+ mAutofillCompatState.dump(prefix2, pw);
+ pw.print(prefix2); pw.print("from settings: ");
pw.println(getWhitelistedCompatModePackagesFromSettings());
}
if (showHistory) {
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 5c41f3f..7bb532e 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -26,6 +26,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
+import android.view.WindowManager;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
@@ -107,6 +108,13 @@
}
@NonNull
+ public static String paramsToString(@NonNull WindowManager.LayoutParams params) {
+ final StringBuilder builder = new StringBuilder(25);
+ params.dumpDimensions(builder);
+ return builder.toString();
+ }
+
+ @NonNull
static ArrayMap<AutofillId, AutofillValue> getFields(@NonNull Dataset dataset) {
final ArrayList<AutofillId> ids = dataset.getFieldIds();
final ArrayList<AutofillValue> values = dataset.getFieldValues();
@@ -128,7 +136,7 @@
return log;
}
- public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable String text) {
+ public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable CharSequence text) {
if (text == null) {
pw.println("null");
} else {
@@ -173,6 +181,7 @@
* @param structure Assist structure
* @param urlBarIds list of ids; only the first id found will be sanitized.
*/
+ @Nullable
public static void sanitizeUrlBar(@NonNull AssistStructure structure,
@NonNull String[] urlBarIds) {
final ViewNode urlBarNode = findViewNode(structure, (node) -> {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 0dbdc13..03c5850 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -206,29 +206,51 @@
@Override
public String toString() {
- return "ViewState: [id=" + id + ", datasetId=" + mDatasetId
- + ", currentValue=" + mCurrentValue
- + ", autofilledValue=" + mAutofilledValue
- + ", bounds=" + mVirtualBounds + ", state=" + getStateAsString() + "]";
+ final StringBuilder builder = new StringBuilder("ViewState: [id=").append(id);
+ if (mDatasetId != null) {
+ builder.append("datasetId:" ).append(mDatasetId);
+ }
+ builder.append("state:" ).append(getStateAsString());
+ if (mCurrentValue != null) {
+ builder.append("currentValue:" ).append(mCurrentValue);
+ }
+ if (mAutofilledValue != null) {
+ builder.append("autofilledValue:" ).append(mAutofilledValue);
+ }
+ if (mSanitizedValue != null) {
+ builder.append("sanitizedValue:" ).append(mSanitizedValue);
+ }
+ if (mVirtualBounds != null) {
+ builder.append("virtualBounds:" ).append(mVirtualBounds);
+ }
+ return builder.toString();
}
void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("id:" ); pw.println(this.id);
- pw.print(prefix); pw.print("datasetId:" ); pw.println(this.mDatasetId);
+ pw.print(prefix); pw.print("id:" ); pw.println(id);
+ if (mDatasetId != null) {
+ pw.print(prefix); pw.print("datasetId:" ); pw.println(mDatasetId);
+ }
pw.print(prefix); pw.print("state:" ); pw.println(getStateAsString());
- pw.print(prefix); pw.print("response:");
- if (mResponse == null) {
- pw.println("N/A");
- } else {
+ if (mResponse != null) {
+ pw.print(prefix); pw.print("response:");
if (sVerbose) {
pw.println(mResponse);
} else {
- pw.println(mResponse.getRequestId());
+ pw.print("id=");pw.println(mResponse.getRequestId());
}
}
- pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue);
- pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue);
- pw.print(prefix); pw.print("sanitizedValue:" ); pw.println(mSanitizedValue);
- pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);
+ if (mCurrentValue != null) {
+ pw.print(prefix); pw.print("currentValue:" ); pw.println(mCurrentValue);
+ }
+ if (mAutofilledValue != null) {
+ pw.print(prefix); pw.print("autofilledValue:" ); pw.println(mAutofilledValue);
+ }
+ if (mSanitizedValue != null) {
+ pw.print(prefix); pw.print("sanitizedValue:" ); pw.println(mSanitizedValue);
+ }
+ if (mVirtualBounds != null) {
+ pw.print(prefix); pw.print("virtualBounds:" ); pw.println(mVirtualBounds);
+ }
}
}
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index ef4656b..edfc412 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -15,6 +15,7 @@
*/
package com.android.server.autofill.ui;
+import static com.android.server.autofill.Helper.paramsToString;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
@@ -37,7 +38,6 @@
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
@@ -568,12 +568,24 @@
@Override
public String toString() {
- return "ViewItem: [dataset=" + (dataset == null ? "null" : dataset.getId())
- + ", value=" + (value == null ? "null" : value.length() + "_chars")
- + ", filterable=" + filterable
- + ", filter=" + (filter == null ? "null" : filter.pattern().length() + "_chars")
- + ", view=" + view.getAutofillId()
- + "]";
+ final StringBuilder builder = new StringBuilder("ViewItem:[view=")
+ .append(view.getAutofillId());
+ final String datasetId = dataset == null ? null : dataset.getId();
+ if (datasetId != null) {
+ builder.append(", dataset=").append(datasetId);
+ }
+ if (value != null) {
+ // Cannot print value because it could contain PII
+ builder.append(", value=").append(value.length()).append("_chars");
+ }
+ if (filterable) {
+ builder.append(", filterable");
+ }
+ if (filter != null) {
+ // Filter should not have PII, but it could be a huge regexp
+ builder.append(", filter=").append(filter.pattern().length()).append("_chars");
+ }
+ return builder.append(']').toString();
}
}
@@ -583,8 +595,7 @@
boolean fitsSystemWindows, int layoutDirection) {
if (sVerbose) {
Slog.v(TAG, "AutofillWindowPresenter.show(): fit=" + fitsSystemWindows
- + ", epicenter="+ transitionEpicenter + ", dir=" + layoutDirection
- + ", params=" + p);
+ + ", params=" + paramsToString(p));
}
UiThread.getHandler().post(() -> mWindow.show(p));
}
@@ -616,7 +627,9 @@
* Shows the window.
*/
public void show(WindowManager.LayoutParams params) {
- if (sVerbose) Slog.v(TAG, "show(): showing=" + mShowing + ", params="+ params);
+ if (sVerbose) {
+ Slog.v(TAG, "show(): showing=" + mShowing + ", params=" + paramsToString(params));
+ }
try {
// Okay here is a bit of voodoo - we want to show the window as system
// controlled one so it covers app windows - adjust the params accordingly.