Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bca61d7f authored by Felipe Leme's avatar Felipe Leme
Browse files

Final (?!?!?!) improvements on Activity.dump()

- Fix handle of special args (they were not called unless the app
  targeted T).
- Lazy-adds some dumpables to Activity (so the list of dumpables
  is not created until dump() is called).

Test: adb shell am start com.android.settings && adb shell dumpsys activity com.android.settings --list-dumpables
Test: atest CtsAppTestCases:android.app.cts.ActivityDumpTest

Bug: 149254050

Change-Id: Id25d115d4aef8ab16ceb3d035c134c637e16dadd
parent badac481
Loading
Loading
Loading
Loading
+43 −20
Original line number Diff line number Diff line
@@ -7204,43 +7204,67 @@ public class Activity extends ContextThemeWrapper
    public void dumpInternal(@NonNull String prefix,
            @SuppressLint("UseParcelFileDescriptor") @Nullable FileDescriptor fd,
            @NonNull PrintWriter writer, @Nullable String[] args) {
        if (args != null && args.length > 0
                && CompatChanges.isChangeEnabled(DUMP_IGNORES_SPECIAL_ARGS)) {

        // Lazy-load mDumpableContainer with Dumpables activity might already have a reference to
        if (mAutofillClientController != null) {
            addDumpable(mAutofillClientController);
        }
        if (mUiTranslationController != null) {
            addDumpable(mUiTranslationController);
        }
        if (mContentCaptureManager != null) {
            mContentCaptureManager.addDumpable(this);
        }

        boolean dumpInternalState = true;
        String arg = null;
        if (args != null && args.length > 0) {
            arg = args[0];
            boolean isSpecialCase = true;
            // Handle special cases
            switch (args[0]) {
            switch (arg) {
                case "--autofill":
                    dumpAutofillManager(prefix, writer, args);
                    return;
                    break;
                case "--contentcapture":
                    dumpContentCaptureManager(prefix, writer);
                    return;
                    break;
                case "--translation":
                    dumpUiTranslation(prefix, writer);
                    return;
                    break;
                case "--list-dumpables":
                    if (mDumpableContainer == null) {
                        writer.print(prefix); writer.println("No dumpables");
                        return;
                    }
                    } else {
                        mDumpableContainer.listDumpables(prefix, writer);
                    return;
                    }
                    break;
                case "--dump-dumpable":
                    if (args.length == 1) {
                        writer.println("--dump-dumpable requires the dumpable name");
                        return;
                    }
                    if (mDumpableContainer == null) {
                    } else if (mDumpableContainer == null) {
                        writer.println("no dumpables");
                        return;
                    }
                    } else {
                        // Strips --dump-dumpable NAME
                        String[] prunedArgs = new String[args.length - 2];
                        System.arraycopy(args, 2, prunedArgs, 0, prunedArgs.length);
                        mDumpableContainer.dumpOneDumpable(prefix, writer, args[1], prunedArgs);
                    return;
                    }
                    break;
                default:
                    isSpecialCase = false;
                    break;
            }
            if (isSpecialCase) {
                dumpInternalState = !CompatChanges.isChangeEnabled(DUMP_IGNORES_SPECIAL_ARGS);
            }
        }

        if (dumpInternalState) {
            dump(prefix, fd, writer, args);
        } else {
            Log.i(TAG, "Not calling dump() on " + this + " because of special argument " + arg);
        }
    }

    void dumpInner(@NonNull String prefix, @Nullable FileDescriptor fd,
@@ -7285,7 +7309,6 @@ public class Activity extends ContextThemeWrapper
    }

    private void dumpContentCaptureManager(String prefix, PrintWriter writer) {
        getContentCaptureManager();
        dumpLegacyDumpable(prefix, writer, ContentCaptureManager.DUMPABLE_NAME, /* args= */ null);
    }

+0 −1
Original line number Diff line number Diff line
@@ -76,7 +76,6 @@ public final class AutofillClientController implements AutofillManager.AutofillC
     */
    public AutofillClientController(Activity activity) {
        mActivity = activity;
        activity.addDumpable(this);
    }

    private AutofillManager getAutofillManager() {
+11 −3
Original line number Diff line number Diff line
@@ -391,6 +391,9 @@ public final class ContentCaptureManager {
    @GuardedBy("mLock")
    private MainContentCaptureSession mMainSession;

    @Nullable // set on-demand by addDumpable()
    private Dumper mDumpable;

    /** @hide */
    public interface ContentCaptureClient {
        /**
@@ -407,9 +410,6 @@ public final class ContentCaptureManager {
        mService = Objects.requireNonNull(service, "service cannot be null");
        mOptions = Objects.requireNonNull(options, "options cannot be null");

        if (context instanceof Activity) {
            ((Activity) context).addDumpable(new Dumper());
        }
        ContentCaptureHelper.setLoggingLevel(mOptions.loggingLevel);

        if (sVerbose) Log.v(TAG, "Constructor for " + context.getPackageName());
@@ -748,6 +748,14 @@ public final class ContentCaptureManager {
        return resultReceiver;
    }

    /** @hide */
    public void addDumpable(Activity activity) {
        if (mDumpable == null) {
            mDumpable = new Dumper();
        }
        activity.addDumpable(mDumpable);
    }

    // NOTE: ContentCaptureManager cannot implement it directly as it would be exposed as public API
    private final class Dumper implements Dumpable {
        @Override
+4 −2
Original line number Diff line number Diff line
@@ -46,8 +46,10 @@ public final class DumpableContainerImpl implements DumpableContainer {
        Objects.requireNonNull(name, () -> "name of" + dumpable);

        if (mDumpables.containsKey(name)) {
            Log.e(TAG, "addDumpable(): ignoring " + dumpable + " as there is already a dumpable"
            if (DEBUG) {
                Log.d(TAG, "addDumpable(): ignoring " + dumpable + " as there is already a dumpable"
                        + " with that name (" + name + "): " + mDumpables.get(name));
            }
            return false;
        }