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

Commit 4e7d31c8 authored by Govinda Wasserman's avatar Govinda Wasserman Committed by Android (Google) Code Review
Browse files

Merge "Trigger doze detection using WakefulnessLifecycle"

parents ed26d36c 61c92d6f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.PackageManager;

import com.android.systemui.assist.AssistModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
@@ -34,7 +35,7 @@ import dagger.Provides;
 * A dagger module for injecting components of System UI that are not overridden by the System UI
 * implementation.
 */
@Module
@Module(includes = {AssistModule.class})
public abstract class SystemUIModule {

    @Singleton
+23 −35
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.assist;

import static com.android.systemui.assist.AssistModule.ASSIST_HANDLE_THREAD_NAME;

import android.content.ComponentName;
import android.content.Context;
import android.os.Handler;
@@ -28,20 +30,21 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dependency;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
import com.android.systemui.ScreenDecorations;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.NavigationModeController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.EnumMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;

/**
 * A class for managing Assistant handle logic.
@@ -49,6 +52,7 @@ import java.util.function.Supplier;
 * Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
 * {@link AssistHandleBehavior}.
 */
@Singleton
public final class AssistHandleBehaviorController implements AssistHandleCallbacks, Dumpable {

    private static final String TAG = "AssistHandleBehavior";
@@ -67,10 +71,9 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
    private final Handler mHandler;
    private final Runnable mHideHandles = this::hideHandles;
    private final Runnable mShowAndGo = this::showAndGoInternal;
    private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
    private final Provider<ScreenDecorations> mScreenDecorations;
    private final PhenotypeHelper mPhenotypeHelper;
    private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
            new EnumMap<>(AssistHandleBehavior.class);
    private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap;

    private boolean mHandlesShowing = false;
    private long mHandlesLastHiddenAt;
@@ -82,41 +85,25 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
    private AssistHandleBehavior mCurrentBehavior = AssistHandleBehavior.OFF;
    private boolean mInGesturalMode;

    AssistHandleBehaviorController(Context context, AssistUtils assistUtils, Handler handler) {
        this(
                context,
                assistUtils,
                handler,
                () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
                new PhenotypeHelper(),
                /* testBehavior = */ null);
    }

    @VisibleForTesting
    @Inject
    AssistHandleBehaviorController(
            Context context,
            AssistUtils assistUtils,
            Handler handler,
            Supplier<ScreenDecorations> screenDecorationsSupplier,
            @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler,
            Provider<ScreenDecorations> screenDecorations,
            PhenotypeHelper phenotypeHelper,
            @Nullable BehaviorController testBehavior) {
            Map<AssistHandleBehavior, BehaviorController> behaviorMap,
            NavigationModeController navigationModeController,
            DumpController dumpController) {
        mContext = context;
        mAssistUtils = assistUtils;
        mHandler = handler;
        mScreenDecorationsSupplier = screenDecorationsSupplier;
        mScreenDecorations = screenDecorations;
        mPhenotypeHelper = phenotypeHelper;
        mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
        mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
        mBehaviorMap.put(
                AssistHandleBehavior.REMINDER_EXP,
                new AssistHandleReminderExpBehavior(handler, phenotypeHelper));
        if (testBehavior != null) {
            mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
        }
        mBehaviorMap = behaviorMap;

        mInGesturalMode = QuickStepContract.isGesturalMode(
                Dependency.get(NavigationModeController.class)
                        .addListener(this::handleNavigationModeChange));
                navigationModeController.addListener(this::handleNavigationModeChange));

        setBehavior(getBehaviorMode());
        mPhenotypeHelper.addOnPropertiesChangedListener(
@@ -128,7 +115,8 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
                                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, null));
                    }
                });
        Dependency.get(DumpController.class).registerDumpable(TAG, this);

        dumpController.registerDumpable(TAG, this);
    }

    @Override // AssistHandleCallbacks
