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

Commit 6a989fbf authored by Ned Burns's avatar Ned Burns Committed by Android (Google) Code Review
Browse files

Merge changes from topic "migrate-dump"

* changes:
  Migrate DumpController -> DumpManager
  Add service for dumping at NORMAL priority
  Introduce DumpManager
parents 904621ba aaeb44bf
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -283,6 +283,12 @@
            android:exported="true"
        />

        <!-- Service for dumping extremely verbose content during a bug report -->
        <service android:name=".dump.SystemUIAuxiliaryDumpService"
             android:exported="false"
             android:permission="com.android.systemui.permission.SELF"
        />

        <!-- On user switch, this service is started to ensure that the associated SystemUI
             process for the current user is started. See the resource
             "config_systemUIServiceComponentsPerUser".
+3 −3
Original line number Diff line number Diff line
@@ -88,12 +88,12 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.DejankUtils;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -1475,14 +1475,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            Context context,
            @Main Looper mainLooper,
            BroadcastDispatcher broadcastDispatcher,
            DumpController dumpController,
            DumpManager dumpManager,
            @Background Executor backgroundExecutor) {
        mContext = context;
        mSubscriptionManager = SubscriptionManager.from(context);
        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
        mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
        dumpController.registerDumpable(this);
        mBackgroundExecutor = backgroundExecutor;
        dumpManager.registerDumpable(getClass().getName(), this);

        mHandler = new Handler(mainLooper) {
            @Override
+3 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui

import android.util.Log
import com.android.internal.annotations.GuardedBy
import com.android.systemui.dump.DumpManager
import java.io.FileDescriptor
import java.io.PrintWriter
import java.lang.ref.WeakReference
@@ -32,7 +33,7 @@ import javax.inject.Singleton
 * boot is completed.
 */
@Singleton
class BootCompleteCacheImpl @Inject constructor(private val dumpController: DumpController) :
class BootCompleteCacheImpl @Inject constructor(dumpManager: DumpManager) :
        BootCompleteCache, Dumpable {

    companion object {
@@ -41,7 +42,7 @@ class BootCompleteCacheImpl @Inject constructor(private val dumpController: Dump
    }

    init {
        dumpController.registerDumpable(TAG, this)
        dumpManager.registerDumpable(TAG, this)
    }

    @GuardedBy("listeners")
+22 −32
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -128,8 +129,6 @@ import com.android.systemui.wm.DisplayController;
import com.android.systemui.wm.DisplayImeController;
import com.android.systemui.wm.SystemWindows;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.function.Consumer;

import javax.inject.Inject;
@@ -211,6 +210,8 @@ public class Dependency {
    private final ArrayMap<Object, Object> mDependencies = new ArrayMap<>();
    private final ArrayMap<Object, LazyDependencyCreator> mProviders = new ArrayMap<>();

    @Inject DumpManager mDumpManager;

    @Inject Lazy<ActivityStarter> mActivityStarter;
    @Inject Lazy<BroadcastDispatcher> mBroadcastDispatcher;
    @Inject Lazy<AsyncSensorManager> mAsyncSensorManager;
@@ -311,7 +312,6 @@ public class Dependency {
    @Inject Lazy<DevicePolicyManagerWrapper> mDevicePolicyManagerWrapper;
    @Inject Lazy<PackageManagerWrapper> mPackageManagerWrapper;
    @Inject Lazy<SensorPrivacyController> mSensorPrivacyController;
    @Inject Lazy<DumpController> mDumpController;
    @Inject Lazy<DockManager> mDockManager;
    @Inject Lazy<ChannelEditorDialogController> mChannelEditorDialogController;
    @Inject Lazy<INotificationManager> mINotificationManager;
@@ -505,7 +505,6 @@ public class Dependency {
        mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get);
        mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
        mProviders.put(SensorPrivacyController.class, mSensorPrivacyController::get);
        mProviders.put(DumpController.class, mDumpController::get);
        mProviders.put(DockManager.class, mDockManager::get);
        mProviders.put(ChannelEditorDialogController.class, mChannelEditorDialogController::get);
        mProviders.put(INotificationManager.class, mINotificationManager::get);
@@ -534,34 +533,6 @@ public class Dependency {
        sDependency = this;
    }

    static void staticDump(FileDescriptor fd, PrintWriter pw, String[] args) {
        sDependency.dump(fd, pw, args);
    }

    /**
     * {@see SystemUI.dump}
     */
    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        // Make sure that the DumpController gets added to mDependencies, as they are only added
        // with Dependency#get.
        getDependency(DumpController.class);
        getDependency(BroadcastDispatcher.class);

        // If an arg is specified, try to dump the dependency
        String controller = args != null && args.length > 1
                ? args[1].toLowerCase()
                : null;
        if (controller != null) {
            pw.println("Dumping controller=" + controller + ":");
        } else {
            pw.println("Dumping existing controllers:");
        }
        mDependencies.values().stream()
                .filter(obj -> obj instanceof Dumpable && (controller == null
                        || obj.getClass().getName().toLowerCase().endsWith(controller)))
                .forEach(o -> ((Dumpable) o).dump(fd, pw, args));
    }

    protected final <T> T getDependency(Class<T> cls) {
        return getDependencyInner(cls);
    }
@@ -576,6 +547,11 @@ public class Dependency {
        if (obj == null) {
            obj = createDependency(key);
            mDependencies.put(key, obj);

            // TODO: Get dependencies to register themselves instead
            if (autoRegisterModulesForDump() && obj instanceof Dumpable) {
                mDumpManager.registerDumpable(obj.getClass().getName(), (Dumpable) obj);
            }
        }
        return obj;
    }
@@ -593,6 +569,17 @@ public class Dependency {
        return provider.createDependency();
    }

    // Currently, there are situations in tests where we might create more than one instance of a
    // thing that should be a singleton: the "real" one (created by Dagger, usually as a result of
    // inflating a view), and a mocked one (injected into Dependency). If we register the mocked
    // one, the DumpManager will throw an exception complaining (rightly) that we have too many
    // things registered with that name. So in tests, we disable the auto-registration until the
    // root cause is fixed, i.e. inflated views in tests with Dagger dependencies.
    @VisibleForTesting
    protected boolean autoRegisterModulesForDump() {
        return true;
    }

    private static Dependency sDependency;

    /**
@@ -605,6 +592,9 @@ public class Dependency {

    private <T> void destroyDependency(Class<T> cls, Consumer<T> destroy) {
        T dep = (T) mDependencies.remove(cls);
        if (dep instanceof Dumpable) {
            mDumpManager.unregisterDumpable(dep.getClass().getName());
        }
        if (dep != null && destroy != null) {
            destroy.accept(dep);
        }
+0 −120
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui

import android.util.ArraySet
import android.util.Log
import androidx.annotation.GuardedBy
import java.io.FileDescriptor
import java.io.PrintWriter
import java.lang.ref.WeakReference
import java.util.Objects.requireNonNull
import javax.inject.Inject
import javax.inject.Singleton

// TODO: Move all Dumpable dependencies to use DumpController
/**
 * Controller that allows any [Dumpable] to subscribe and be dumped along with other SystemUI
 * dependencies.
 *
 * To dump a specific dumpable on-demand:
 *
 * ```
 * $ adb shell dumpsys activity service com.android.systemui/.SystemUIService dependency DumpController <tag1>,<tag2>,<tag3>
 * ```
 *
 * Where tag1, tag2, etc. are the tags of the dumpables you want to dump.
 */
@Singleton
class DumpController @Inject constructor() : Dumpable {

    companion object {
        private const val TAG = "DumpController"
        private const val DEBUG = false
    }

    @GuardedBy("listeners")
    private val listeners = mutableListOf<RegisteredDumpable>()
    val numListeners: Int
        get() = listeners.size

    /**
     * Adds a [Dumpable] dumpable to be dumped.
     *
     * @param dumpable the [Dumpable] to be added
     */
    fun registerDumpable(dumpable: Dumpable) {
        requireNonNull(dumpable, "The dumpable to be added cannot be null")
        registerDumpable(dumpable.javaClass.simpleName, dumpable)
    }

    /**
     * Adds a [Dumpable] dumpable to be dumped.
     *
     * @param tag a string tag to associate with this dumpable. Tags must be globally unique; this
     *      method will throw if the same tag has already been registered. Tags can be used to
     *      filter output when debugging.
     * @param dumpable the [Dumpable] to be added
     */
    fun registerDumpable(tag: String, dumpable: Dumpable) {
        requireNonNull(dumpable, "The dumpable to be added cannot be null")
        if (DEBUG) Log.v(TAG, "*** register callback for $dumpable")
        synchronized<Unit>(listeners) {
            if (listeners.any { it.tag == tag }) {
                throw IllegalArgumentException("Duplicate dumpable tag registered: $tag")
            } else {
                listeners.add(RegisteredDumpable(tag, WeakReference(dumpable)))
            }
        }
    }

    /**
     * Removes a dumpable from the list of elements to be dumped.
     *
     * @param dumpable the [Dumpable] to be removed.
     */
    fun unregisterDumpable(dumpable: Dumpable) {
        if (DEBUG) Log.v(TAG, "*** unregister callback for $dumpable")
        synchronized(listeners) {
            listeners.removeAll { it.dumpable.get() == dumpable || it.dumpable.get() == null }
        }
    }

    /**
     * Dump all the [Dumpable] registered with the controller
     */
    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<String>) {
        pw.println("DumpController state:")

        val filter = if (args.size >= 3 && args[0].toLowerCase() == "dependency" &&
                args[1] == "DumpController") {
            ArraySet(args[2].split(',').map { it.toLowerCase() })
        } else {
            null
        }

        synchronized(listeners) {
            listeners.forEach {
                if (filter == null || filter.contains(it.tag.toLowerCase())) {
                    it.dumpable.get()?.dump(fd, pw, args)
                }
            }
        }
    }

    data class RegisteredDumpable(val tag: String, val dumpable: WeakReference<Dumpable>)
}
Loading