Merge "Improves the REMINDER_EXP mode for Assist Handle behavior" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4335d958e4
@@ -119,6 +119,26 @@ public final class SystemUiDeviceConfigFlags {
|
|||||||
public static final String ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS =
|
public static final String ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS =
|
||||||
"assist_handles_show_and_go_duration_ms";
|
"assist_handles_show_and_go_duration_ms";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
|
||||||
|
* performing a short delayed show.
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS =
|
||||||
|
"assist_handles_show_and_go_delayed_short_delay_ms";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
|
||||||
|
* performing a long delayed show.
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
|
||||||
|
"assist_handles_show_and_go_delayed_long_delay_ms";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (long) How long, in milliseconds, to wait before resetting delayed show delay times.
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
|
||||||
|
"assist_handles_show_and_go_delay_reset_timeout_ms";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (long) How long, in milliseconds, to wait before displaying Assist Handles temporarily after
|
* (long) How long, in milliseconds, to wait before displaying Assist Handles temporarily after
|
||||||
* hiding them.
|
* hiding them.
|
||||||
@@ -138,5 +158,23 @@ public final class SystemUiDeviceConfigFlags {
|
|||||||
*/
|
*/
|
||||||
public static final String ASSIST_HANDLES_LEARN_COUNT = "assist_handles_learn_count";
|
public static final String ASSIST_HANDLES_LEARN_COUNT = "assist_handles_learn_count";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (bool) Whether to suppress handles on lockscreen."
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN =
|
||||||
|
"assist_handles_suppress_on_lockscreen";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (bool) Whether to suppress handles on launcher."
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER =
|
||||||
|
"assist_handles_suppress_on_launcher";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (bool) Whether to suppress handles on apps."
|
||||||
|
*/
|
||||||
|
public static final String ASSIST_HANDLES_SUPPRESS_ON_APPS =
|
||||||
|
"assist_handles_suppress_on_apps";
|
||||||
|
|
||||||
private SystemUiDeviceConfigFlags() { }
|
private SystemUiDeviceConfigFlags() { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.DeviceConfig;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -30,11 +29,15 @@ import com.android.internal.app.AssistUtils;
|
|||||||
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
||||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
|
import com.android.systemui.DumpController;
|
||||||
|
import com.android.systemui.Dumpable;
|
||||||
import com.android.systemui.ScreenDecorations;
|
import com.android.systemui.ScreenDecorations;
|
||||||
import com.android.systemui.SysUiServiceProvider;
|
import com.android.systemui.SysUiServiceProvider;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.statusbar.phone.NavigationModeController;
|
import com.android.systemui.statusbar.phone.NavigationModeController;
|
||||||
|
|
||||||
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -46,11 +49,11 @@ import java.util.function.Supplier;
|
|||||||
* Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
|
* Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
|
||||||
* {@link AssistHandleBehavior}.
|
* {@link AssistHandleBehavior}.
|
||||||
*/
|
*/
|
||||||
public final class AssistHandleBehaviorController implements AssistHandleCallbacks {
|
public final class AssistHandleBehaviorController implements AssistHandleCallbacks, Dumpable {
|
||||||
|
|
||||||
private static final String TAG = "AssistHandleBehavior";
|
private static final String TAG = "AssistHandleBehavior";
|
||||||
|
|
||||||
private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(10);
|
private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = 0;
|
||||||
private static final long DEFAULT_SHOW_AND_GO_DURATION_MS = TimeUnit.SECONDS.toMillis(3);
|
private static final long DEFAULT_SHOW_AND_GO_DURATION_MS = TimeUnit.SECONDS.toMillis(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,7 +66,9 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
private final AssistUtils mAssistUtils;
|
private final AssistUtils mAssistUtils;
|
||||||
private final Handler mHandler;
|
private final Handler mHandler;
|
||||||
private final Runnable mHideHandles = this::hideHandles;
|
private final Runnable mHideHandles = this::hideHandles;
|
||||||
|
private final Runnable mShowAndGo = this::showAndGoInternal;
|
||||||
private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
|
private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
|
||||||
|
private final PhenotypeHelper mPhenotypeHelper;
|
||||||
private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
|
private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
|
||||||
new EnumMap<>(AssistHandleBehavior.class);
|
new EnumMap<>(AssistHandleBehavior.class);
|
||||||
|
|
||||||
@@ -80,7 +85,9 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
this(
|
this(
|
||||||
context,
|
context,
|
||||||
assistUtils,
|
assistUtils,
|
||||||
handler, () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
|
handler,
|
||||||
|
() -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
|
||||||
|
new PhenotypeHelper(),
|
||||||
/* testBehavior = */ null);
|
/* testBehavior = */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,15 +97,18 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
AssistUtils assistUtils,
|
AssistUtils assistUtils,
|
||||||
Handler handler,
|
Handler handler,
|
||||||
Supplier<ScreenDecorations> screenDecorationsSupplier,
|
Supplier<ScreenDecorations> screenDecorationsSupplier,
|
||||||
|
PhenotypeHelper phenotypeHelper,
|
||||||
@Nullable BehaviorController testBehavior) {
|
@Nullable BehaviorController testBehavior) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAssistUtils = assistUtils;
|
mAssistUtils = assistUtils;
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mScreenDecorationsSupplier = screenDecorationsSupplier;
|
mScreenDecorationsSupplier = screenDecorationsSupplier;
|
||||||
|
mPhenotypeHelper = phenotypeHelper;
|
||||||
mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
|
mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
|
||||||
mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
|
mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
|
||||||
mBehaviorMap.put(AssistHandleBehavior.REMINDER_EXP, new AssistHandleReminderExpBehavior());
|
mBehaviorMap.put(
|
||||||
|
AssistHandleBehavior.REMINDER_EXP,
|
||||||
|
new AssistHandleReminderExpBehavior(handler, phenotypeHelper));
|
||||||
if (testBehavior != null) {
|
if (testBehavior != null) {
|
||||||
mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
|
mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
|
||||||
}
|
}
|
||||||
@@ -107,38 +117,48 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
Dependency.get(NavigationModeController.class)
|
Dependency.get(NavigationModeController.class)
|
||||||
.addListener(this::handleNavigationModeChange));
|
.addListener(this::handleNavigationModeChange));
|
||||||
|
|
||||||
setBehavior(DeviceConfig.getString(
|
setBehavior(getBehaviorMode());
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
mPhenotypeHelper.addOnPropertiesChangedListener(
|
||||||
SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
|
|
||||||
DEFAULT_BEHAVIOR.toString()));
|
|
||||||
DeviceConfig.addOnPropertyChangedListener(
|
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
|
||||||
mHandler::post,
|
mHandler::post,
|
||||||
(namespace, name, value) -> {
|
(properties) -> {
|
||||||
if (SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE.equals(name)) {
|
if (properties.getKeyset().contains(
|
||||||
setBehavior(value);
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE)) {
|
||||||
|
setBehavior(properties.getString(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, null));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Dependency.get(DumpController.class).addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override // AssistHandleCallbacks
|
||||||
public void hide() {
|
public void hide() {
|
||||||
mHandler.removeCallbacks(mHideHandles);
|
clearPendingCommands();
|
||||||
mHandler.post(mHideHandles);
|
mHandler.post(mHideHandles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override // AssistHandleCallbacks
|
||||||
public void showAndGo() {
|
public void showAndGo() {
|
||||||
mHandler.removeCallbacks(mHideHandles);
|
clearPendingCommands();
|
||||||
mHandler.post(() -> {
|
mHandler.post(mShowAndGo);
|
||||||
maybeShowHandles(/* ignoreThreshold = */ false);
|
|
||||||
mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void showAndGoInternal() {
|
||||||
|
maybeShowHandles(/* ignoreThreshold = */ false);
|
||||||
|
mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // AssistHandleCallbacks
|
||||||
|
public void showAndGoDelayed(long delayMs, boolean hideIfShowing) {
|
||||||
|
clearPendingCommands();
|
||||||
|
if (hideIfShowing) {
|
||||||
|
mHandler.post(mHideHandles);
|
||||||
|
}
|
||||||
|
mHandler.postDelayed(mShowAndGo, delayMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // AssistHandleCallbacks
|
||||||
public void showAndStay() {
|
public void showAndStay() {
|
||||||
mHandler.removeCallbacks(mHideHandles);
|
clearPendingCommands();
|
||||||
mHandler.post(() -> maybeShowHandles(/* ignoreThreshold = */ true));
|
mHandler.post(() -> maybeShowHandles(/* ignoreThreshold = */ true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,37 +198,41 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
|
|
||||||
private boolean handlesUnblocked(boolean ignoreThreshold) {
|
private boolean handlesUnblocked(boolean ignoreThreshold) {
|
||||||
long timeSinceHidden = SystemClock.elapsedRealtime() - mHandlesLastHiddenAt;
|
long timeSinceHidden = SystemClock.elapsedRealtime() - mHandlesLastHiddenAt;
|
||||||
boolean notThrottled = ignoreThreshold || timeSinceHidden > getShownFrequencyThreshold();
|
boolean notThrottled = ignoreThreshold || timeSinceHidden >= getShownFrequencyThreshold();
|
||||||
ComponentName assistantComponent =
|
ComponentName assistantComponent =
|
||||||
mAssistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser());
|
mAssistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser());
|
||||||
return notThrottled && assistantComponent != null;
|
return notThrottled && assistantComponent != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getShownFrequencyThreshold() {
|
private long getShownFrequencyThreshold() {
|
||||||
return DeviceConfig.getLong(
|
return mPhenotypeHelper.getLong(
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
|
||||||
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS,
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS,
|
||||||
DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS);
|
DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getShowAndGoDuration() {
|
private long getShowAndGoDuration() {
|
||||||
return DeviceConfig.getLong(
|
return mPhenotypeHelper.getLong(
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
|
||||||
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS,
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS,
|
||||||
DEFAULT_SHOW_AND_GO_DURATION_MS);
|
DEFAULT_SHOW_AND_GO_DURATION_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getBehaviorMode() {
|
||||||
|
return mPhenotypeHelper.getString(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
|
||||||
|
DEFAULT_BEHAVIOR.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private void maybeShowHandles(boolean ignoreThreshold) {
|
private void maybeShowHandles(boolean ignoreThreshold) {
|
||||||
if (mHandlesShowing) {
|
if (mHandlesShowing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handlesUnblocked(ignoreThreshold)) {
|
if (handlesUnblocked(ignoreThreshold)) {
|
||||||
mHandlesShowing = true;
|
|
||||||
ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
|
ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
|
||||||
if (screenDecorations == null) {
|
if (screenDecorations == null) {
|
||||||
Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
|
Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
|
||||||
} else {
|
} else {
|
||||||
|
mHandlesShowing = true;
|
||||||
screenDecorations.setAssistHintVisible(true);
|
screenDecorations.setAssistHintVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -244,14 +268,46 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearPendingCommands() {
|
||||||
|
mHandler.removeCallbacks(mHideHandles);
|
||||||
|
mHandler.removeCallbacks(mShowAndGo);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void setInGesturalModeForTest(boolean inGesturalMode) {
|
void setInGesturalModeForTest(boolean inGesturalMode) {
|
||||||
mInGesturalMode = inGesturalMode;
|
mInGesturalMode = inGesturalMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // Dumpable
|
||||||
|
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
|
pw.println("Current AssistHandleBehaviorController State:");
|
||||||
|
|
||||||
|
pw.println(" mHandlesShowing=" + mHandlesShowing);
|
||||||
|
pw.println(" mHandlesLastHiddenAt=" + mHandlesLastHiddenAt);
|
||||||
|
pw.println(" mInGesturalMode=" + mInGesturalMode);
|
||||||
|
|
||||||
|
pw.println(" Phenotype Flags:");
|
||||||
|
pw.println(" "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS
|
||||||
|
+ "="
|
||||||
|
+ getShowAndGoDuration());
|
||||||
|
pw.println(" "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS
|
||||||
|
+ "="
|
||||||
|
+ getShownFrequencyThreshold());
|
||||||
|
pw.println(" "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE
|
||||||
|
+ "="
|
||||||
|
+ getBehaviorMode());
|
||||||
|
|
||||||
|
pw.println(" mCurrentBehavior=" + mCurrentBehavior.toString());
|
||||||
|
mBehaviorMap.get(mCurrentBehavior).dump(pw, " ");
|
||||||
|
}
|
||||||
|
|
||||||
interface BehaviorController {
|
interface BehaviorController {
|
||||||
void onModeActivated(Context context, AssistHandleCallbacks callbacks);
|
void onModeActivated(Context context, AssistHandleCallbacks callbacks);
|
||||||
default void onModeDeactivated() {}
|
default void onModeDeactivated() {}
|
||||||
default void onAssistantGesturePerformed() {}
|
default void onAssistantGesturePerformed() {}
|
||||||
|
default void dump(PrintWriter pw, String prefix) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ public interface AssistHandleCallbacks {
|
|||||||
*/
|
*/
|
||||||
void showAndGo();
|
void showAndGo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as show and go, but will not do anything until a delay has elapsed.
|
||||||
|
*
|
||||||
|
* Will be cancelled if another command is given during the delay.
|
||||||
|
*/
|
||||||
|
void showAndGoDelayed(long delayMs, boolean hideIfShowing);
|
||||||
|
|
||||||
/** Show the Assistant handles. */
|
/** Show the Assistant handles. */
|
||||||
void showAndStay();
|
void showAndStay();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
|||||||
import com.android.systemui.recents.OverviewProxyService;
|
import com.android.systemui.recents.OverviewProxyService;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
|
* Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
|
||||||
* shown/hidden, respectively.
|
* shown/hidden, respectively.
|
||||||
@@ -108,4 +110,12 @@ final class AssistHandleLikeHomeBehavior implements BehaviorController {
|
|||||||
mAssistHandleCallbacks.showAndStay();
|
mAssistHandleCallbacks.showAndStay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintWriter pw, String prefix) {
|
||||||
|
pw.println("Current AssistHandleLikeHomeBehavior State:");
|
||||||
|
|
||||||
|
pw.println(prefix + " mIsDozing=" + mIsDozing);
|
||||||
|
pw.println(prefix + " mIsHomeHandleHiding=" + mIsHomeHandleHiding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,16 @@
|
|||||||
|
|
||||||
package com.android.systemui.assist;
|
package com.android.systemui.assist;
|
||||||
|
|
||||||
|
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.DeviceConfig;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -31,10 +36,14 @@ import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorContro
|
|||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.recents.OverviewProxyService;
|
import com.android.systemui.recents.OverviewProxyService;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
|
import com.android.systemui.shared.system.PackageManagerWrapper;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,8 +55,18 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
|
|
||||||
private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
|
private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
|
||||||
private static final String LEARNING_EVENT_COUNT_KEY = "reminder_exp_learning_event_count";
|
private static final String LEARNING_EVENT_COUNT_KEY = "reminder_exp_learning_event_count";
|
||||||
private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(3);
|
private static final String LEARNED_HINT_LAST_SHOWN_KEY =
|
||||||
private static final int DEFAULT_LEARNING_COUNT = 3;
|
"reminder_exp_learned_hint_last_shown";
|
||||||
|
private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(200);
|
||||||
|
private static final int DEFAULT_LEARNING_COUNT = 30000;
|
||||||
|
private static final long DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS = 150;
|
||||||
|
private static final long DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
|
||||||
|
TimeUnit.SECONDS.toMillis(1);
|
||||||
|
private static final long DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
|
||||||
|
TimeUnit.SECONDS.toMillis(3);
|
||||||
|
private static final boolean DEFAULT_SUPPRESS_ON_LOCKSCREEN = false;
|
||||||
|
private static final boolean DEFAULT_SUPPRESS_ON_LAUNCHER = false;
|
||||||
|
private static final boolean DEFAULT_SUPPRESS_ON_APPS = false;
|
||||||
|
|
||||||
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
||||||
new StatusBarStateController.StateListener() {
|
new StatusBarStateController.StateListener() {
|
||||||
@@ -64,13 +83,13 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
private final TaskStackChangeListener mTaskStackChangeListener =
|
private final TaskStackChangeListener mTaskStackChangeListener =
|
||||||
new TaskStackChangeListener() {
|
new TaskStackChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onTaskMovedToFront(int taskId) {
|
public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
|
||||||
handleTaskStackTopChanged(taskId);
|
handleTaskStackTopChanged(taskInfo.taskId, taskInfo.topActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskCreated(int taskId, ComponentName componentName) {
|
public void onTaskCreated(int taskId, ComponentName componentName) {
|
||||||
handleTaskStackTopChanged(taskId);
|
handleTaskStackTopChanged(taskId, componentName);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
|
private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
|
||||||
@@ -85,7 +104,18 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
handleSystemUiStateChanged(sysuiStateFlags);
|
handleSystemUiStateChanged(sysuiStateFlags);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private final BroadcastReceiver mDefaultHomeBroadcastReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
mDefaultHome = getCurrentDefaultHome();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final IntentFilter mDefaultHomeIntentFilter =
|
||||||
|
new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED);
|
||||||
|
private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;
|
||||||
|
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final PhenotypeHelper mPhenotypeHelper;
|
||||||
private final StatusBarStateController mStatusBarStateController;
|
private final StatusBarStateController mStatusBarStateController;
|
||||||
private final ActivityManagerWrapper mActivityManagerWrapper;
|
private final ActivityManagerWrapper mActivityManagerWrapper;
|
||||||
private final OverviewProxyService mOverviewProxyService;
|
private final OverviewProxyService mOverviewProxyService;
|
||||||
@@ -94,6 +124,8 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
private boolean mIsDozing;
|
private boolean mIsDozing;
|
||||||
private int mRunningTaskId;
|
private int mRunningTaskId;
|
||||||
private boolean mIsNavBarHidden;
|
private boolean mIsNavBarHidden;
|
||||||
|
private boolean mIsLauncherShowing;
|
||||||
|
private int mConsecutiveTaskSwitches;
|
||||||
|
|
||||||
/** Whether user has learned the gesture. */
|
/** Whether user has learned the gesture. */
|
||||||
private boolean mIsLearned;
|
private boolean mIsLearned;
|
||||||
@@ -102,11 +134,15 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
private long mLearningTimeElapsed;
|
private long mLearningTimeElapsed;
|
||||||
/** Number of successful Assistant invocations while in this behavior. */
|
/** Number of successful Assistant invocations while in this behavior. */
|
||||||
private int mLearningCount;
|
private int mLearningCount;
|
||||||
|
private long mLearnedHintLastShownEpochDay;
|
||||||
|
|
||||||
@Nullable private Context mContext;
|
@Nullable private Context mContext;
|
||||||
@Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
|
@Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
|
||||||
|
@Nullable private ComponentName mDefaultHome;
|
||||||
|
|
||||||
AssistHandleReminderExpBehavior() {
|
AssistHandleReminderExpBehavior(Handler handler, PhenotypeHelper phenotypeHelper) {
|
||||||
|
mHandler = handler;
|
||||||
|
mPhenotypeHelper = phenotypeHelper;
|
||||||
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
|
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
|
||||||
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
|
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
|
||||||
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
|
||||||
@@ -116,6 +152,9 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
|
public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mAssistHandleCallbacks = callbacks;
|
mAssistHandleCallbacks = callbacks;
|
||||||
|
mConsecutiveTaskSwitches = 0;
|
||||||
|
mDefaultHome = getCurrentDefaultHome();
|
||||||
|
context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
|
||||||
mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
|
mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
|
||||||
mIsDozing = mStatusBarStateController.isDozing();
|
mIsDozing = mStatusBarStateController.isDozing();
|
||||||
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
mStatusBarStateController.addCallback(mStatusBarStateListener);
|
||||||
@@ -128,6 +167,8 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
|
context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
|
||||||
mLearningCount = Settings.Secure.getInt(
|
mLearningCount = Settings.Secure.getInt(
|
||||||
context.getContentResolver(), LEARNING_EVENT_COUNT_KEY, /* default = */ 0);
|
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 = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
callbackForCurrentState(/* justUnlocked = */ false);
|
callbackForCurrentState(/* justUnlocked = */ false);
|
||||||
@@ -137,10 +178,10 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
public void onModeDeactivated() {
|
public void onModeDeactivated() {
|
||||||
mAssistHandleCallbacks = null;
|
mAssistHandleCallbacks = null;
|
||||||
if (mContext != null) {
|
if (mContext != null) {
|
||||||
Settings.Secure.putLong(
|
mContext.unregisterReceiver(mDefaultHomeBroadcastReceiver);
|
||||||
mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
|
Settings.Secure.putLong(mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, 0);
|
||||||
Settings.Secure.putInt(
|
Settings.Secure.putInt(mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, 0);
|
||||||
mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, mLearningCount);
|
Settings.Secure.putLong(mContext.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, 0);
|
||||||
mContext = null;
|
mContext = null;
|
||||||
}
|
}
|
||||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
||||||
@@ -162,12 +203,18 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
|
return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static ComponentName getCurrentDefaultHome() {
|
||||||
|
return PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
private void handleStatusBarStateChanged(int newState) {
|
private void handleStatusBarStateChanged(int newState) {
|
||||||
boolean onLockscreen = onLockscreen(newState);
|
boolean onLockscreen = onLockscreen(newState);
|
||||||
if (mOnLockscreen == onLockscreen) {
|
if (mOnLockscreen == onLockscreen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetConsecutiveTaskSwitches();
|
||||||
mOnLockscreen = onLockscreen;
|
mOnLockscreen = onLockscreen;
|
||||||
callbackForCurrentState(!onLockscreen);
|
callbackForCurrentState(!onLockscreen);
|
||||||
}
|
}
|
||||||
@@ -177,16 +224,24 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetConsecutiveTaskSwitches();
|
||||||
mIsDozing = isDozing;
|
mIsDozing = isDozing;
|
||||||
callbackForCurrentState(/* justUnlocked = */ false);
|
callbackForCurrentState(/* justUnlocked = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTaskStackTopChanged(int taskId) {
|
private void handleTaskStackTopChanged(int taskId, @Nullable ComponentName taskComponentName) {
|
||||||
if (mRunningTaskId == taskId) {
|
if (mRunningTaskId == taskId || taskComponentName == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRunningTaskId = taskId;
|
mRunningTaskId = taskId;
|
||||||
|
mIsLauncherShowing = taskComponentName.equals(mDefaultHome);
|
||||||
|
if (mIsLauncherShowing) {
|
||||||
|
resetConsecutiveTaskSwitches();
|
||||||
|
} else {
|
||||||
|
rescheduleConsecutiveTaskSwitchesReset();
|
||||||
|
mConsecutiveTaskSwitches++;
|
||||||
|
}
|
||||||
callbackForCurrentState(/* justUnlocked = */ false);
|
callbackForCurrentState(/* justUnlocked = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,11 +251,13 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetConsecutiveTaskSwitches();
|
||||||
mIsNavBarHidden = isNavBarHidden;
|
mIsNavBarHidden = isNavBarHidden;
|
||||||
callbackForCurrentState(/* justUnlocked = */ false);
|
callbackForCurrentState(/* justUnlocked = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleOverviewShown() {
|
private void handleOverviewShown() {
|
||||||
|
resetConsecutiveTaskSwitches();
|
||||||
callbackForCurrentState(/* justUnlocked = */ false);
|
callbackForCurrentState(/* justUnlocked = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +284,17 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
if (mIsDozing || mIsNavBarHidden || mOnLockscreen) {
|
if (mIsDozing || mIsNavBarHidden || mOnLockscreen) {
|
||||||
mAssistHandleCallbacks.hide();
|
mAssistHandleCallbacks.hide();
|
||||||
} else if (justUnlocked) {
|
} else if (justUnlocked) {
|
||||||
mAssistHandleCallbacks.showAndGo();
|
long currentEpochDay = LocalDate.now().toEpochDay();
|
||||||
|
if (mLearnedHintLastShownEpochDay < currentEpochDay) {
|
||||||
|
if (mContext != null) {
|
||||||
|
Settings.Secure.putLong(
|
||||||
|
mContext.getContentResolver(),
|
||||||
|
LEARNED_HINT_LAST_SHOWN_KEY,
|
||||||
|
currentEpochDay);
|
||||||
|
}
|
||||||
|
mLearnedHintLastShownEpochDay = currentEpochDay;
|
||||||
|
mAssistHandleCallbacks.showAndGo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,12 +303,28 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIsDozing || mIsNavBarHidden) {
|
if (mIsDozing || mIsNavBarHidden || isSuppressed()) {
|
||||||
mAssistHandleCallbacks.hide();
|
mAssistHandleCallbacks.hide();
|
||||||
} else if (mOnLockscreen) {
|
} else if (mOnLockscreen) {
|
||||||
mAssistHandleCallbacks.showAndStay();
|
mAssistHandleCallbacks.showAndStay();
|
||||||
} else {
|
} else if (mIsLauncherShowing) {
|
||||||
mAssistHandleCallbacks.showAndGo();
|
mAssistHandleCallbacks.showAndGo();
|
||||||
|
} else if (mConsecutiveTaskSwitches == 1) {
|
||||||
|
mAssistHandleCallbacks.showAndGoDelayed(
|
||||||
|
getShowAndGoDelayedShortDelayMs(), /* hideIfShowing = */ false);
|
||||||
|
} else {
|
||||||
|
mAssistHandleCallbacks.showAndGoDelayed(
|
||||||
|
getShowAndGoDelayedLongDelayMs(), /* hideIfShowing = */ true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSuppressed() {
|
||||||
|
if (mOnLockscreen) {
|
||||||
|
return getSuppressOnLockscreen();
|
||||||
|
} else if (mIsLauncherShowing) {
|
||||||
|
return getSuppressOnLauncher();
|
||||||
|
} else {
|
||||||
|
return getSuppressOnApps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,17 +343,114 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
|
|||||||
mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
|
mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void resetConsecutiveTaskSwitches() {
|
||||||
|
mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
|
||||||
|
mConsecutiveTaskSwitches = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rescheduleConsecutiveTaskSwitchesReset() {
|
||||||
|
mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
|
||||||
|
mHandler.postDelayed(mResetConsecutiveTaskSwitches, getShowAndGoDelayResetTimeoutMs());
|
||||||
|
}
|
||||||
|
|
||||||
private long getLearningTimeMs() {
|
private long getLearningTimeMs() {
|
||||||
return DeviceConfig.getLong(
|
return mPhenotypeHelper.getLong(
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
|
||||||
SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS,
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS,
|
||||||
DEFAULT_LEARNING_TIME_MS);
|
DEFAULT_LEARNING_TIME_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getLearningCount() {
|
private int getLearningCount() {
|
||||||
return DeviceConfig.getInt(
|
return mPhenotypeHelper.getInt(
|
||||||
DeviceConfig.NAMESPACE_SYSTEMUI,
|
|
||||||
SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT,
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT,
|
||||||
DEFAULT_LEARNING_COUNT);
|
DEFAULT_LEARNING_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long getShowAndGoDelayedShortDelayMs() {
|
||||||
|
return mPhenotypeHelper.getLong(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS,
|
||||||
|
DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getShowAndGoDelayedLongDelayMs() {
|
||||||
|
return mPhenotypeHelper.getLong(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS,
|
||||||
|
DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getShowAndGoDelayResetTimeoutMs() {
|
||||||
|
return mPhenotypeHelper.getLong(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS,
|
||||||
|
DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getSuppressOnLockscreen() {
|
||||||
|
return mPhenotypeHelper.getBoolean(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN,
|
||||||
|
DEFAULT_SUPPRESS_ON_LOCKSCREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getSuppressOnLauncher() {
|
||||||
|
return mPhenotypeHelper.getBoolean(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER,
|
||||||
|
DEFAULT_SUPPRESS_ON_LAUNCHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getSuppressOnApps() {
|
||||||
|
return mPhenotypeHelper.getBoolean(
|
||||||
|
SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS,
|
||||||
|
DEFAULT_SUPPRESS_ON_APPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump(PrintWriter pw, String prefix) {
|
||||||
|
pw.println(prefix + "Current AssistHandleReminderExpBehavior State:");
|
||||||
|
pw.println(prefix + " mOnLockscreen=" + mOnLockscreen);
|
||||||
|
pw.println(prefix + " mIsDozing=" + mIsDozing);
|
||||||
|
pw.println(prefix + " mRunningTaskId=" + mRunningTaskId);
|
||||||
|
pw.println(prefix + " mDefaultHome=" + mDefaultHome);
|
||||||
|
pw.println(prefix + " mIsNavBarHidden=" + mIsNavBarHidden);
|
||||||
|
pw.println(prefix + " mIsLauncherShowing=" + mIsLauncherShowing);
|
||||||
|
pw.println(prefix + " mConsecutiveTaskSwitches=" + mConsecutiveTaskSwitches);
|
||||||
|
pw.println(prefix + " mIsLearned=" + mIsLearned);
|
||||||
|
pw.println(prefix + " mLastLearningTimestamp=" + mLastLearningTimestamp);
|
||||||
|
pw.println(prefix + " mLearningTimeElapsed=" + mLearningTimeElapsed);
|
||||||
|
pw.println(prefix + " mLearningCount=" + mLearningCount);
|
||||||
|
pw.println(prefix + " mLearnedHintLastShownEpochDay=" + mLearnedHintLastShownEpochDay);
|
||||||
|
pw.println(
|
||||||
|
prefix + " mAssistHandleCallbacks present: " + (mAssistHandleCallbacks != null));
|
||||||
|
|
||||||
|
pw.println(prefix + " Phenotype Flags:");
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS
|
||||||
|
+ "="
|
||||||
|
+ getLearningTimeMs());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT
|
||||||
|
+ "="
|
||||||
|
+ getLearningCount());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS
|
||||||
|
+ "="
|
||||||
|
+ getShowAndGoDelayedShortDelayMs());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS
|
||||||
|
+ "="
|
||||||
|
+ getShowAndGoDelayedLongDelayMs());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS
|
||||||
|
+ "="
|
||||||
|
+ getShowAndGoDelayResetTimeoutMs());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN
|
||||||
|
+ "="
|
||||||
|
+ getSuppressOnLockscreen());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER
|
||||||
|
+ "="
|
||||||
|
+ getSuppressOnLauncher());
|
||||||
|
pw.println(prefix + " "
|
||||||
|
+ SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS
|
||||||
|
+ "="
|
||||||
|
+ getSuppressOnApps());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.assist;
|
||||||
|
|
||||||
|
import android.provider.DeviceConfig;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
class PhenotypeHelper {
|
||||||
|
|
||||||
|
PhenotypeHelper() {}
|
||||||
|
|
||||||
|
long getLong(String name, long defaultValue) {
|
||||||
|
return DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getInt(String name, int defaultValue) {
|
||||||
|
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String getString(String name, @Nullable String defaultValue) {
|
||||||
|
return DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean getBoolean(String name, boolean defaultValue) {
|
||||||
|
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addOnPropertiesChangedListener(
|
||||||
|
Executor executor, DeviceConfig.OnPropertiesChangedListener listener) {
|
||||||
|
DeviceConfig.addOnPropertiesChangedListener(
|
||||||
|
DeviceConfig.NAMESPACE_SYSTEMUI, executor, listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import static org.mockito.AdditionalAnswers.answerVoid;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
@@ -35,11 +36,13 @@ import android.testing.TestableLooper.RunWithLooper;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.internal.app.AssistUtils;
|
import com.android.internal.app.AssistUtils;
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
||||||
import com.android.systemui.ScreenDecorations;
|
import com.android.systemui.ScreenDecorations;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.recents.OverviewProxyService;
|
import com.android.systemui.recents.OverviewProxyService;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -59,6 +62,7 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase {
|
|||||||
@Mock private ScreenDecorations mMockScreenDecorations;
|
@Mock private ScreenDecorations mMockScreenDecorations;
|
||||||
@Mock private AssistUtils mMockAssistUtils;
|
@Mock private AssistUtils mMockAssistUtils;
|
||||||
@Mock private Handler mMockHandler;
|
@Mock private Handler mMockHandler;
|
||||||
|
@Mock private PhenotypeHelper mMockPhenotypeHelper;
|
||||||
@Mock private AssistHandleBehaviorController.BehaviorController mMockBehaviorController;
|
@Mock private AssistHandleBehaviorController.BehaviorController mMockBehaviorController;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -69,14 +73,21 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase {
|
|||||||
doAnswer(answerVoid(Runnable::run)).when(mMockHandler).post(any(Runnable.class));
|
doAnswer(answerVoid(Runnable::run)).when(mMockHandler).post(any(Runnable.class));
|
||||||
doAnswer(answerVoid(Runnable::run)).when(mMockHandler)
|
doAnswer(answerVoid(Runnable::run)).when(mMockHandler)
|
||||||
.postDelayed(any(Runnable.class), anyLong());
|
.postDelayed(any(Runnable.class), anyLong());
|
||||||
|
|
||||||
mAssistHandleBehaviorController =
|
mAssistHandleBehaviorController =
|
||||||
new AssistHandleBehaviorController(
|
new AssistHandleBehaviorController(
|
||||||
mContext,
|
mContext,
|
||||||
mMockAssistUtils,
|
mMockAssistUtils,
|
||||||
mMockHandler, () -> mMockScreenDecorations,
|
mMockHandler, () -> mMockScreenDecorations,
|
||||||
|
mMockPhenotypeHelper,
|
||||||
mMockBehaviorController);
|
mMockBehaviorController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void teardown() {
|
||||||
|
mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.OFF);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hide_hidesHandlesWhenShowing() {
|
public void hide_hidesHandlesWhenShowing() {
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -185,6 +196,9 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase {
|
|||||||
public void showAndGo_doesNothingIfRecentlyHidden() {
|
public void showAndGo_doesNothingIfRecentlyHidden() {
|
||||||
// Arrange
|
// Arrange
|
||||||
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
||||||
|
when(mMockPhenotypeHelper.getLong(
|
||||||
|
eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
|
||||||
|
anyLong())).thenReturn(10000L);
|
||||||
mAssistHandleBehaviorController.showAndGo();
|
mAssistHandleBehaviorController.showAndGo();
|
||||||
reset(mMockScreenDecorations);
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
@@ -209,6 +223,87 @@ public class AssistHandleBehaviorControllerTest extends SysuiTestCase {
|
|||||||
verifyNoMoreInteractions(mMockScreenDecorations);
|
verifyNoMoreInteractions(mMockScreenDecorations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showAndGoDelayed_showsThenHidesHandlesWhenHiding() {
|
||||||
|
// Arrange
|
||||||
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
||||||
|
mAssistHandleBehaviorController.hide();
|
||||||
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
InOrder inOrder = inOrder(mMockScreenDecorations);
|
||||||
|
inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
|
||||||
|
inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showAndGoDelayed_hidesHandlesAfterTimeoutWhenShowing() {
|
||||||
|
// Arrange
|
||||||
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
||||||
|
mAssistHandleBehaviorController.showAndStay();
|
||||||
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verify(mMockScreenDecorations).setAssistHintVisible(false);
|
||||||
|
verifyNoMoreInteractions(mMockScreenDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showAndGoDelayed_hidesInitiallyThenShowsThenHidesAfterTimeoutWhenHideRequested() {
|
||||||
|
// Arrange
|
||||||
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
||||||
|
mAssistHandleBehaviorController.showAndStay();
|
||||||
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mAssistHandleBehaviorController.showAndGoDelayed(1000, true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
InOrder inOrder = inOrder(mMockScreenDecorations);
|
||||||
|
inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
|
||||||
|
inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
|
||||||
|
inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
|
||||||
|
inOrder.verifyNoMoreInteractions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showAndGoDelayed_doesNothingIfRecentlyHidden() {
|
||||||
|
// Arrange
|
||||||
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
|
||||||
|
when(mMockPhenotypeHelper.getLong(
|
||||||
|
eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
|
||||||
|
anyLong())).thenReturn(10000L);
|
||||||
|
mAssistHandleBehaviorController.showAndGo();
|
||||||
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verifyNoMoreInteractions(mMockScreenDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void showAndGoDelayed_doesNothingWhenThereIsNoAssistant() {
|
||||||
|
// Arrange
|
||||||
|
when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null);
|
||||||
|
mAssistHandleBehaviorController.hide();
|
||||||
|
reset(mMockScreenDecorations);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
verifyNoMoreInteractions(mMockScreenDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setBehavior_activatesTheBehaviorWhenInGesturalMode() {
|
public void setBehavior_activatesTheBehaviorWhenInGesturalMode() {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|||||||
Reference in New Issue
Block a user