@@ -241,7 +229,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
        }

        if (handlesUnblocked(ignoreThreshold)) {
            ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
            ScreenDecorations screenDecorations = mScreenDecorations.get();
            if (screenDecorations == null) {
                Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
            } else {
@@ -256,7 +244,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
            return;
        }

        ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
        ScreenDecorations screenDecorations = mScreenDecorations.get();
        if (screenDecorations == null) {
            Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
        } else {
+41 −15
Original line number Diff line number Diff line
@@ -20,56 +20,82 @@ import android.content.Context;

import androidx.annotation.Nullable;

import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract;

import java.io.PrintWriter;

import javax.inject.Inject;
import javax.inject.Singleton;

import dagger.Lazy;

/**
 * Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
 * shown/hidden, respectively.
 */
@Singleton
final class AssistHandleLikeHomeBehavior implements BehaviorController {

    private final StatusBarStateController.StateListener mStatusBarStateListener =
            new StatusBarStateController.StateListener() {
    private final WakefulnessLifecycle.Observer mWakefulnessLifecycleObserver =
            new WakefulnessLifecycle.Observer() {
                @Override
                public void onStartedWakingUp() {
                    handleDozingChanged(/* isDozing = */ true);
                }

                @Override
                public void onFinishedWakingUp() {
                    handleDozingChanged(/* isDozing = */ false);
                }

                @Override
                public void onStartedGoingToSleep() {
                    handleDozingChanged(/* isDozing = */ true);
                }

                @Override
                public void onDozingChanged(boolean isDozing) {
                    handleDozingChanged(isDozing);
                public void onFinishedGoingToSleep() {
                    handleDozingChanged(/* isDozing = */ true);
                }
            };

    private final SysUiState.SysUiStateCallback mSysUiStateCallback =
            this::handleSystemUiStateChange;
    private final StatusBarStateController mStatusBarStateController;
    private final SysUiState mSysUiFlagContainer;

    private final Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
    private final Lazy<SysUiState> mSysUiFlagContainer;

    private boolean mIsDozing;
    private boolean mIsHomeHandleHiding;

    @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;

    AssistHandleLikeHomeBehavior() {
        mStatusBarStateController = Dependency.get(StatusBarStateController.class);
        mSysUiFlagContainer = Dependency.get(SysUiState.class);
    @Inject
    AssistHandleLikeHomeBehavior(
            Lazy<WakefulnessLifecycle> wakefulnessLifecycle,
            Lazy<SysUiState> sysUiFlagContainer) {
        mWakefulnessLifecycle = wakefulnessLifecycle;
        mSysUiFlagContainer = sysUiFlagContainer;
    }

    @Override
    public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
        mAssistHandleCallbacks = callbacks;
        mIsDozing = mStatusBarStateController.isDozing();
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mSysUiFlagContainer.addCallback(mSysUiStateCallback);
        mIsDozing = mWakefulnessLifecycle.get().getWakefulness()
                != WakefulnessLifecycle.WAKEFULNESS_AWAKE;
        mWakefulnessLifecycle.get().addObserver(mWakefulnessLifecycleObserver);
        mSysUiFlagContainer.get().addCallback(mSysUiStateCallback);
        callbackForCurrentState();
    }

    @Override
    public void onModeDeactivated() {
        mAssistHandleCallbacks = null;
        mSysUiFlagContainer.removeCallback(mSysUiStateCallback);
        mWakefulnessLifecycle.get().removeObserver(mWakefulnessLifecycleObserver);
        mSysUiFlagContainer.get().removeCallback(mSysUiStateCallback);
    }

    private static boolean isHomeHandleHiding(int sysuiStateFlags) {
+8 −0
Original line number Diff line number Diff line
@@ -20,9 +20,17 @@ import android.content.Context;

import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;

import javax.inject.Inject;
import javax.inject.Singleton;

/** Assistant handle behavior that hides the Assistant handles. */
@Singleton
final class AssistHandleOffBehavior implements BehaviorController {

    @Inject
    AssistHandleOffBehavior() {
    }

    @Override
    public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
        callbacks.hide();
+71 −50
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@

package com.android.systemui.assist;

import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.assist.AssistModule.ASSIST_HANDLE_THREAD_NAME;
import static com.android.systemui.assist.AssistModule.UPTIME_NAME;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -26,14 +27,14 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;

import androidx.annotation.Nullable;
import androidx.slice.Clock;

import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
@@ -49,11 +50,18 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

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

import dagger.Lazy;

/**
 * Assistant handle behavior that hides the handles when the phone is dozing or in immersive mode,
 * shows the handles when on lockscreen, and shows the handles temporarily when changing tasks or
 * entering overview.
 */
@Singleton
final class AssistHandleReminderExpBehavior implements BehaviorController {

    private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
@@ -86,11 +94,6 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
                public void onStateChanged(int newState) {
                    handleStatusBarStateChanged(newState);
                }

                @Override
                public void onDozingChanged(boolean isDozing) {
                    handleDozingChanged(isDozing);
                }
            };
    private final TaskStackChangeListener mTaskStackChangeListener =
            new TaskStackChangeListener() {
@@ -111,9 +114,20 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
                    handleOverviewShown();
                }
            };

    private final SysUiState.SysUiStateCallback mSysUiStateCallback =
            this::handleSystemUiStateChanged;
    private final WakefulnessLifecycle.Observer mWakefulnessLifecycleObserver =
            new WakefulnessLifecycle.Observer() {
                @Override
                public void onFinishedWakingUp() {
                    handleDozingChanged(false);
                }

                @Override
                public void onStartedGoingToSleep() {
                    handleDozingChanged(true);
                }
    };
    private final BroadcastReceiver mDefaultHomeBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
@@ -123,12 +137,15 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
    private final IntentFilter mDefaultHomeIntentFilter;
    private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;

    private final Clock mClock;
    private final Handler mHandler;
    private final PhenotypeHelper mPhenotypeHelper;
    private final StatusBarStateController mStatusBarStateController;
    private final ActivityManagerWrapper mActivityManagerWrapper;
    private final OverviewProxyService mOverviewProxyService;
    private final SysUiState mSysUiFlagContainer;
    private final Lazy<StatusBarStateController> mStatusBarStateController;
    private final Lazy<ActivityManagerWrapper> mActivityManagerWrapper;
    private final Lazy<OverviewProxyService> mOverviewProxyService;
    private final Lazy<SysUiState> mSysUiFlagContainer;
    private final Lazy<WakefulnessLifecycle> mWakefulnessLifecycle;
    private final Lazy<PackageManagerWrapper> mPackageManagerWrapper;

    private boolean mOnLockscreen;
    private boolean mIsDozing;
@@ -150,13 +167,26 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
    @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
    @Nullable private ComponentName mDefaultHome;

    AssistHandleReminderExpBehavior(Handler handler, PhenotypeHelper phenotypeHelper) {
    @Inject
    AssistHandleReminderExpBehavior(
            @Named(UPTIME_NAME) Clock clock,
            @Named(ASSIST_HANDLE_THREAD_NAME) Handler handler,
            PhenotypeHelper phenotypeHelper,
            Lazy<StatusBarStateController> statusBarStateController,
            Lazy<ActivityManagerWrapper> activityManagerWrapper,
            Lazy<OverviewProxyService> overviewProxyService,
            Lazy<SysUiState> sysUiFlagContainer,
            Lazy<WakefulnessLifecycle> wakefulnessLifecycle,
            Lazy<PackageManagerWrapper> packageManagerWrapper) {
        mClock = clock;
        mHandler = handler;
        mPhenotypeHelper = phenotypeHelper;
        mStatusBarStateController = Dependency.get(StatusBarStateController.class);
        mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
        mSysUiFlagContainer = Dependency.get(SysUiState.class);
        mStatusBarStateController = statusBarStateController;
        mActivityManagerWrapper = activityManagerWrapper;
        mOverviewProxyService = overviewProxyService;
        mSysUiFlagContainer = sysUiFlagContainer;
        mWakefulnessLifecycle = wakefulnessLifecycle;
        mPackageManagerWrapper = packageManagerWrapper;
        mDefaultHomeIntentFilter = new IntentFilter();
        for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
            mDefaultHomeIntentFilter.addAction(action);
@@ -170,14 +200,17 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
        mConsecutiveTaskSwitches = 0;
        mDefaultHome = getCurrentDefaultHome();
        context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
        mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
        mIsDozing = mStatusBarStateController.isDozing();
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        ActivityManager.RunningTaskInfo runningTaskInfo = mActivityManagerWrapper.getRunningTask();
        mOnLockscreen = onLockscreen(mStatusBarStateController.get().getState());
        mStatusBarStateController.get().addCallback(mStatusBarStateListener);
        ActivityManager.RunningTaskInfo runningTaskInfo =
                mActivityManagerWrapper.get().getRunningTask();
        mRunningTaskId = runningTaskInfo == null ? 0 : runningTaskInfo.taskId;
        mActivityManagerWrapper.registerTaskStackListener(mTaskStackChangeListener);
        mOverviewProxyService.addCallback(mOverviewProxyListener);
        mSysUiFlagContainer.addCallback(mSysUiStateCallback);
        mActivityManagerWrapper.get().registerTaskStackListener(mTaskStackChangeListener);
        mOverviewProxyService.get().addCallback(mOverviewProxyListener);
        mSysUiFlagContainer.get().addCallback(mSysUiStateCallback);
        mIsDozing = mWakefulnessLifecycle.get().getWakefulness()
                != WakefulnessLifecycle.WAKEFULNESS_AWAKE;
        mWakefulnessLifecycle.get().addObserver(mWakefulnessLifecycleObserver);

        mLearningTimeElapsed = Settings.Secure.getLong(
                context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
@@ -185,7 +218,7 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
                context.getContentResolver(), LEARNING_EVENT_COUNT_KEY, /* default = */ 0);
        mLearnedHintLastShownEpochDay = Settings.Secure.getLong(
                context.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, /* default = */ 0);
        mLastLearningTimestamp = SystemClock.uptimeMillis();
        mLastLearningTimestamp = mClock.currentTimeMillis();

        callbackForCurrentState(/* justUnlocked = */ false);
    }
@@ -200,10 +233,11 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
            Settings.Secure.putLong(mContext.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, 0);
            mContext = null;
        }
        mStatusBarStateController.removeCallback(mStatusBarStateListener);
        mActivityManagerWrapper.unregisterTaskStackListener(mTaskStackChangeListener);
        mOverviewProxyService.removeCallback(mOverviewProxyListener);
        mSysUiFlagContainer.removeCallback(mSysUiStateCallback);
        mStatusBarStateController.get().removeCallback(mStatusBarStateListener);
        mActivityManagerWrapper.get().unregisterTaskStackListener(mTaskStackChangeListener);
        mOverviewProxyService.get().removeCallback(mOverviewProxyListener);
        mSysUiFlagContainer.get().removeCallback(mSysUiStateCallback);
        mWakefulnessLifecycle.get().removeObserver(mWakefulnessLifecycleObserver);
    }

    @Override
@@ -223,15 +257,10 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
        }
    }

    private static boolean isNavBarHidden(int sysuiStateFlags) {
        return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
    }

    @Nullable
    private static ComponentName getCurrentDefaultHome() {
    private ComponentName getCurrentDefaultHome() {
        List<ResolveInfo> homeActivities = new ArrayList<>();
        ComponentName defaultHome =
                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
        ComponentName defaultHome = mPackageManagerWrapper.get().getHomeActivities(homeActivities);
        if (defaultHome != null) {
            return defaultHome;
        }
@@ -287,7 +316,8 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
    }

    private void handleSystemUiStateChanged(int sysuiStateFlags) {
        boolean isNavBarHidden = isNavBarHidden(sysuiStateFlags);
        boolean isNavBarHidden =
                (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
        if (mIsNavBarHidden == isNavBarHidden) {
            return;
        }
@@ -374,24 +404,15 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
            return;
        }

        long currentTimestamp = SystemClock.uptimeMillis();
        long currentTimestamp = mClock.currentTimeMillis();
        mLearningTimeElapsed += currentTimestamp - mLastLearningTimestamp;
        mLastLearningTimestamp = currentTimestamp;
        // TODO(b/140034473)
        whitelistIpcs(() -> Settings.Secure.putLong(
                mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed));

        mIsLearned =
                mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();

        mHandler.post(this::recordLearnTimeElapsed);
    }

    private void recordLearnTimeElapsed() {
        if (mContext != null) {
            Settings.Secure.putLong(
                    mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
        }
        mHandler.post(() -> Settings.Secure.putLong(
                mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed));
    }

    private void resetConsecutiveTaskSwitches() {
Loading