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

Commit 0734aafb authored by Will Leshner's avatar Will Leshner
Browse files

Allow setting a connection callback to PersistentServiceManager.

Add methods to PersistentServiceManager to add/remove a connection
callback. This is needed to fix an issue with the cast icon not
appearing correctly when docked and dreaming.

Also add dumpsys logging to PersistentServiceManager and
ObservableServiceConnection to aid debugging connection issues.

Bug: 314690485
Test: atest PersistentServiceManagerTest,
ObservableServiceConnectionTest
Flag: NA

Change-Id: I75fc633d0ccb88cb45ace201190c51f67ba42248
parent 849eaa9d
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -22,12 +22,17 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.IndentingPrintWriter;
import android.util.Log;

import androidx.annotation.NonNull;

import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.DumpUtilsKt;
import com.android.systemui.util.annotations.WeaklyReferencedCallback;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
@@ -244,6 +249,21 @@ public class ObservableServiceConnection<T> implements ServiceConnection {
        });
    }

    void dump(@NonNull PrintWriter pw) {
        IndentingPrintWriter ipw = DumpUtilsKt.asIndenting(pw);
        ipw.println("ObservableServiceConnection state:");
        DumpUtilsKt.withIncreasedIndent(ipw, () -> {
            ipw.println("mServiceIntent: " + mServiceIntent);
            ipw.println("mLastDisconnectReason: " + mLastDisconnectReason.orElse(-1));
            ipw.println("Callbacks:");
            DumpUtilsKt.withIncreasedIndent(ipw, () -> {
                for (WeakReference<Callback<T>> cbRef : mCallbacks) {
                    ipw.println(cbRef.get());
                }
            });
        });
    }

    private void applyToCallbacksLocked(Consumer<Callback<T>> applicator) {
        final Iterator<WeakReference<Callback<T>>> iterator = mCallbacks.iterator();

+41 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.util.service;

import static com.android.systemui.util.service.dagger.ObservableServiceModule.BASE_RECONNECT_DELAY_MS;
import static com.android.systemui.util.service.dagger.ObservableServiceModule.DUMPSYS_NAME;
import static com.android.systemui.util.service.dagger.ObservableServiceModule.MAX_RECONNECT_ATTEMPTS;
import static com.android.systemui.util.service.dagger.ObservableServiceModule.MIN_CONNECTION_DURATION_MS;
import static com.android.systemui.util.service.dagger.ObservableServiceModule.OBSERVER;
@@ -24,9 +25,15 @@ import static com.android.systemui.util.service.dagger.ObservableServiceModule.S

import android.util.Log;

import androidx.annotation.NonNull;

import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.time.SystemClock;

import java.io.PrintWriter;

import javax.inject.Inject;
import javax.inject.Named;

@@ -35,7 +42,7 @@ import javax.inject.Named;
 * {@link ObservableServiceConnection}.
 * @param <T> The transformed connection type handled by the service.
 */
public class PersistentConnectionManager<T> {
public class PersistentConnectionManager<T> implements Dumpable {
    private static final String TAG = "PersistentConnManager";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

@@ -45,6 +52,8 @@ public class PersistentConnectionManager<T> {
    private final int mMaxReconnectAttempts;
    private final int mMinConnectionDuration;
    private final Observer mObserver;
    private final DumpManager mDumpManager;
    private final String mDumpsysName;

    private int mReconnectAttempts = 0;
    private Runnable mCurrentReconnectCancelable;
@@ -89,6 +98,8 @@ public class PersistentConnectionManager<T> {
    public PersistentConnectionManager(
            SystemClock clock,
            DelayableExecutor mainExecutor,
            DumpManager dumpManager,
            @Named(DUMPSYS_NAME) String dumpsysName,
            @Named(SERVICE_CONNECTION) ObservableServiceConnection<T> serviceConnection,
            @Named(MAX_RECONNECT_ATTEMPTS) int maxReconnectAttempts,
            @Named(BASE_RECONNECT_DELAY_MS) int baseReconnectDelayMs,
@@ -98,6 +109,8 @@ public class PersistentConnectionManager<T> {
        mMainExecutor = mainExecutor;
        mConnection = serviceConnection;
        mObserver = observer;
        mDumpManager = dumpManager;
        mDumpsysName = TAG + "#" + dumpsysName;

        mMaxReconnectAttempts = maxReconnectAttempts;
        mBaseReconnectDelayMs = baseReconnectDelayMs;
@@ -108,6 +121,7 @@ public class PersistentConnectionManager<T> {
     * Begins the {@link PersistentConnectionManager} by connecting to the associated service.
     */
    public void start() {
        mDumpManager.registerCriticalDumpable(mDumpsysName, this);
        mConnection.addCallback(mConnectionCallback);
        mObserver.addCallback(mObserverCallback);
        initiateConnectionAttempt();
@@ -120,6 +134,32 @@ public class PersistentConnectionManager<T> {
        mConnection.removeCallback(mConnectionCallback);
        mObserver.removeCallback(mObserverCallback);
        mConnection.unbind();
        mDumpManager.unregisterDumpable(mDumpsysName);
    }

    /**
     * Add a callback to the {@link ObservableServiceConnection}.
     * @param callback The callback to add.
     */
    public void addConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
        mConnection.addCallback(callback);
    }

    /**
     * Remove a callback from the {@link ObservableServiceConnection}.
     * @param callback The callback to remove.
     */
    public void removeConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
        mConnection.removeCallback(callback);
    }

    @Override
    public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
        pw.println("mMaxReconnectAttempts: " + mMaxReconnectAttempts);
        pw.println("mBaseReconnectDelayMs: " + mBaseReconnectDelayMs);
        pw.println("mMinConnectionDuration: " + mMinConnectionDuration);
        pw.println("mReconnectAttempts: " + mReconnectAttempts);
        mConnection.dump(pw);
    }

    private void initiateConnectionAttempt() {
+4 −3
Original line number Diff line number Diff line
@@ -19,14 +19,14 @@ package com.android.systemui.util.service.dagger;

import android.content.res.Resources;

import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.Main;

import javax.inject.Named;
import com.android.systemui.res.R;

import dagger.Module;
import dagger.Provides;

import javax.inject.Named;

/**
 * Module containing components and parameters for
 * {@link com.android.systemui.util.service.ObservableServiceConnection}
@@ -41,6 +41,7 @@ public class ObservableServiceModule {
    public static final String MIN_CONNECTION_DURATION_MS = "min_connection_duration_ms";
    public static final String SERVICE_CONNECTION = "service_connection";
    public static final String OBSERVER = "observer";
    public static final String DUMPSYS_NAME = "dumpsys_name";

    @Provides
    @Named(MAX_RECONNECT_ATTEMPTS)
+22 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;

@@ -41,6 +42,7 @@ public class PersistentConnectionManagerTest extends SysuiTestCase {
    private static final int MAX_RETRIES = 5;
    private static final int RETRY_DELAY_MS = 1000;
    private static final int CONNECTION_MIN_DURATION_MS = 5000;
    private static final String DUMPSYS_NAME = "dumpsys_name";

    private FakeSystemClock mFakeClock = new FakeSystemClock();
    private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
@@ -48,9 +50,15 @@ public class PersistentConnectionManagerTest extends SysuiTestCase {
    @Mock
    private ObservableServiceConnection<Proxy> mConnection;

    @Mock
    private ObservableServiceConnection.Callback<Proxy> mConnectionCallback;

    @Mock
    private Observer mObserver;

    @Mock
    private DumpManager mDumpManager;

    private static class Proxy {
    }

@@ -63,6 +71,8 @@ public class PersistentConnectionManagerTest extends SysuiTestCase {
        mConnectionManager = new PersistentConnectionManager<>(
                mFakeClock,
                mFakeExecutor,
                mDumpManager,
                DUMPSYS_NAME,
                mConnection,
                MAX_RETRIES,
                RETRY_DELAY_MS,
@@ -154,4 +164,16 @@ public class PersistentConnectionManagerTest extends SysuiTestCase {
        callbackCaptor.getValue().onSourceChanged();
        verify(mConnection).bind();
    }

    @Test
    public void testAddConnectionCallback() {
        mConnectionManager.addConnectionCallback(mConnectionCallback);
        verify(mConnection).addCallback(mConnectionCallback);
    }

    @Test
    public void testRemoveConnectionCallback() {
        mConnectionManager.removeConnectionCallback(mConnectionCallback);
        verify(mConnection).removeCallback(mConnectionCallback);
    }
}