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

Commit edcc5a96 authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Generalize Communal Conditions."

parents d443f19b 40093359
Loading
Loading
Loading
Loading
+8 −120
Original line number Diff line number Diff line
@@ -16,139 +16,27 @@

package com.android.systemui.communal.conditions;

import static com.android.systemui.communal.dagger.CommunalModule.COMMUNAL_CONDITIONS;

import android.util.Log;
import static com.android.systemui.communal.dagger.CommunalModule.COMMUNAL_CONDITIONS;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.policy.CallbackController;

import org.jetbrains.annotations.NotNull;
import com.android.systemui.util.condition.Condition;
import com.android.systemui.util.condition.Monitor;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

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

/**
 * {@link CommunalConditionsMonitor} takes in a set of conditions, monitors whether all of them have
 * been fulfilled, and informs any registered listeners.
 * A concrete implementation of {@Monitor} with conditions for monitoring when communal mode should
 * be enabled.
 */
@SysUISingleton
public class CommunalConditionsMonitor implements
        CallbackController<CommunalConditionsMonitor.Callback> {
    private final String mTag = getClass().getSimpleName();

    private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();

    // Set of all conditions that need to be monitored.
    private final Set<CommunalCondition> mConditions;

    // Map of values of each condition.
    private final HashMap<CommunalCondition, Boolean> mConditionsMap = new HashMap<>();

    // Whether all conditions have been met.
    private boolean mAllConditionsMet = false;

    // Whether the monitor has started listening for all the conditions.
    private boolean mHaveConditionsStarted = false;

    // Callback for when each condition has been updated.
    private final CommunalCondition.Callback mConditionCallback = (condition, isConditionMet) -> {
        mConditionsMap.put(condition, isConditionMet);

        final boolean newAllConditionsMet = !mConditionsMap.containsValue(false);

        if (newAllConditionsMet == mAllConditionsMet) {
            return;
        }

        if (shouldLog()) Log.d(mTag, "all conditions met: " + newAllConditionsMet);
        mAllConditionsMet = newAllConditionsMet;

        // Updates all callbacks.
        final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
        while (iterator.hasNext()) {
            final Callback callback = iterator.next().get();
            if (callback == null) {
                iterator.remove();
            } else {
                callback.onConditionsChanged(mAllConditionsMet);
            }
        }
    };

public class CommunalConditionsMonitor extends Monitor {
    @Inject
    public CommunalConditionsMonitor(
            @Named(COMMUNAL_CONDITIONS) Set<CommunalCondition> communalConditions) {
        mConditions = communalConditions;

        // Initializes the conditions map and registers a callback for each condition.
        mConditions.forEach((condition -> mConditionsMap.put(condition, false)));
    }

    @Override
    public void addCallback(@NotNull Callback callback) {
        if (shouldLog()) Log.d(mTag, "adding callback");
        mCallbacks.add(new WeakReference<>(callback));

        // Updates the callback immediately.
        callback.onConditionsChanged(mAllConditionsMet);

        if (!mHaveConditionsStarted) {
            if (shouldLog()) Log.d(mTag, "starting all conditions");
            mConditions.forEach(condition -> condition.addCallback(mConditionCallback));
            mHaveConditionsStarted = true;
        }
    }

    @Override
    public void removeCallback(@NotNull Callback callback) {
        if (shouldLog()) Log.d(mTag, "removing callback");
        final Iterator<WeakReference<Callback>> iterator = mCallbacks.iterator();
        while (iterator.hasNext()) {
            final Callback cb = iterator.next().get();
            if (cb == null || cb == callback) {
                iterator.remove();
            }
        }

        if (mCallbacks.isEmpty() && mHaveConditionsStarted) {
            if (shouldLog()) Log.d(mTag, "stopping all conditions");
            mConditions.forEach(condition -> condition.removeCallback(mConditionCallback));

            mAllConditionsMet = false;
            mHaveConditionsStarted = false;
        }
    }

    /**
     * Force updates each condition to the value provided.
     */
    @VisibleForTesting
    public void overrideAllConditionsMet(boolean value) {
        mConditions.forEach(condition -> condition.updateCondition(value));
    }

    private boolean shouldLog() {
        return Log.isLoggable(mTag, Log.DEBUG);
    }

    /**
     * Callback that receives updates of whether all conditions have been fulfilled.
     */
    public interface Callback {
        /**
         * Triggered when the fulfillment of all conditions have been met.
         *
         * @param allConditionsMet True if all conditions have been fulfilled. False if none or
         *                         only partial conditions have been fulfilled.
         */
        void onConditionsChanged(boolean allConditionsMet);
            @Named(COMMUNAL_CONDITIONS) Set<Condition> communalConditions) {
        super(communalConditions);
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.provider.Settings;

import androidx.annotation.MainThread;

import com.android.systemui.util.condition.Condition;
import com.android.systemui.util.settings.SecureSettings;

import javax.inject.Inject;
@@ -30,7 +31,7 @@ import javax.inject.Inject;
/**
 * Monitors the communal setting, and informs any listeners with updates.
 */
public class CommunalSettingCondition extends CommunalCondition {
public class CommunalSettingCondition extends Condition {
    private final SecureSettings mSecureSettings;
    private final ContentObserver mCommunalSettingContentObserver;

+2 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.util.Log;
import androidx.annotation.NonNull;

import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.condition.Condition;
import com.android.systemui.util.settings.SecureSettings;

import java.util.Arrays;
@@ -42,7 +43,7 @@ import javax.inject.Inject;
 * Monitors Wi-Fi connections and triggers callback, if any, when the device is connected to and
 * disconnected from a trusted network.
 */
public class CommunalTrustedNetworkCondition extends CommunalCondition {
public class CommunalTrustedNetworkCondition extends Condition {
    private final String mTag = getClass().getSimpleName();
    private final ConnectivityManager mConnectivityManager;
    private final ContentObserver mTrustedNetworksObserver;
+2 −2
Original line number Diff line number Diff line
@@ -28,12 +28,12 @@ import androidx.annotation.Nullable;
import com.android.systemui.R;
import com.android.systemui.communal.CommunalSource;
import com.android.systemui.communal.PackageObserver;
import com.android.systemui.communal.conditions.CommunalCondition;
import com.android.systemui.communal.conditions.CommunalSettingCondition;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.idle.AmbientLightModeMonitor;
import com.android.systemui.idle.LightSensorEventsDebounceAlgorithm;
import com.android.systemui.idle.dagger.IdleViewComponent;
import com.android.systemui.util.condition.Condition;

import java.util.Collections;
import java.util.HashSet;
@@ -99,7 +99,7 @@ public interface CommunalModule {
    @Provides
    @ElementsIntoSet
    @Named(COMMUNAL_CONDITIONS)
    static Set<CommunalCondition> provideCommunalConditions(
    static Set<Condition> provideCommunalConditions(
            CommunalSettingCondition communalSettingCondition) {
        return new HashSet<>(Collections.singletonList(communalSettingCondition));
    }
+5 −4
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.systemui.communal.conditions;
package com.android.systemui.util.condition;

import android.util.Log;

@@ -27,9 +27,10 @@ import java.util.ArrayList;
import java.util.Iterator;

/**
 * Base class for a condition that needs to be fulfilled in order for Communal Mode to display.
 * Base class for a condition that needs to be fulfilled in order for {@link Monitor} to inform
 * its callbacks.
 */
public abstract class CommunalCondition implements CallbackController<CommunalCondition.Callback> {
public abstract class Condition implements CallbackController<Condition.Callback> {
    private final String mTag = getClass().getSimpleName();

    private final ArrayList<WeakReference<Callback>> mCallbacks = new ArrayList<>();
@@ -125,6 +126,6 @@ public abstract class CommunalCondition implements CallbackController<CommunalCo
         * @param condition The condition in question.
         * @param isConditionMet True if the condition has been fulfilled. False otherwise.
         */
        void onConditionChanged(CommunalCondition condition, boolean isConditionMet);
        void onConditionChanged(Condition condition, boolean isConditionMet);
    }
}
Loading