Merge "Decrease predicted icon outline size" into ub-launcher3-rvc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index d552daf..c6e8c20b 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -38,7 +38,7 @@
optional ContainerInfo container_info = 7;
// Stores the origin of the Item
- optional Origin source = 8;
+ optional Attribute attribute = 8;
}
// Represents various launcher surface where items are placed.
@@ -52,6 +52,7 @@
PredictionContainer prediction_container = 6;
SearchResultContainer search_result_container = 7;
ShortcutsContainer shortcuts_container = 8;
+ SettingsContainer settings_container = 9;
}
}
@@ -75,7 +76,12 @@
message ShortcutsContainer {
}
-enum Origin {
+// Container for generic system shortcuts for launcher specific settings.
+// Typically shown up as popup window by longpressing on empty space on workspace.
+message SettingsContainer {
+}
+
+enum Attribute {
UNKNOWN = 0;
DEFAULT_LAYOUT = 1; // icon automatically placed in workspace, folder, hotseat
BACKUP_RESTORE = 2; // icon layout restored from backup
@@ -85,6 +91,8 @@
ADD_TO_HOMESCREEN = 6; // play install + launcher home setting
ALLAPPS_PREDICTION = 7; // from prediction bar in all apps container
HOTSEAT_PREDICTION = 8; // from prediction bar in hotseat container
+ SUGGESTED_LABEL = 9; // folder icon's label was suggested
+ MANUAL_LABEL = 10; // folder icon's label was manually edited
}
// Main app icons
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
index d4cc129..44691d3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -31,6 +31,7 @@
import android.util.AttributeSet;
import android.util.IntProperty;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
@@ -241,8 +242,9 @@
while (getChildCount() > mNumPredictedAppsPerRow) {
removeViewAt(0);
}
+ LayoutInflater inflater = mLauncher.getAppsView().getLayoutInflater();
while (getChildCount() < mNumPredictedAppsPerRow) {
- BubbleTextView icon = (BubbleTextView) mLauncher.getLayoutInflater().inflate(
+ BubbleTextView icon = (BubbleTextView) inflater.inflate(
R.layout.all_apps_icon, this, false);
icon.setOnClickListener(PREDICTION_CLICK_LISTENER);
icon.setOnLongClickListener(ItemLongClickListener.INSTANCE_ALL_APPS);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 725f516..bd4d713 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -326,7 +326,7 @@
}
private void setPredictedApps(List<AppTarget> appTargets) {
mComponentKeyMappers.clear();
- if (appTargets.isEmpty() && mRestoreHelper.shouldRestoreToBackup()) {
+ if (appTargets.isEmpty()) {
mRestoreHelper.restoreBackup();
}
StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
index c95ff7a..8c1db4e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.LauncherSettings.Favorites.HYBRID_HOTSEAT_BACKUP_TABLE;
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
@@ -29,72 +30,57 @@
*/
public class HotseatRestoreHelper {
private final Launcher mLauncher;
- private boolean mBackupExists;
+ private boolean mBackupRestored = false;
HotseatRestoreHelper(Launcher context) {
mLauncher = context;
- setupBackupTable();
}
/**
* Creates a snapshot backup of Favorite table for future restoration use.
*/
- public synchronized void createBackup() {
- try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
- LauncherSettings.Settings.call(
- mLauncher.getContentResolver(),
- LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
- .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
- InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
- GridBackupTable backupTable = new GridBackupTable(mLauncher,
- transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
- idp.numRows);
- backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE);
- transaction.commit();
- LauncherSettings.Settings.call(mLauncher.getContentResolver(),
- LauncherSettings.Settings.METHOD_REFRESH_HOTSEAT_RESTORE_TABLE);
- mBackupExists = true;
- }
+ public void createBackup() {
+ MODEL_EXECUTOR.execute(() -> {
+ try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
+ LauncherSettings.Settings.call(
+ mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
+ InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+ GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ idp.numRows);
+ backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE);
+ transaction.commit();
+ LauncherSettings.Settings.call(mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_REFRESH_HOTSEAT_RESTORE_TABLE);
+ }
+ });
}
/**
* Finds and restores a previously saved snapshow of Favorites table
*/
public void restoreBackup() {
- try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
- LauncherSettings.Settings.call(
- mLauncher.getContentResolver(),
- LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
- .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
- if (!tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE)) {
- mBackupExists = false;
- return;
+ if (mBackupRestored) return;
+ MODEL_EXECUTOR.execute(() -> {
+ try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
+ LauncherSettings.Settings.call(
+ mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
+ if (!tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE)) {
+ return;
+ }
+ InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+ GridBackupTable backupTable = new GridBackupTable(mLauncher,
+ transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ idp.numRows);
+ backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true);
+ transaction.commit();
+ mBackupRestored = true;
+ mLauncher.getModel().forceReload();
}
- InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
- GridBackupTable backupTable = new GridBackupTable(mLauncher,
- transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
- idp.numRows);
- backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true);
- transaction.commit();
- mBackupExists = false;
- mLauncher.getModel().forceReload();
- }
- }
-
- /**
- * Returns if prediction controller should attempt restoring a backup
- */
- public synchronized boolean shouldRestoreToBackup() {
- return mBackupExists;
- }
-
- private synchronized void setupBackupTable() {
- try (LauncherDbUtils.SQLiteTransaction transaction = (LauncherDbUtils.SQLiteTransaction)
- LauncherSettings.Settings.call(
- mLauncher.getContentResolver(),
- LauncherSettings.Settings.METHOD_NEW_TRANSACTION)
- .getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
- mBackupExists = tableExists(transaction.getDb(), HYBRID_HOTSEAT_BACKUP_TABLE);
- }
+ });
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index e5782e7..de83caf 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -53,14 +53,17 @@
private final BaseActivityInterface<?, T> mActivityInterface;
// The id of the currently running task that is transitioning to overview.
private final int mTargetTaskId;
+ private final RecentsAnimationDeviceState mDeviceState;
private T mActivity;
private RecentsView mRecentsView;
AppToOverviewAnimationProvider(
- BaseActivityInterface<?, T> activityInterface, int targetTaskId) {
+ BaseActivityInterface<?, T> activityInterface, int targetTaskId,
+ RecentsAnimationDeviceState deviceState) {
mActivityInterface = activityInterface;
mTargetTaskId = targetTaskId;
+ mDeviceState = deviceState;
}
/**
@@ -73,6 +76,7 @@
activity.<RecentsView>getOverviewPanel().showCurrentTask(mTargetTaskId);
AbstractFloatingView.closeAllOpenViews(activity, wasVisible);
BaseActivityInterface.AnimationFactory factory = mActivityInterface.prepareRecentsUI(
+ mDeviceState,
wasVisible, (controller) -> {
controller.dispatchOnStart();
controller.getAnimationPlayer().end();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 6cbe794..b5fb31a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -300,9 +300,6 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "BaseSwipeUpHandler.2");
}
- ((RecentsView) createdActivity.getOverviewPanel())
- .setLayoutRotation(mDeviceState.getCurrentActiveRotation(),
- mDeviceState.getDisplayRotation());
initTransitionEndpoints(InvariantDeviceProfile.INSTANCE.get(mContext)
.getDeviceProfile(mContext));
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
index 92e10b1..414d7ae 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandlerV2.java
@@ -41,6 +41,7 @@
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
@@ -78,9 +79,11 @@
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.TaskStackChangeListener;
/**
* Handles the navigation gestures when Launcher is the default home activity.
@@ -331,7 +334,7 @@
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
if (mGestureState.getEndTarget() != HOME) {
Runnable initAnimFactory = () -> {
- mAnimationFactory = mActivityInterface.prepareRecentsUI(
+ mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
maybeUpdateRecentsAttachedState(false /* animate */);
};
@@ -900,6 +903,21 @@
protected abstract HomeAnimationFactory createHomeAnimationFactory(long duration);
+ private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() {
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ if (task.taskId == mGestureState.getRunningTaskId()) {
+ // Since this is an edge case, just cancel and relaunch with default activity
+ // options (since we don't know if there's an associated app icon to launch from)
+ endRunningWindowAnim(true /* cancel */);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
+ mActivityRestartListener);
+ ActivityManagerWrapper.getInstance().startActivityFromRecents(task.taskId, null);
+ }
+ }
+ };
+
@UiThread
private void animateToProgressInternal(float start, float end, long duration,
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
@@ -907,6 +925,13 @@
mGestureState.setEndTarget(target, false /* isAtomic */);
maybeUpdateRecentsAttachedState();
+ // If we are transitioning to launcher, then listen for the activity to be restarted while
+ // the transition is in progress
+ if (mGestureState.getEndTarget().isLauncher) {
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(
+ mActivityRestartListener);
+ }
+
if (mGestureState.getEndTarget() == HOME) {
HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(duration);
RectFSpringAnim windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
@@ -1127,6 +1152,7 @@
}
mActivityInitListener.unregister();
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
mTaskSnapshot = null;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java
index 70be3ab..33b9cde 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityInterface.java
@@ -83,7 +83,7 @@
/** 6 */
@Override
- public AnimationFactory prepareRecentsUI(
+ public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
factory.initUI();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index 4801d71..6751723 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -118,8 +118,11 @@
}
@Override
- public AnimationFactory prepareRecentsUI(
+ public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
+ ((RecentsView) getCreatedActivity().getOverviewPanel())
+ .setLayoutRotation(deviceState.getCurrentActiveRotation(),
+ deviceState.getDisplayRotation());
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
@Override
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
index 8846727..434a929 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
@@ -165,7 +165,7 @@
mActivityInterface = mOverviewComponentObserver.getActivityInterface();
mCreateTime = SystemClock.elapsedRealtime();
mAnimationProvider = new AppToOverviewAnimationProvider<>(mActivityInterface,
- RecentsModel.getRunningTaskId());
+ RecentsModel.getRunningTaskId(), mDeviceState);
// Preload the plan
mRecentsModel.getTasks(null);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 3cfff7e..97cd11b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -18,12 +18,16 @@
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Rect;
+import android.os.Build;
import android.widget.Toast;
+import androidx.annotation.RequiresApi;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
@@ -122,6 +126,7 @@
}
}
+ @SuppressLint("NewApi")
@Override
public void onScreenshot() {
if (isAllowedByPolicy) {
@@ -159,9 +164,9 @@
*
* @return the insets in screen coordinates.
*/
+ @RequiresApi(api = Build.VERSION_CODES.Q)
public Insets getTaskSnapshotInsets() {
- // TODO: return the real insets
- return Insets.of(0, 0, 0, 0);
+ return mThumbnailView.getScaledInsets();
}
private void showBlockedByPolicyMessage() {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 6f596e9..4ca4e4c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -24,7 +24,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
-import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
@@ -609,7 +608,7 @@
// If Bubbles is expanded, use the overlay input consumer, which will close Bubbles
// instead of going all the way home when a swipe up is detected.
- if (mDeviceState.isBubblesExpanded()) {
+ if (mDeviceState.isBubblesExpanded() || mDeviceState.isGlobalActionsShowing()) {
base = new SysUiOverlayInputConsumer(
getBaseContext(), mDeviceState, mInputMonitorCompat);
}
@@ -636,9 +635,7 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "handleOrientationSetup.1");
}
- if (!isFixedRotationTransformEnabled()) {
- return;
- }
+
baseInputConsumer.notifyOrientationSetup();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index e7b965b..8daa982 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
@@ -41,6 +42,7 @@
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.statehandlers.DepthController;
@@ -67,7 +69,7 @@
private final AnimatorSet mAnimators = new AnimatorSet();
public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim) {
- prepareToAnimate(launcher);
+ prepareToAnimate(launcher, animateOverviewScrim);
mVelocity = velocity;
@@ -129,8 +131,9 @@
}
if (animateOverviewScrim) {
- addScrimAnimationForState(launcher, BACKGROUND_APP, 0);
- addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
+ PendingAnimation pendingAnimation = new PendingAnimation(ALPHA_DURATION_MS);
+ addScrimAnimationForState(launcher, NORMAL, pendingAnimation);
+ mAnimators.play(pendingAnimation.buildAnim());
}
addDepthAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
@@ -153,7 +156,7 @@
/**
* Setup workspace with 0 duration to prepare for our staggered animation.
*/
- private void prepareToAnimate(Launcher launcher) {
+ private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
StateAnimationConfig config = new StateAnimationConfig();
config.animFlags = ANIM_ALL_COMPONENTS | SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER;
config.duration = 0;
@@ -162,6 +165,10 @@
// Stop scrolling so that it doesn't interfere with the translation offscreen.
launcher.<RecentsView>getOverviewPanel().getScroller().forceFinished(true);
+
+ if (animateOverviewScrim) {
+ addScrimAnimationForState(launcher, BACKGROUND_APP, NO_ANIM_PROPERTY_SETTER);
+ }
}
public AnimatorSet getAnimators() {
@@ -224,15 +231,14 @@
mAnimators.play(alpha);
}
- private void addScrimAnimationForState(Launcher launcher, LauncherState state, long duration) {
- PendingAnimation builder = new PendingAnimation(duration);
- launcher.getWorkspace().getStateTransitionAnimation().setScrim(builder, state);
- builder.setFloat(
+ private void addScrimAnimationForState(Launcher launcher, LauncherState state,
+ PropertySetter setter) {
+ launcher.getWorkspace().getStateTransitionAnimation().setScrim(setter, state);
+ setter.setFloat(
launcher.getDragLayer().getOverviewScrim(),
OverviewScrim.SCRIM_PROGRESS,
state.getOverviewScrimAlpha(launcher),
ACCEL_DEACCEL);
- mAnimators.play(builder.buildAnim());
}
private void addDepthAnimationForState(Launcher launcher, LauncherState state, long duration) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
index df89f74..6b99f90 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/AllAppsEduView.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_7;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALL_APPS_EDU_SHOWN;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import android.animation.Animator;
@@ -231,6 +232,8 @@
launcher, parent);
view.init(launcher);
launcher.getDragLayer().addView(view);
+ launcher.getStatsLogManager().log(LAUNCHER_ALL_APPS_EDU_SHOWN);
+
view.requestLayout();
view.playAnimation();
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 68cc481..a19026b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -33,6 +33,7 @@
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.Surface;
import android.widget.FrameLayout;
import com.android.launcher3.BaseQuickstepLauncher;
@@ -225,6 +226,7 @@
public void reset() {
super.reset();
+ setLayoutRotation(Surface.ROTATION_0, Surface.ROTATION_0);
// We are moving to home or some other UI with no recents. Switch back to the home client,
// the home predictions should have been updated when the activity was resumed.
PredictionUiStateManager.INSTANCE.get(getContext()).switchClient(Client.HOME);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
index 08c3dc9..95eb10f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/OverviewActionsView.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -31,6 +32,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
+import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -45,7 +47,9 @@
* View for showing action buttons in Overview
*/
public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayout
- implements OnClickListener {
+ implements OnClickListener, Insettable {
+
+ private final Rect mInsets = new Rect();
@IntDef(flag = true, value = {
HIDDEN_UNSUPPORTED_NAVIGATION,
@@ -137,6 +141,12 @@
updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
}
+ @Override
+ public void setInsets(Rect insets) {
+ mInsets.set(insets);
+ updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ }
+
public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
if (enable) {
mHiddenFlags |= visibilityFlags;
@@ -173,6 +183,7 @@
bottomMargin = getResources()
.getDimensionPixelSize(R.dimen.overview_actions_bottom_margin_gesture);
}
+ bottomMargin += mInsets.bottom;
LayoutParams params = (LayoutParams) getLayoutParams();
params.setMargins(
params.leftMargin, params.topMargin, params.rightMargin, bottomMargin);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 64d90cf..98784ef 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -1900,7 +1900,7 @@
anim.play(depthAnimator);
}
anim.play(progressAnim);
- anim.setDuration(duration).setInterpolator(interpolator);
+ anim.setInterpolator(interpolator);
mPendingAnimation = new PendingAnimation(duration);
mPendingAnimation.add(anim);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
index 3299736..a371dd2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -27,6 +27,7 @@
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
@@ -34,17 +35,21 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
+import android.os.Build;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
import android.view.Surface;
import android.view.View;
+import androidx.annotation.RequiresApi;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
import com.android.quickstep.TaskOverlayFactory;
@@ -63,9 +68,9 @@
private static final ColorMatrix COLOR_MATRIX = new ColorMatrix();
private static final ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
- private static final RectF EMPTY_RECT_F = new RectF();
- private static final FullscreenDrawParams TEMP_PARAMS = new FullscreenDrawParams();
+ private static final MainThreadInitializedObject<FullscreenDrawParams> TEMP_PARAMS =
+ new MainThreadInitializedObject<>(FullscreenDrawParams::new);
public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
new FloatProperty<TaskThumbnailView>("dimAlpha") {
@@ -91,8 +96,7 @@
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
private final Rect mPreviewRect = new Rect();
private final PreviewPositionHelper mPreviewPositionHelper = new PreviewPositionHelper();
- // Initialize with dummy value. It is overridden later by TaskView
- private TaskView.FullscreenDrawParams mFullscreenParams = TEMP_PARAMS;
+ private TaskView.FullscreenDrawParams mFullscreenParams;
private Task mTask;
private ThumbnailData mThumbnailData;
@@ -122,6 +126,8 @@
mDimmingPaintAfterClearing.setColor(Color.BLACK);
mActivity = BaseActivity.fromContext(context);
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
+ // Initialize with dummy value. It is overridden later by TaskView
+ mFullscreenParams = TEMP_PARAMS.get(context);
}
/**
@@ -209,6 +215,38 @@
return fallback;
}
+ /**
+ * Get the scaled insets that are being used to draw the task view. This is a subsection of
+ * the full snapshot.
+ * @return the insets in snapshot bitmap coordinates.
+ */
+ @RequiresApi(api = Build.VERSION_CODES.Q)
+ public Insets getScaledInsets() {
+ if (mThumbnailData == null) {
+ return Insets.NONE;
+ }
+
+ RectF bitmapRect = new RectF(
+ 0, 0,
+ mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
+ RectF viewRect = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight());
+
+ // The position helper matrix tells us how to transform the bitmap to fit the view, the
+ // inverse tells us where the view would be in the bitmaps coordinates. The insets are the
+ // difference between the bitmap bounds and the projected view bounds.
+ Matrix boundsToBitmapSpace = new Matrix();
+ mPreviewPositionHelper.getMatrix().invert(boundsToBitmapSpace);
+ RectF boundsInBitmapSpace = new RectF();
+ boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
+
+ return Insets.of(
+ Math.round(boundsInBitmapSpace.left),
+ Math.round(boundsInBitmapSpace.top),
+ Math.round(bitmapRect.right - boundsInBitmapSpace.right),
+ Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom));
+ }
+
+
public int getSysUiStatusNavFlags() {
if (mThumbnailData != null) {
int flags = 0;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 429ccf5..cadf6c4 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -1018,10 +1018,6 @@
mCurrentDrawnCornerRadius = mCornerRadius;
}
- public FullscreenDrawParams() {
- mCurrentDrawnCornerRadius = mWindowCornerRadius = mCornerRadius = 0;
- }
-
/**
* Sets the progress in range [0, 1]
*/
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index fc60434..5ad0bca 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -26,7 +26,6 @@
import android.content.Context;
import android.os.Build;
import android.os.Handler;
-import android.util.Log;
import androidx.annotation.BinderThread;
import androidx.annotation.UiThread;
@@ -154,16 +153,8 @@
// Because t=0 has the app icon in its original spot, we can skip the
// first frame and have the same movement one frame earlier.
- int singleFrameMs = getSingleFrameMs(context);
- long playTime = singleFrameMs;
- // b/153821199 Add logs to debug crash but ensure release builds do not crash.
- if (Utilities.IS_DEBUG_DEVICE) {
- Log.e(TAG, "Total duration=[" + mAnimator.getTotalDuration()
- + "], singleFrameMs=[" + singleFrameMs + "], mAnimator=" + mAnimator);
- } else {
- playTime = Math.min(singleFrameMs, mAnimator.getTotalDuration());
- }
- mAnimator.setCurrentPlayTime(playTime);
+ mAnimator.setCurrentPlayTime(
+ Math.min(getSingleFrameMs(context), mAnimator.getTotalDuration()));
}
}
}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 7122647..2b698bd 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -105,7 +105,7 @@
public abstract void onAssistantVisibilityChanged(float visibility);
- public abstract AnimationFactory prepareRecentsUI(
+ public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
boolean activityVisible, Consumer<AnimatorPlaybackController> callback);
public abstract ActivityInitListener createActivityInitListener(
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 66e011d..07aed52 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -23,10 +23,10 @@
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
-import static com.android.quickstep.util.RecentsOrientedState.isFixedRotationTransformEnabled;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
@@ -196,10 +196,6 @@
}
private void setupOrientationSwipeHandler() {
- if (!isFixedRotationTransformEnabled()) {
- return;
- }
-
ActivityManagerWrapper.getInstance().registerTaskStackListener(mFrozenTaskListener);
mOnDestroyFrozenTaskRunnable = () -> ActivityManagerWrapper.getInstance()
.unregisterTaskStackListener(mFrozenTaskListener);
@@ -236,10 +232,8 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
mDefaultDisplay.removeChangeListener(this);
- if (newMode.hasGestures) {
- mDefaultDisplay.addChangeListener(this);
- onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
- }
+ mDefaultDisplay.addChangeListener(this);
+ onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
if (newMode == NO_BUTTON) {
mExclusionListener.register();
@@ -261,12 +255,16 @@
@Override
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
- if (info.id != getDisplayId() || (flags & CHANGE_FRAME_DELAY) == CHANGE_FRAME_DELAY) {
+ if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
// ignore displays that aren't running launcher and frame refresh rate changes
return;
}
mDisplayRotation = info.rotation;
+
+ if (!mMode.hasGestures) {
+ return;
+ }
mNavBarPosition = new NavBarPosition(mMode, info);
updateGestureTouchRegions();
mOrientationTouchTransformer.createOrAddTouchRegion(info);
@@ -413,6 +411,13 @@
}
/**
+ * @return whether the global actions dialog is showing
+ */
+ public boolean isGlobalActionsShowing() {
+ return (mSystemUiStateFlags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0;
+ }
+
+ /**
* @return whether lock-task mode is active
*/
public boolean isLockToAppActive() {
@@ -598,7 +603,11 @@
}
}
- public int getCurrentActiveRotation() {
+ int getCurrentActiveRotation() {
+ if (!mMode.hasGestures) {
+ // touch rotation should always match that of display for 3 button
+ return mDisplayRotation;
+ }
return mOrientationTouchTransformer.getCurrentActiveRotation();
}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 5a4292b..348a78d 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -17,8 +17,11 @@
package com.android.quickstep.logging;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__ALLAPPS;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__BACKGROUND;
import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__HOME;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__DST_STATE__OVERVIEW;
+import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGED__SRC_STATE__HOME;
import android.content.Context;
import android.util.Log;
@@ -26,9 +29,11 @@
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
@@ -100,10 +105,40 @@
}
/**
+ * Logs a ranking event and accompanying {@link InstanceId} and package name.
+ */
+ @Override
+ public void log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName,
+ int position) {
+ SysUiStatsLog.write(SysUiStatsLog.RANKING_SELECTED,
+ rankingEvent.getId() /* event_id = 1; */,
+ packageName /* package_name = 2; */,
+ instanceId.getId() /* instance_id = 3; */,
+ position /* position_picked = 4; */);
+ }
+
+ /**
+ * Logs an event and accompanying {@link LauncherState}s. If either of the state refers
+ * to workspace state, then use pageIndex to pass in index of workspace.
+ */
+ @Override
+ public void log(EventEnum event, int srcState, int dstState, int pageIndex) {
+ LauncherAtom.ItemInfo info = LauncherAtom.ItemInfo.getDefaultInstance();
+ if (srcState == LAUNCHER_UICHANGED__DST_STATE__HOME
+ || dstState == LAUNCHER_UICHANGED__SRC_STATE__HOME) {
+ info = LauncherAtom.ItemInfo.newBuilder().setContainerInfo(
+ LauncherAtom.ContainerInfo.newBuilder().setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder().setPageIndex(pageIndex)
+ )).build();
+ }
+ logInternal(event, DEFAULT_INSTANCE_ID, info, srcState, dstState);
+ }
+
+ /**
* Logs an event and accompanying {@link InstanceId} and {@link LauncherAtom.ItemInfo}.
*/
private void logInternal(EventEnum event, InstanceId instanceId,
- @Nullable LauncherAtom.ItemInfo info, int startState, int endState) {
+ @Nullable LauncherAtom.ItemInfo info, int srcState, int dstState) {
info = info == null ? LauncherAtom.ItemInfo.getDefaultInstance() : info;
if (IS_VERBOSE) {
@@ -111,8 +146,10 @@
event.getId() + "";
Log.d(TAG, instanceId == DEFAULT_INSTANCE_ID
- ? String.format("\n%s\n%s", name, info)
- : String.format("%s(InstanceId:%s)\n%s", name, instanceId, info));
+ ? String.format("\n%s (State:%s->%s) \n%s", name, getStateString(srcState),
+ getStateString(dstState), info)
+ : String.format("\n%s (State:%s->%s) (InstanceId:%s)\n%s", name, instanceId,
+ getStateString(srcState), getStateString(dstState), info));
}
if (!Utilities.ATLEAST_R) {
@@ -122,8 +159,8 @@
SysUiStatsLog.write(
SysUiStatsLog.LAUNCHER_EVENT,
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
- startState,
- endState,
+ srcState,
+ dstState,
null /* launcher extensions, deprecated */,
false /* quickstep_enabled, deprecated */,
event.getId() /* event_id */,
@@ -157,33 +194,37 @@
}
private class SnapshotWorker extends BaseModelUpdateTask {
+ private final InstanceId mInstanceId;
+ SnapshotWorker() {
+ mInstanceId = new InstanceIdSequence(
+ 1 << 20 /*InstanceId.INSTANCE_ID_MAX*/).newInstanceId();
+ }
@Override
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
IntSparseArrayMap<FolderInfo> folders = dataModel.folders.clone();
ArrayList<ItemInfo> workspaceItems = (ArrayList) dataModel.workspaceItems.clone();
ArrayList<LauncherAppWidgetInfo> appWidgets = (ArrayList) dataModel.appWidgets.clone();
-
for (ItemInfo info : workspaceItems) {
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
- writeSnapshot(atomInfo);
+ writeSnapshot(atomInfo, mInstanceId);
}
for (FolderInfo fInfo : folders) {
for (ItemInfo info : fInfo.contents) {
LauncherAtom.ItemInfo atomInfo = info.buildProto(fInfo);
- writeSnapshot(atomInfo);
+ writeSnapshot(atomInfo, mInstanceId);
}
}
for (ItemInfo info : appWidgets) {
LauncherAtom.ItemInfo atomInfo = info.buildProto(null);
- writeSnapshot(atomInfo);
+ writeSnapshot(atomInfo, mInstanceId);
}
}
}
- private static void writeSnapshot(LauncherAtom.ItemInfo info) {
+ private static void writeSnapshot(LauncherAtom.ItemInfo info, InstanceId instanceId) {
if (IS_VERBOSE) {
- Log.d(TAG, "\nwriteSnapshot:" + info);
+ Log.d(TAG, String.format("\nwriteSnapshot(%d):\n%s", instanceId.getId(), info));
}
if (!Utilities.ATLEAST_R) {
return;
@@ -191,7 +232,7 @@
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
0 /* event_id */,
info.getItemCase().getNumber() /* target_id */,
- 0 /* instance_id */,
+ instanceId.getId() /* instance_id */,
0 /* uid */,
getPackageName(info) /* package_name */,
getComponentName(info) /* component_name */,
@@ -203,8 +244,8 @@
getPageId(info, true) /* page_id_parent */,
getHierarchy(info) /* hierarchy */,
info.getIsWork() /* is_work_profile */,
- 0 /* origin TODO */,
- 0 /* cardinality */,
+ info.getAttribute().getNumber() /* origin */,
+ info.getFolderIcon().getCardinality() /* cardinality */,
info.getWidget().getSpanX(),
info.getWidget().getSpanY());
}
@@ -283,4 +324,20 @@
return info.getContainerInfo().getContainerCase().getNumber();
}
}
+
+ private static String getStateString(int state) {
+ switch(state) {
+ case LAUNCHER_UICHANGED__DST_STATE__BACKGROUND:
+ return "BACKGROUND";
+ case LAUNCHER_UICHANGED__DST_STATE__HOME:
+ return "HOME";
+ case LAUNCHER_UICHANGED__DST_STATE__OVERVIEW:
+ return "OVERVIEW";
+ case LAUNCHER_UICHANGED__DST_STATE__ALLAPPS:
+ return "ALLAPPS";
+ default:
+ return "INVALID";
+
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 498c232..7715cca 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -72,8 +72,6 @@
private static final String TAG = "RecentsOrientedState";
private static final boolean DEBUG = true;
- private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
-
private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
@@ -94,25 +92,22 @@
private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY = 1 << 0;
// Multiple orientation is only supported if density is < 600
private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY = 1 << 1;
- // Feature flag controlling the multi-orientation feature
- private static final int FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG = 1 << 2;
// Shared prefs for rotation, only if activity supports it
- private static final int FLAG_HOME_ROTATION_ALLOWED_IN_PREFS = 1 << 3;
+ private static final int FLAG_HOME_ROTATION_ALLOWED_IN_PREFS = 1 << 2;
// If the user has enabled system rotation
- private static final int FLAG_SYSTEM_ROTATION_ALLOWED = 1 << 4;
+ private static final int FLAG_SYSTEM_ROTATION_ALLOWED = 1 << 3;
// Multiple orientation is not supported in multiwindow mode
- private static final int FLAG_MULTIWINDOW_ROTATION_ALLOWED = 1 << 5;
+ private static final int FLAG_MULTIWINDOW_ROTATION_ALLOWED = 1 << 4;
// Whether to rotation sensor is supported on the device
- private static final int FLAG_ROTATION_WATCHER_SUPPORTED = 1 << 6;
+ private static final int FLAG_ROTATION_WATCHER_SUPPORTED = 1 << 5;
// Whether to enable rotation watcher when multi-rotation is supported
- private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 7;
+ private static final int FLAG_ROTATION_WATCHER_ENABLED = 1 << 6;
// Enable home rotation for UI tests, ignoring home rotation value from prefs
- private static final int FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING = 1 << 8;
+ private static final int FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING = 1 << 7;
private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
- | FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY
- | FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG;
+ | FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
// State for which rotation watcher will be enabled. We skip it when home rotation or
// multi-window is enabled as in that case, activity itself rotates.
@@ -123,9 +118,6 @@
private SysUINavigationMode.NavigationModeChangeListener mNavModeChangeListener =
newMode -> setFlag(FLAG_ROTATION_WATCHER_SUPPORTED, newMode != TWO_BUTTONS);
- /** TODO: Remove once R ships. This is unlikely to change across different swipe gestures. */
- private static boolean sFixedRotationEnabled;
-
private final Context mContext;
private final ContentResolver mContentResolver;
private final SharedPreferences mSharedPrefs;
@@ -168,11 +160,6 @@
if (originalSmallestWidth < 600) {
mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
}
- sFixedRotationEnabled = Settings.Global.getInt(
- context.getContentResolver(), FIXED_ROTATION_TRANSFORM_SETTING_NAME, 1) == 1;
- if (sFixedRotationEnabled) {
- mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_FLAG;
- }
initFlags();
}
@@ -207,6 +194,7 @@
mLauncherRotation = launcherRotation;
mDisplayRotation = displayRotation;
mTouchRotation = touchRotation;
+ mPreviousRotation = touchRotation;
if (mLauncherRotation == mTouchRotation || canLauncherRotate()) {
mOrientationHandler = PagedOrientationHandler.HOME_ROTATED;
@@ -520,14 +508,6 @@
}
}
- /**
- * Returns true if system can keep Launcher fixed to portrait layout even if the
- * foreground app is rotated
- */
- public static boolean isFixedRotationTransformEnabled() {
- return sFixedRotationEnabled;
- }
-
@NonNull
@Override
public String toString() {
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 3d048a6..f20a0ba 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -25,7 +25,6 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
-import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.util.RaceConditionReproducer;
import com.android.quickstep.NavigationModeSwitchRule.Mode;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
@@ -99,5 +98,7 @@
// The test action.
mLauncher.getBackground().switchToOverview();
}
+ // Workaround for b/157099707
+ mLauncher.pressHome();
}
}
\ No newline at end of file
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index a41fb9a..67ec664 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -19,6 +19,7 @@
<com.android.launcher3.allapps.LauncherAllAppsContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps_view"
+ android:theme="?attr/allAppsTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="true"
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 08e1c98..7f1107f 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -15,6 +15,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="?attr/allAppsScrimColor"
android:padding="48dp"
android:orientation="vertical"
android:gravity="center">
@@ -34,6 +35,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:id="@+id/work_apps_paused_content"
android:textColor="?attr/workProfileOverlayTextColor"
android:text="@string/work_apps_paused_body"
android:textAlignment="center"
diff --git a/res/layout/work_mode_switch.xml b/res/layout/work_mode_switch.xml
index 9cb7ce8..b5237db 100644
--- a/res/layout/work_mode_switch.xml
+++ b/res/layout/work_mode_switch.xml
@@ -28,11 +28,11 @@
android:gravity="start"
android:lines="1"
android:showText="false"
- android:textSize="16sp"
+ android:textSize="@dimen/work_profile_footer_text_size"
android:background="?attr/allAppsScrimColor"
android:text="@string/work_profile_toggle_label"
- android:paddingBottom="@dimen/all_apps_work_profile_tab_footer_padding"
- android:paddingLeft="@dimen/all_apps_work_profile_tab_footer_padding"
- android:paddingRight="@dimen/all_apps_work_profile_tab_footer_padding"
- android:paddingTop="@dimen/all_apps_work_profile_tab_footer_padding"
+ android:paddingBottom="@dimen/work_profile_footer_padding"
+ android:paddingLeft="@dimen/work_profile_footer_padding"
+ android:paddingRight="@dimen/work_profile_footer_padding"
+ android:paddingTop="@dimen/work_profile_footer_padding"
/>
diff --git a/res/values-v30/styles.xml b/res/values-v30/styles.xml
new file mode 100644
index 0000000..71740a9
--- /dev/null
+++ b/res/values-v30/styles.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2020 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.
+*/
+-->
+
+<resources>
+ <!-- Launcher theme -->
+ <style name="BaseLauncherTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:colorEdgeEffect">#FF757575</item>
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowNoTitle">true</item>
+ <item name="android:windowShowWallpaper">true</item>
+ <item name="folderTextColor">?attr/workspaceTextColor</item>
+ <item name="android:windowLayoutInDisplayCutoutMode">always</item>
+ <item name="android:enforceStatusBarContrast">false</item>
+ <item name="android:enforceNavigationBarContrast">false</item>
+ </style>
+</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 2875006..26e6cba 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -22,6 +22,7 @@
<attr name="allAppsScrimColor" format="color" />
<attr name="allAppsInterimScrimAlpha" format="integer" />
<attr name="allAppsNavBarScrimColor" format="color" />
+ <attr name="allAppsTheme" format="reference" />
<attr name="popupColorPrimary" format="color" />
<attr name="popupColorSecondary" format="color" />
<attr name="popupColorTertiary" format="color" />
@@ -44,6 +45,7 @@
<attr name="folderTextColor" format="color" />
<attr name="folderHintColor" format="color" />
<attr name="workProfileOverlayTextColor" format="color" />
+ <attr name="disabledIconAlpha" format="float" />
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 31b12ad..947e635 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -96,7 +96,6 @@
<!-- The size of corner radius of the arrow in the arrow toast. -->
<dimen name="arrow_toast_corner_radius">2dp</dimen>
- <dimen name="all_apps_work_profile_tab_footer_padding">20dp</dimen>
<!-- Search bar in All Apps -->
<dimen name="all_apps_header_max_elevation">3dp</dimen>
@@ -105,6 +104,9 @@
<dimen name="all_apps_divider_margin_vertical">8dp</dimen>
+ <dimen name="work_profile_footer_padding">20dp</dimen>
+ <dimen name="work_profile_footer_text_size">16sp</dimen>
+
<!-- Widget tray -->
<dimen name="widget_preview_label_vertical_padding">8dp</dimen>
<dimen name="widget_preview_label_horizontal_padding">16dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e470c42..a922183 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -34,6 +34,7 @@
<item name="allAppsScrimColor">#FFFFFFFF</item>
<item name="allAppsInterimScrimAlpha">46</item>
<item name="allAppsNavBarScrimColor">#66FFFFFF</item>
+ <item name="allAppsTheme">@style/AllAppsTheme</item>
<item name="popupColorPrimary">#FFF</item>
<item name="popupColorSecondary">#F1F3F4</item>
<item name="popupColorTertiary">#E0E0E0</item> <!-- Gray 300 -->
@@ -54,6 +55,7 @@
<item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
<item name="workProfileOverlayTextColor">#FF212121</item>
<item name="eduHalfSheetBGColor">?android:attr/colorAccent</item>
+ <item name="disabledIconAlpha">.36</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">false</item>
@@ -67,6 +69,8 @@
<style name="LauncherTheme.DarkMainColor" parent="@style/LauncherTheme">
<item name="folderFillColor">#FF3C4043</item> <!-- 100% GM2 800 -->
<item name="folderTextColor">?attr/workspaceTextColor</item>
+ <item name="disabledIconAlpha">.24</item>
+
</style>
<style name="LauncherTheme.DarkText" parent="@style/LauncherTheme">
@@ -93,6 +97,7 @@
<item name="allAppsScrimColor">#FF000000</item>
<item name="allAppsInterimScrimAlpha">102</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
+ <item name="allAppsTheme">@style/AllAppsTheme.Dark</item>
<item name="popupColorPrimary">#3C4043</item> <!-- Gray 800 -->
<item name="popupColorSecondary">#202124</item>
<item name="popupColorTertiary">#757575</item> <!-- Gray 600 -->
@@ -112,6 +117,7 @@
<style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
<item name="folderFillColor">#FF3C4043</item> <!-- 100% GM2 800 -->
<item name="folderTextColor">@android:color/white</item>
+ <item name="disabledIconAlpha">.24</item>
</style>
<style name="LauncherTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark">
@@ -180,6 +186,14 @@
<item name="android:importantForAccessibility">no</item>
</style>
+ <style name="AllAppsTheme">
+ <item name="disabledIconAlpha">.24</item>
+ </style>
+
+ <style name="AllAppsTheme.Dark">
+ <item name="disabledIconAlpha">.28</item>
+ </style>
+
<!-- Base theme for BubbleTextView and sub classes -->
<style name="BaseIcon" parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:layout_width">match_parent</item>
diff --git a/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
index 2584f65..3a252dc 100644
--- a/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -92,7 +92,8 @@
SCREEN, CELLX, CELLY, RESTORED, INTENT
});
- mLoaderCursor = new LoaderCursor(mCursor, LauncherSettings.Favorites.CONTENT_URI, mApp);
+ mLoaderCursor = new LoaderCursor(mCursor, LauncherSettings.Favorites.CONTENT_URI, mApp,
+ new UserManagerState());
mLoaderCursor.allUsers.put(0, Process.myUserHandle());
}
diff --git a/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
index 4b0ae7e..87fe3c0 100644
--- a/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
@@ -199,7 +199,7 @@
}
@Override
- public void bindAllApplications(AppInfo[] apps) {
+ public void bindAllApplications(AppInfo[] apps, int flags) {
mAppInfos = apps;
}
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index d1d5e26..268b910 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -187,8 +187,9 @@
sourceContainer);
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
- getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item == null ? null
- : item.buildProto());
+ if (item != null) {
+ getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item.buildProto());
+ }
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 72831f4..e3cd0bd 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -538,7 +538,6 @@
mInsets.right + hotseatBarSidePaddingStartPx, mInsets.bottom);
}
} else {
-
// We want the edges of the hotseat to line up with the edges of the workspace, but the
// icons in the hotseat are a different size, and so don't line up perfectly. To account
// for this, we pad the left and right of the hotseat with half of the difference of a
@@ -547,9 +546,11 @@
float hotseatCellWidth = (float) widthPx / inv.numHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
mHotseatPadding.set(
- hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx,
+ hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
+ + mInsets.left,
hotseatBarTopPaddingPx,
- hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx,
+ hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx
+ + mInsets.right,
hotseatBarBottomPaddingPx + mInsets.bottom + cellLayoutBottomPaddingPx);
}
return mHotseatPadding;
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index f96aafa..d3b86de 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -36,6 +36,7 @@
import com.android.launcher3.graphics.PlaceHolderIconDrawable;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.util.Themes;
public class FastBitmapDrawable extends Drawable {
@@ -44,7 +45,6 @@
private static final float DISABLED_DESATURATION = 1f;
private static final float DISABLED_BRIGHTNESS = 0.5f;
- private static final float DISABLED_ALPHA = 0.54f;
public static final int CLICK_FEEDBACK_DURATION = 200;
@@ -56,6 +56,7 @@
private boolean mIsPressed;
private boolean mIsDisabled;
+ private float mDisabledAlpha = 1f;
// Animator and properties for the fast bitmap drawable's scale
private static final Property<FastBitmapDrawable, Float> SCALE
@@ -253,7 +254,7 @@
mat[4] = brightnessI;
mat[9] = brightnessI;
mat[14] = brightnessI;
- mat[18] = DISABLED_ALPHA;
+ mat[18] = mDisabledAlpha;
tempFilterMatrix.preConcat(tempBrightnessMatrix);
sDisabledFColorFilter = new ColorMatrixColorFilter(tempFilterMatrix);
}
@@ -319,12 +320,15 @@
* Creates a drawable for the provided BitmapInfo
*/
public static FastBitmapDrawable newIcon(Context context, BitmapInfo info) {
+ final FastBitmapDrawable drawable;
if (info instanceof Factory) {
- return ((Factory) info).newDrawable();
+ drawable = ((Factory) info).newDrawable();
} else if (info.isLowRes()) {
- return new PlaceHolderIconDrawable(info, context);
+ drawable = new PlaceHolderIconDrawable(info, context);
} else {
- return new FastBitmapDrawable(info);
+ drawable = new FastBitmapDrawable(info);
}
+ drawable.mDisabledAlpha = Themes.getFloat(context, R.attr.disabledIconAlpha, 1f);
+ return drawable;
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 1c157c2..51f3819 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -91,7 +91,6 @@
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
DeviceProfile grid = mActivity.getDeviceProfile();
- insets = grid.getInsets();
if (grid.isVerticalBarLayout()) {
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1f84c42..ec32e62 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2455,8 +2455,9 @@
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void bindAllApplications(AppInfo[] apps) {
- mAppsView.getAppsStore().setApps(apps);
+ @Override
+ public void bindAllApplications(AppInfo[] apps, int flags) {
+ mAppsView.getAppsStore().setApps(apps, flags);
}
/**
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 3b1c7bb..f434c91 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -117,7 +117,7 @@
@Override
public void run() {
if (mModelLoaded && hasShortcutsPermission(mApp.getContext())
- != mBgDataModel.hasShortcutHostPermission) {
+ != mBgAllAppsList.hasShortcutHostPermission()) {
forceReload();
}
}
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 9ac370f..6951ff2 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -1,19 +1,12 @@
package com.android.launcher3;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
-import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
-import static com.android.launcher3.util.SystemUiController.UI_STATE_ROOT_VIEW;
import android.annotation.TargetApi;
-import android.app.ActivityManager;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
-import android.view.View;
import android.view.ViewDebug;
import android.view.WindowInsets;
@@ -26,16 +19,10 @@
private final Launcher mLauncher;
- private final Paint mOpaquePaint;
-
- @ViewDebug.ExportedProperty(category = "launcher")
- private final Rect mConsumedInsets = new Rect();
-
@ViewDebug.ExportedProperty(category = "launcher")
private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
Collections.singletonList(new Rect());
- private View mAlignedView;
private WindowStateListener mWindowStateListener;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mDisallowBackGesture;
@@ -44,55 +31,15 @@
public LauncherRootView(Context context, AttributeSet attrs) {
super(context, attrs);
-
- mOpaquePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mOpaquePaint.setColor(Color.BLACK);
- mOpaquePaint.setStyle(Paint.Style.FILL);
-
mLauncher = Launcher.getLauncher(context);
}
- @Override
- protected void onFinishInflate() {
- if (getChildCount() > 0) {
- // LauncherRootView contains only one child, which should be aligned
- // based on the horizontal insets.
- mAlignedView = getChildAt(0);
- }
- super.onFinishInflate();
- }
-
private void handleSystemWindowInsets(Rect insets) {
- mConsumedInsets.setEmpty();
- boolean drawInsetBar = false;
- if ((insets.right > 0 || insets.left > 0)
- && getContext().getSystemService(ActivityManager.class).isLowRamDevice()) {
- mConsumedInsets.left = insets.left;
- mConsumedInsets.right = insets.right;
- insets.set(0, insets.top, 0, insets.bottom);
- drawInsetBar = true;
- }
-
- mLauncher.getSystemUiController().updateUiState(
- UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
-
// Update device profile before notifying th children.
mLauncher.getDeviceProfile().updateInsets(insets);
boolean resetState = !insets.equals(mInsets);
setInsets(insets);
- if (mAlignedView != null) {
- // Apply margins on aligned view to handle consumed insets.
- MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
- if (lp.leftMargin != mConsumedInsets.left || lp.rightMargin != mConsumedInsets.right ||
- lp.bottomMargin != mConsumedInsets.bottom) {
- lp.leftMargin = mConsumedInsets.left;
- lp.rightMargin = mConsumedInsets.right;
- lp.topMargin = mConsumedInsets.top;
- lp.bottomMargin = mConsumedInsets.bottom;
- mAlignedView.setLayoutParams(lp);
- }
- }
if (resetState) {
mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */);
}
@@ -103,12 +50,7 @@
mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
handleSystemWindowInsets(mTempRect);
- if (Utilities.ATLEAST_Q) {
- return insets.inset(mConsumedInsets.left, mConsumedInsets.top,
- mConsumedInsets.right, mConsumedInsets.bottom);
- } else {
- return insets.replaceSystemWindowInsets(mTempRect);
- }
+ return insets;
}
@Override
@@ -125,24 +67,6 @@
super.setInsets(mInsets);
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
-
- // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
- if (mConsumedInsets.right > 0) {
- int width = getWidth();
- canvas.drawRect(width - mConsumedInsets.right, 0, width, getHeight(), mOpaquePaint);
- }
- if (mConsumedInsets.left > 0) {
- canvas.drawRect(0, 0, mConsumedInsets.left, getHeight(), mOpaquePaint);
- }
- if (mConsumedInsets.bottom > 0) {
- int height = getHeight();
- canvas.drawRect(0, height - mConsumedInsets.bottom, getWidth(), height, mOpaquePaint);
- }
- }
-
public void setWindowStateListener(WindowStateListener listener) {
mWindowStateListener = listener;
}
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 2a5ee00..208d565 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -162,6 +162,7 @@
// Represents search results view.
public static final int CONTAINER_SEARCH_RESULTS = -106;
public static final int CONTAINER_SHORTCUTS = -107;
+ public static final int CONTAINER_SETTINGS = -108;
public static final String containerToString(int container) {
switch (container) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 32685b0..f6c392b 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1342,7 +1342,6 @@
ValueAnimator stepAnimator = ValueAnimator.ofFloat(0, 1);
stepAnimator.addUpdateListener(listener);
- stepAnimator.setDuration(config.duration);
stepAnimator.addListener(listener);
animation.add(stepAnimator);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index a45c96c..c989e7b 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -16,9 +16,14 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
@@ -37,7 +42,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
-import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -54,7 +58,6 @@
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.pm.UserCache;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -195,7 +198,7 @@
}
private void resetWorkProfile() {
- mWorkModeSwitch.refresh();
+ mWorkModeSwitch.update(!mAllAppsStore.hasModelFlag(FLAG_QUIET_MODE_ENABLED));
mAH[AdapterHolder.WORK].setupOverlay();
mAH[AdapterHolder.WORK].applyPadding();
}
@@ -277,6 +280,10 @@
}
}
+ public LayoutInflater getLayoutInflater() {
+ return LayoutInflater.from(getContext());
+ }
+
/**
* Resets the state of AllApps.
*/
@@ -349,15 +356,15 @@
}
ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
+ mlp.leftMargin = insets.left;
+ mlp.rightMargin = insets.right;
+ setLayoutParams(mlp);
+
if (grid.isVerticalBarLayout()) {
- mlp.leftMargin = insets.left;
- mlp.rightMargin = insets.right;
setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
} else {
- mlp.leftMargin = mlp.rightMargin = 0;
setPadding(0, 0, 0, 0);
}
- setLayoutParams(mlp);
InsettableFrameLayout.dispatchInsets(this, insets);
}
@@ -427,11 +434,22 @@
}
private void setupWorkToggle() {
- mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
- R.layout.work_mode_switch, this, false);
- this.addView(mWorkModeSwitch);
- mWorkModeSwitch.setInsets(mInsets);
- mWorkModeSwitch.post(() -> mAH[AdapterHolder.WORK].applyPadding());
+ if (Utilities.ATLEAST_P) {
+ mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
+ R.layout.work_mode_switch, this, false);
+ this.addView(mWorkModeSwitch);
+ mWorkModeSwitch.setInsets(mInsets);
+ mWorkModeSwitch.post(() -> mAH[AdapterHolder.WORK].applyPadding());
+ }
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ View overlay = mAH[AdapterHolder.WORK].getOverlayView();
+ int v = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? GONE : VISIBLE;
+ overlay.findViewById(R.id.work_apps_paused_title).setVisibility(v);
+ overlay.findViewById(R.id.work_apps_paused_content).setVisibility(v);
}
private void replaceRVContainer(boolean showTabs) {
@@ -444,7 +462,7 @@
int index = indexOfChild(oldView);
removeView(oldView);
int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
- View newView = LayoutInflater.from(getContext()).inflate(layout, this, false);
+ View newView = getLayoutInflater().inflate(layout, this, false);
addView(newView, index);
if (showTabs) {
mViewPager = (AllAppsPagedView) newView;
@@ -466,7 +484,9 @@
}
reset(true /* animate */);
if (mWorkModeSwitch != null) {
- mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK);
+ mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK
+ && mAllAppsStore.hasModelFlag(
+ FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
}
}
@@ -576,15 +596,8 @@
&& valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
int searchViewId = getSearchView().getId();
addSpringView(searchViewId);
-
finishWithShiftAndVelocity(1, velocity * FLING_VELOCITY_MULTIPLIER,
- new DynamicAnimation.OnAnimationEndListener() {
- @Override
- public void onAnimationEnd(DynamicAnimation animation,
- boolean canceled, float value, float velocity) {
- removeSpringView(searchViewId);
- }
- });
+ (anim, canceled, value, velocity) -> removeSpringView(searchViewId));
shouldSpring = false;
}
@@ -617,7 +630,7 @@
AdapterHolder(boolean isWork) {
mIsWork = isWork;
appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, isWork);
- adapter = new AllAppsGridAdapter(mLauncher, appsList);
+ adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList);
appsList.setAdapter(adapter);
layoutManager = adapter.getLayoutManager();
}
@@ -643,7 +656,7 @@
void setupOverlay() {
if (!mIsWork || recyclerView == null) return;
- boolean workDisabled = UserCache.INSTANCE.get(mLauncher).isAnyProfileQuietModeEnabled();
+ boolean workDisabled = mAllAppsStore.hasModelFlag(FLAG_QUIET_MODE_ENABLED);
if (mWorkDisabled == workDisabled) return;
recyclerView.setContentDescription(workDisabled ? mLauncher.getString(
R.string.work_apps_paused_content_description) : null);
@@ -651,10 +664,12 @@
recyclerView.setItemAnimator(new DefaultItemAnimator());
if (workDisabled) {
overlayView.setAlpha(0);
- appsList.updateItemFilter((info, cn) -> false);
recyclerView.addAutoSizedOverlay(overlayView);
overlayView.animate().alpha(1).withEndAction(
- () -> recyclerView.setItemAnimator(null)).start();
+ () -> {
+ appsList.updateItemFilter((info, cn) -> false);
+ recyclerView.setItemAnimator(null);
+ }).start();
} else if (mInfoMatcher != null) {
appsList.updateItemFilter(mInfoMatcher);
overlayView.animate().alpha(0).withEndAction(() -> {
@@ -667,8 +682,12 @@
void applyPadding() {
if (recyclerView != null) {
- int bottomOffset =
- mWorkModeSwitch != null && mIsWork ? mWorkModeSwitch.getHeight() : 0;
+ Resources res = getResources();
+ int switchH = res.getDimensionPixelSize(R.dimen.work_profile_footer_padding) * 2
+ + mInsets.bottom + Utilities.calculateTextHeight(
+ res.getDimension(R.dimen.work_profile_footer_text_size));
+
+ int bottomOffset = mWorkModeSwitch != null && mIsWork ? switchH : 0;
recyclerView.setPadding(padding.left, padding.top, padding.right,
padding.bottom + bottomOffset);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 3afa756..8ec4d27 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -188,7 +188,8 @@
// The intent to send off to the market app, updated each time the search query changes.
private Intent mMarketSearchIntent;
- public AllAppsGridAdapter(BaseDraggingActivity launcher, AlphabeticalAppsList apps) {
+ public AllAppsGridAdapter(BaseDraggingActivity launcher, LayoutInflater inflater,
+ AlphabeticalAppsList apps) {
Resources res = launcher.getResources();
mLauncher = launcher;
mApps = apps;
@@ -196,7 +197,7 @@
mGridSizer = new GridSpanSizer();
mGridLayoutMgr = new AppsGridLayoutManager(launcher);
mGridLayoutMgr.setSpanSizeLookup(mGridSizer);
- mLayoutInflater = LayoutInflater.from(launcher);
+ mLayoutInflater = inflater;
mOnIconClickListener = launcher.getItemOnClickListener();
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index b11312c..3ae0a18 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -52,6 +52,7 @@
private final List<OnUpdateListener> mUpdateListeners = new CopyOnWriteArrayList<>();
private final ArrayList<ViewGroup> mIconContainers = new ArrayList<>();
+ private int mModelFlags;
private int mDeferUpdatesFlags = 0;
private boolean mUpdatePending = false;
@@ -63,11 +64,21 @@
/**
* Sets the current set of apps.
*/
- public void setApps(AppInfo[] apps) {
+ public void setApps(AppInfo[] apps, int flags) {
mApps = apps;
+ mModelFlags = flags;
notifyUpdate();
}
+ /**
+ * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_QUIET_MODE_ENABLED
+ * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+ * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
+ */
+ public boolean hasModelFlag(int mask) {
+ return (mModelFlags & mask) != 0;
+ }
+
public AppInfo getApp(ComponentKey key) {
mTempInfo.componentName = key.componentName;
mTempInfo.user = key.user;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 99ed0ad..8260336 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -189,7 +189,6 @@
: FAST_OUT_SLOW_IN;
Animator anim = createSpringAnimation(mProgress, targetProgress);
- anim.setDuration(config.duration);
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
anim.addListener(getProgressAnimatorListener());
builder.add(anim);
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 6692af5..4567ee6 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -15,11 +15,8 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
-
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Process;
@@ -59,7 +56,6 @@
public WorkModeSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
init();
-
}
public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -73,9 +69,7 @@
}
@Override
- public void setChecked(boolean checked) {
-
- }
+ public void setChecked(boolean checked) { }
@Override
public void toggle() {
@@ -84,20 +78,17 @@
trySetQuietModeEnabledToAllProfilesAsync(isChecked());
}
- private void setCheckedInternal(boolean checked) {
- super.setChecked(checked);
+ /**
+ * Sets the enabled or disabled state of the button
+ * @param isChecked
+ */
+ public void update(boolean isChecked) {
+ super.setChecked(isChecked);
setCompoundDrawablesRelativeWithIntrinsicBounds(
- checked ? R.drawable.ic_corp : R.drawable.ic_corp_off, 0, 0, 0);
- }
-
- public void refresh() {
- if (!shouldShowWorkSwitch()) return;
- UserCache userManager = UserCache.INSTANCE.get(getContext());
- setCheckedInternal(!userManager.isAnyProfileQuietModeEnabled());
+ isChecked ? R.drawable.ic_corp : R.drawable.ic_corp_off, 0, 0, 0);
setEnabled(true);
}
-
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
@@ -116,12 +107,6 @@
return super.onTouchEvent(ev);
}
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- this.setVisibility(shouldShowWorkSwitch() ? VISIBLE : GONE);
- }
-
private void trySetQuietModeEnabledToAllProfilesAsync(boolean enabled) {
new SetQuietModeEnabledAsyncTask(enabled, new WeakReference<>(this)).execute();
}
@@ -138,13 +123,12 @@
* Animates in/out work profile toggle panel based on the tab user is on
*/
public void setWorkTabVisible(boolean workTabVisible) {
- if (!shouldShowWorkSwitch()) return;
clearAnimation();
if (workTabVisible) {
setVisibility(VISIBLE);
setAlpha(0);
animate().alpha(1).start();
- showTipifNeeded();
+ showTipIfNeeded();
} else {
animate().alpha(0).withEndAction(() -> this.setVisibility(GONE)).start();
}
@@ -201,16 +185,10 @@
}
}
- private boolean shouldShowWorkSwitch() {
- return Utilities.ATLEAST_P && (hasShortcutsPermission(getContext())
- || getContext().checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
- == PackageManager.PERMISSION_GRANTED);
- }
-
/**
* Shows a work tip on the Nth work tab open
*/
- public void showTipifNeeded() {
+ public void showTipIfNeeded() {
Context context = getContext();
SharedPreferences prefs = Utilities.getPrefs(context);
int tipCounter = prefs.getInt(KEY_WORK_TIP_COUNTER, WORK_TIP_THRESHOLD);
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index afeb341..4195933 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -69,7 +69,7 @@
}
public void add(Animator a, SpringProperty springProperty) {
- mAnim.play(a);
+ mAnim.play(a.setDuration(mDuration));
addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
}
@@ -87,7 +87,7 @@
}
ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, alpha);
anim.addListener(new AlphaUpdateListener(view));
- anim.setDuration(mDuration).setInterpolator(interpolator);
+ anim.setInterpolator(interpolator);
add(anim);
}
@@ -105,7 +105,7 @@
public <T> void addFloat(T target, FloatProperty<T> property, float from, float to,
TimeInterpolator interpolator) {
Animator anim = ObjectAnimator.ofFloat(target, property, from, to);
- anim.setDuration(mDuration).setInterpolator(interpolator);
+ anim.setInterpolator(interpolator);
add(anim);
}
@@ -116,7 +116,7 @@
return;
}
Animator anim = ObjectAnimator.ofInt(target, property, value);
- anim.setDuration(mDuration).setInterpolator(interpolator);
+ anim.setInterpolator(interpolator);
add(anim);
}
@@ -125,7 +125,7 @@
*/
public void addOnFrameCallback(Runnable runnable) {
if (mProgressAnimator == null) {
- mProgressAnimator = ValueAnimator.ofFloat(0, 1).setDuration(mDuration);
+ mProgressAnimator = ValueAnimator.ofFloat(0, 1);
}
mProgressAnimator.addUpdateListener(anim -> runnable.run());
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 118ce0c..8df6f90 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -98,6 +98,10 @@
"FOLDER_NAME_SUGGEST", true,
"Suggests folder names instead of blank text.");
+ public static final BooleanFlag FOLDER_NAME_MAJORITY_RANKING = getDebugFlag(
+ "FOLDER_NAME_MAJORITY_RANKING", true,
+ "Suggests folder names based on majority based ranking.");
+
public static final BooleanFlag APP_SEARCH_IMPROVEMENTS = new DeviceFlag(
"APP_SEARCH_IMPROVEMENTS", true,
"Adds localized title and keyword search and ranking");
@@ -173,6 +177,9 @@
"SEPARATE_RECENTS_ACTIVITY", false,
"Uses a separate recents activity instead of using the integrated recents+Launcher UI");
+ public static final BooleanFlag USER_EVENT_DISPATCHER = new DeviceFlag(
+ "USER_EVENT_DISPATCHER", true, "User event dispatcher collects logs.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index f07cf94..f216f81 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -19,6 +19,7 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.logger.LauncherAtom.ItemInfo;
import com.android.launcher3.logging.StatsLogUtils.LogStateProvider;
@@ -37,12 +38,18 @@
}
public enum LauncherEvent implements EventEnum {
+ /* Used to prevent double logging. */
+ IGNORE(-1),
+
@UiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
LAUNCHER_APP_LAUNCH_TAP(338),
@UiEvent(doc = "Task launched from overview using TAP")
LAUNCHER_TASK_LAUNCH_TAP(339),
+ @UiEvent(doc = "User tapped on notification inside popup context menu.")
+ LAUNCHER_NOTIFICATION_LAUNCH_TAP(516),
+
@UiEvent(doc = "Task launched from overview using SWIPE DOWN")
LAUNCHER_TASK_LAUNCH_SWIPE_DOWN(340),
@@ -101,7 +108,7 @@
LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS(517),
@UiEvent(doc = "User opened package specific widgets list by tapping on widgets system "
- + "shortcut within longpress popup window.")
+ + "shortcut inside popup context menu.")
LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP(514),
@UiEvent(doc = "User tapped on app info system shortcut.")
@@ -117,7 +124,10 @@
LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP(521),
@UiEvent(doc = "User tapped on pin system shortcut.")
- LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP(522);
+ LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP(522),
+
+ @UiEvent(doc = "User is shown All Apps education view.")
+ LAUNCHER_ALL_APPS_EDU_SHOWN(523);
// ADD MORE
private final int mId;
@@ -131,6 +141,25 @@
}
}
+ /**
+ * Launcher specific ranking related events.
+ */
+ public enum LauncherRankingEvent implements EventEnum {
+
+ UNKNOWN(0);
+ // ADD MORE
+
+ private final int mId;
+
+ LauncherRankingEvent(int id) {
+ mId = id;
+ }
+
+ public int getId() {
+ return mId;
+ }
+ }
+
protected LogStateProvider mStateProvider;
/**
@@ -172,6 +201,26 @@
}
/**
+ * Log an event with ranked-choice information along with package. Does nothing if event.getId()
+ * <= 0.
+ *
+ * @param rankingEvent an enum implementing UiEventEnum interface.
+ * @param instanceId An identifier obtained from an InstanceIdSequence.
+ * @param packageName the package name of the relevant app, if known (null otherwise).
+ * @param position the position picked.
+ */
+ public void log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName,
+ int position) {
+ }
+
+ /**
+ * Logs an event and accompanying {@link LauncherState}s. If either of the state refers
+ * to workspace state, then use pageIndex to pass in index of workspace.
+ */
+ public void log(EventEnum event, int srcState, int dstState, int pageIndex) {
+ }
+
+ /**
* Logs snapshot, or impression of the current workspace.
*/
public void logSnapshot() {
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 4f349ca..eb5d106 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -35,6 +35,7 @@
import com.android.launcher3.AppFilter;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.PromiseAppInfo;
import com.android.launcher3.pm.PackageInstallInfo;
@@ -73,6 +74,13 @@
private AlphabeticIndexCompat mIndex;
/**
+ * @see Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+ * @see Callbacks#FLAG_QUIET_MODE_ENABLED
+ * @see Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
+ */
+ private int mFlags;
+
+ /**
* Boring constructor.
*/
public AllAppsList(IconCache iconCache, AppFilter appFilter) {
@@ -91,6 +99,33 @@
}
/**
+ * Helper to checking {@link Callbacks#FLAG_HAS_SHORTCUT_PERMISSION}
+ */
+ public boolean hasShortcutHostPermission() {
+ return (mFlags & Callbacks.FLAG_HAS_SHORTCUT_PERMISSION) != 0;
+ }
+
+ /**
+ * Sets or clears the provided flag
+ */
+ public void setFlags(int flagMask, boolean enabled) {
+ if (enabled) {
+ mFlags |= flagMask;
+ } else {
+ mFlags &= ~flagMask;
+ }
+ mDataChanged = true;
+ }
+
+ /**
+ * Returns the model flags
+ */
+ public int getFlags() {
+ return mFlags;
+ }
+
+
+ /**
* Add the supplied ApplicationInfo objects to the list, and enqueue it into the
* list to broadcast when notify() is called.
*
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index ab921ea..8b0ef7b 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -96,7 +96,8 @@
public void bindAllApps() {
// shallow copy
AppInfo[] apps = mBgAllAppsList.copyData();
- executeCallbacksTask(c -> c.bindAllApplications(apps), mUiExecutor);
+ int flags = mBgAllAppsList.getFlags();
+ executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);
}
public abstract void bindWidgets();
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 7ce970d..9013cba 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -117,7 +117,8 @@
public void bindApplicationsIfNeeded() {
if (mAllAppsList.getAndResetChangeFlag()) {
AppInfo[] apps = mAllAppsList.copyData();
- scheduleCallbackTask(c -> c.bindAllApplications(apps));
+ int flags = mAllAppsList.getFlags();
+ scheduleCallbackTask(c -> c.bindAllApplications(apps, flags));
}
}
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 2522a49..9bef847 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -98,9 +98,11 @@
public final ArrayList<AppInfo> cachedPredictedItems = new ArrayList<>();
/**
- * True if the launcher has permission to access deep shortcuts.
+ * @see Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+ * @see Callbacks#FLAG_QUIET_MODE_ENABLED
+ * @see Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
*/
- public boolean hasShortcutHostPermission;
+ public int flags;
/**
* Maps all launcher activities to counts of their shortcuts.
@@ -347,6 +349,13 @@
}
public interface Callbacks {
+ // If the launcher has permission to access deep shortcuts.
+ int FLAG_HAS_SHORTCUT_PERMISSION = 1 << 0;
+ // If quiet mode is enabled for any user
+ int FLAG_QUIET_MODE_ENABLED = 1 << 1;
+ // If launcher can change quiet mode
+ int FLAG_QUIET_MODE_CHANGE_PERMISSION = 1 << 2;
+
/**
* Returns the page number to bind first, synchronously if possible or -1
*/
@@ -370,7 +379,7 @@
void executeOnNextDraw(ViewOnDrawExecutor executor);
void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
- void bindAllApplications(AppInfo[] apps);
+ void bindAllApplications(AppInfo[] apps, int flags);
/**
* Binds predicted appInfos at at available prediction slots.
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index 4bfabb0..a5d798b 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -32,7 +32,6 @@
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Point;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
@@ -53,6 +52,7 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -259,64 +259,54 @@
return diff;
}
- private static void insertEntryInDb(SQLiteDatabase db, Context context,
- ArrayList<DbEntry> entriesFromSrcDb, DbEntry entry, String srcTableName,
- String destTableName) {
- int id = -1;
- switch (entry.itemType) {
- case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: {
- for (DbEntry e : entriesFromSrcDb) {
- if (TextUtils.equals(e.mIntent, entry.mIntent)) {
- id = e.id;
- }
- }
+ private static void insertEntryInDb(SQLiteDatabase db, Context context, DbEntry entry,
+ String srcTableName, String destTableName) {
+ int id = copyEntryAndUpdate(db, context, entry, srcTableName, destTableName);
- break;
+ if (entry.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
+ for (int itemId : entry.mFolderItems.values()) {
+ copyEntryAndUpdate(db, context, itemId, id, srcTableName, destTableName);
}
- case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
- for (DbEntry e : entriesFromSrcDb) {
- if (e.mFolderItems.size() == entry.mFolderItems.size()
- && e.mFolderItems.containsAll(entry.mFolderItems)) {
- id = e.id;
- }
- }
- break;
- }
- case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
- case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: {
- for (DbEntry e : entriesFromSrcDb) {
- if (TextUtils.equals(e.mProvider, entry.mProvider)) {
- id = e.id;
- break;
- }
- }
- break;
- }
- default:
- return;
}
+ }
- Cursor c = db.query(srcTableName, null, LauncherSettings.Favorites._ID + " = '" + id + "'",
+ private static int copyEntryAndUpdate(SQLiteDatabase db, Context context,
+ DbEntry entry, String srcTableName, String destTableName) {
+ return copyEntryAndUpdate(db, context, entry, -1, -1, srcTableName, destTableName);
+ }
+
+ private static int copyEntryAndUpdate(SQLiteDatabase db, Context context,
+ int id, int folderId, String srcTableName, String destTableName) {
+ return copyEntryAndUpdate(db, context, null, id, folderId, srcTableName, destTableName);
+ }
+
+ private static int copyEntryAndUpdate(SQLiteDatabase db, Context context,
+ DbEntry entry, int id, int folderId, String srcTableName, String destTableName) {
+ int newId = -1;
+ Cursor c = db.query(srcTableName, null,
+ LauncherSettings.Favorites._ID + " = '" + (entry != null ? entry.id : id) + "'",
null, null, null, null);
-
while (c.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(c, values);
- entry.updateContentValues(values);
- values.put(LauncherSettings.Favorites._ID,
- LauncherSettings.Settings.call(context.getContentResolver(),
- LauncherSettings.Settings.METHOD_NEW_ITEM_ID).getInt(
- LauncherSettings.Settings.EXTRA_VALUE));
+ if (entry != null) {
+ entry.updateContentValues(values);
+ } else {
+ values.put(LauncherSettings.Favorites.CONTAINER, folderId);
+ }
+ newId = LauncherSettings.Settings.call(context.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_ITEM_ID).getInt(
+ LauncherSettings.Settings.EXTRA_VALUE);
+ values.put(LauncherSettings.Favorites._ID, newId);
db.insert(destTableName, null, values);
}
c.close();
+ return newId;
}
- private static void removeEntryFromDb(SQLiteDatabase db, String tableName, IntArray entryId) {
+ private static void removeEntryFromDb(SQLiteDatabase db, String tableName, IntArray entryIds) {
db.delete(tableName,
- Utilities.createDbSelectionQuery(LauncherSettings.Favorites._ID, entryId), null);
+ Utilities.createDbSelectionQuery(LauncherSettings.Favorites._ID, entryIds), null);
}
private static HashSet<String> getValidPackages(Context context) {
@@ -381,8 +371,8 @@
continue;
}
if (findPlacement(entry)) {
- insertEntryInDb(mDb, mContext, mSrcReader.mWorkspaceEntries, entry,
- mSrcReader.mTableName, mDestReader.mTableName);
+ insertEntryInDb(mDb, mContext, entry, mSrcReader.mTableName,
+ mDestReader.mTableName);
iterator.remove();
}
}
@@ -451,8 +441,8 @@
// to something other than -1.
entry.cellX = i;
entry.cellY = 0;
- insertEntryInDb(mDb, mContext, mSrcReader.mHotseatEntries, entry,
- mSrcReader.mTableName, mDestReader.mTableName);
+ insertEntryInDb(mDb, mContext, entry, mSrcReader.mTableName,
+ mDestReader.mTableName);
mOccupied.markCells(entry, true);
}
}
@@ -669,10 +659,11 @@
int total = 0;
while (c.moveToNext()) {
try {
+ int id = c.getInt(0);
String intent = c.getString(1);
verifyIntent(intent);
total++;
- entry.mFolderItems.add(intent);
+ entry.mFolderItems.put(intent, id);
} catch (Exception e) {
removeEntryFromDb(mDb, mTableName, IntArray.wrap(c.getInt(0)));
}
@@ -711,7 +702,7 @@
private String mIntent;
private String mProvider;
- private Set<String> mFolderItems = new HashSet<>();
+ private Map<String, Integer> mFolderItems = new HashMap<>();
/** Comparator according to the reading order */
@Override
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 244de96..165d1ea 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -65,7 +65,7 @@
private static final String TAG = "LoaderCursor";
- public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
+ public final LongSparseArray<UserHandle> allUsers;
private final Uri mContentUri;
private final Context mContext;
@@ -100,9 +100,11 @@
public int itemType;
public int restoreFlag;
- public LoaderCursor(Cursor cursor, Uri contentUri, LauncherAppState app) {
+ public LoaderCursor(Cursor cursor, Uri contentUri, LauncherAppState app,
+ UserManagerState userManagerState) {
super(cursor);
+ allUsers = userManagerState.allUsers;
mContentUri = contentUri;
mContext = app.getContext();
mIconCache = app.getIconCache();
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index d05d70b..f2073ef 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -17,6 +17,9 @@
package com.android.launcher3.model;
import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
@@ -35,6 +38,7 @@
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.net.Uri;
import android.os.UserHandle;
@@ -120,6 +124,8 @@
private final InstallSessionHelper mSessionHelper;
private final IconCache mIconCache;
+ private final UserManagerState mUserManagerState = new UserManagerState();
+
private boolean mStopped;
public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
@@ -333,7 +339,8 @@
Map<ShortcutKey, ShortcutInfo> shortcutKeyToPinnedShortcuts = new HashMap<>();
final LoaderCursor c = new LoaderCursor(
- contentResolver.query(contentUri, null, null, null, null), contentUri, mApp);
+ contentResolver.query(contentUri, null, null, null, null), contentUri, mApp,
+ mUserManagerState);
Map<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
@@ -352,12 +359,13 @@
LauncherSettings.Favorites.OPTIONS);
final LongSparseArray<UserHandle> allUsers = c.allUsers;
- final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
+
+ mUserManagerState.init(mUserCache, mUserManager);
+
for (UserHandle user : mUserCache.getUserProfiles()) {
long serialNo = mUserCache.getSerialNumberForUser(user);
allUsers.put(serialNo, user);
- quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
boolean userUnlocked = mUserManager.isUserUnlocked(user);
@@ -404,8 +412,8 @@
continue;
}
- int disabledState = quietMode.get(c.serialNumber) ?
- WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
+ int disabledState = mUserManagerState.isUserQuiet(c.serialNumber)
+ ? WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
ComponentName cn = intent.getComponent();
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
@@ -862,8 +870,8 @@
for (ComponentKey key : componentKeys) {
l = mLauncherApps.getActivityList(key.componentName.getPackageName(), key.user);
if (l.size() == 0) continue;
- boolean quietMode = mUserManager.isQuietModeEnabled(key.user);
- AppInfo info = new AppInfo(l.get(0), key.user, quietMode);
+ AppInfo info = new AppInfo(l.get(0), key.user,
+ mUserManagerState.isUserQuiet(key.user));
mBgDataModel.cachedPredictedItems.add(info);
mIconCache.getTitleAndIcon(info, false);
}
@@ -883,7 +891,7 @@
if (apps == null || apps.isEmpty()) {
return allActivityList;
}
- boolean quietMode = mUserManager.isQuietModeEnabled(user);
+ boolean quietMode = mUserManagerState.isUserQuiet(user);
// Create the ApplicationInfos
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
@@ -905,11 +913,19 @@
List<LauncherActivityInfo> l = mLauncherApps.getActivityList(
item.componentName.getPackageName(), item.user);
for (LauncherActivityInfo info : l) {
- boolean quietMode = mUserManager.isQuietModeEnabled(item.user);
+ boolean quietMode = mUserManagerState.isUserQuiet(item.user);
mBgAllAppsList.add(new AppInfo(info, item.user, quietMode), info);
}
}
+ mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
+ mUserManagerState.isAnyProfileQuietModeEnabled());
+ mBgAllAppsList.setFlags(FLAG_HAS_SHORTCUT_PERMISSION,
+ hasShortcutsPermission(mApp.getContext()));
+ mBgAllAppsList.setFlags(FLAG_QUIET_MODE_CHANGE_PERMISSION,
+ mApp.getContext().checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
+ == PackageManager.PERMISSION_GRANTED);
+
mBgAllAppsList.getAndResetChangeFlag();
return allActivityList;
}
@@ -917,8 +933,8 @@
private List<ShortcutInfo> loadDeepShortcuts() {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
mBgDataModel.deepShortcutMap.clear();
- mBgDataModel.hasShortcutHostPermission = hasShortcutsPermission(mApp.getContext());
- if (mBgDataModel.hasShortcutHostPermission) {
+
+ if (mBgAllAppsList.hasShortcutHostPermission()) {
for (UserHandle user : mUserCache.getUserProfiles()) {
if (mUserManager.isUserUnlocked(user)) {
List<ShortcutInfo> shortcuts = new ShortcutRequest(mApp.getContext(), user)
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 2fa6051..7cd467e 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.model;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
import static com.android.launcher3.model.data.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
import static com.android.launcher3.model.data.WorkspaceItemInfo.FLAG_RESTORED_ICON;
@@ -41,6 +42,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntSparseArrayMap;
@@ -149,14 +151,21 @@
if (DEBUG) Log.d(TAG, "mAllAppsList.(un)suspend " + N);
appsList.updateDisabledFlags(matcher, flagOp);
break;
- case OP_USER_AVAILABILITY_CHANGE:
- flagOp = context.getSystemService(UserManager.class).isQuietModeEnabled(mUser)
+ case OP_USER_AVAILABILITY_CHANGE: {
+ UserManagerState ums = new UserManagerState();
+ ums.init(UserCache.INSTANCE.get(context),
+ context.getSystemService(UserManager.class));
+ flagOp = ums.isUserQuiet(mUser)
? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER)
: FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER);
// We want to update all packages for this user.
matcher = ItemInfoMatcher.ofUser(mUser);
appsList.updateDisabledFlags(matcher, flagOp);
+
+ // We are not synchronizing here, as int operations are atomic
+ appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled());
break;
+ }
}
bindApplicationsIfNeeded();
diff --git a/src/com/android/launcher3/model/UserManagerState.java b/src/com/android/launcher3/model/UserManagerState.java
new file mode 100644
index 0000000..3a4206c
--- /dev/null
+++ b/src/com/android/launcher3/model/UserManagerState.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 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.launcher3.model;
+
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.LongSparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.launcher3.pm.UserCache;
+
+/**
+ * Utility class to manager store and user manager state at any particular time
+ */
+public class UserManagerState {
+
+ public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
+
+ private final LongSparseArray<Boolean> mQuietUsersSerialNoMap = new LongSparseArray<>();
+ private final SparseBooleanArray mQuietUsersHashCodeMap = new SparseBooleanArray();
+
+ /**
+ * Initialises the state values for all users
+ */
+ public void init(UserCache userCache, UserManager userManager) {
+ for (UserHandle user : userCache.getUserProfiles()) {
+ long serialNo = userCache.getSerialNumberForUser(user);
+ boolean isUserQuiet = userManager.isQuietModeEnabled(user);
+ allUsers.put(serialNo, user);
+ mQuietUsersHashCodeMap.put(user.hashCode(), isUserQuiet);
+ mQuietUsersSerialNoMap.put(serialNo, isUserQuiet);
+ }
+ }
+
+ /**
+ * Returns true if quiet mode is enabled for the provided user
+ */
+ public boolean isUserQuiet(long serialNo) {
+ return mQuietUsersSerialNoMap.get(serialNo);
+ }
+
+ /**
+ * Returns true if quiet mode is enabled for the provided user
+ */
+ public boolean isUserQuiet(UserHandle user) {
+ return mQuietUsersHashCodeMap.get(user.hashCode());
+ }
+
+ /**
+ * Returns true if any user profile has quiet mode enabled.
+ */
+ public boolean isAnyProfileQuietModeEnabled() {
+ for (int i = mQuietUsersHashCodeMap.size() - 1; i >= 0; i--) {
+ if (mQuietUsersHashCodeMap.valueAt(i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 096743a..8f577b5 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -22,6 +22,8 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.logger.LauncherAtom.Attribute.MANUAL_LABEL;
+import static com.android.launcher3.logger.LauncherAtom.Attribute.SUGGESTED_LABEL;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_EMPTY;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
@@ -205,6 +207,7 @@
return getDefaultItemInfoBuilder()
.setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size()))
.setRank(rank)
+ .setAttribute(fromCustom ? MANUAL_LABEL : SUGGESTED_LABEL)
.setContainerInfo(getContainerInfo())
.build();
}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 0c815d1..8dcdec1 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SEARCH_RESULTS;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SETTINGS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
@@ -46,6 +47,7 @@
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.PredictionContainer;
import com.android.launcher3.logger.LauncherAtom.SearchResultContainer;
+import com.android.launcher3.logger.LauncherAtom.SettingsContainer;
import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
import com.android.launcher3.util.ContentWriter;
@@ -369,6 +371,10 @@
return ContainerInfo.newBuilder()
.setShortcutsContainer(ShortcutsContainer.getDefaultInstance())
.build();
+ case CONTAINER_SETTINGS:
+ return ContainerInfo.newBuilder()
+ .setSettingsContainer(SettingsContainer.getDefaultInstance())
+ .build();
}
return ContainerInfo.getDefaultInstance();
}
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index e5525b2..fa1bdfb 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -16,6 +16,8 @@
package com.android.launcher3.notification;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_LAUNCH_TAP;
+
import android.app.ActivityOptions;
import android.app.Notification;
import android.app.PendingIntent;
@@ -32,6 +34,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.graphics.IconPalette;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.PackageUserKey;
/**
@@ -51,6 +54,7 @@
public final boolean autoCancel;
public final boolean dismissable;
+ private final ItemInfo mItemInfo;
private Drawable mIconDrawable;
private int mIconColor;
private boolean mIsIconLarge;
@@ -58,7 +62,8 @@
/**
* Extracts the data that we need from the StatusBarNotification.
*/
- public NotificationInfo(Context context, StatusBarNotification statusBarNotification) {
+ public NotificationInfo(Context context, StatusBarNotification statusBarNotification,
+ ItemInfo itemInfo) {
packageUserKey = PackageUserKey.fromNotification(statusBarNotification);
notificationKey = statusBarNotification.getKey();
Notification notification = statusBarNotification.getNotification();
@@ -88,6 +93,7 @@
intent = notification.contentIntent;
autoCancel = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0;
dismissable = (notification.flags & Notification.FLAG_ONGOING_EVENT) == 0;
+ this.mItemInfo = itemInfo;
}
@Override
@@ -101,6 +107,8 @@
try {
intent.send(null, 0, null, null, null, null, activityOptions);
launcher.getUserEventDispatcher().logNotificationLaunch(view, intent);
+ launcher.getStatsLogManager()
+ .log(LAUNCHER_NOTIFICATION_LAUNCH_TAP, mItemInfo.buildProto());
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index f723256..5aab41a 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.content.Intent;
-import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -107,22 +106,6 @@
}
/**
- * Returns true if any user profile has quiet mode enabled.
- */
- public boolean isAnyProfileQuietModeEnabled() {
- List<UserHandle> userProfiles = getUserProfiles();
- for (UserHandle userProfile : userProfiles) {
- if (Process.myUserHandle().equals(userProfile)) {
- continue;
- }
- if (mUserManager.isQuietModeEnabled(userProfile)) {
- return true;
- }
- }
- return false;
- }
-
- /**
* @see UserManager#getSerialNumberForUser(UserHandle)
*/
public long getSerialNumberForUser(UserHandle user) {
@@ -160,16 +143,4 @@
List<UserHandle> users = mUserManager.getUserProfiles();
return users == null ? Collections.emptyList() : users;
}
-
- /**
- * Returns true is there is at least one user profile enabled
- */
- public boolean hasWorkProfile() {
- synchronized (this) {
- if (mUsers != null) {
- return mUsers.size() > 1;
- }
- }
- return getUserProfiles().size() > 1;
- }
}
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 18bc55a..5b0c388 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -293,8 +293,8 @@
// gravity to CENTER_HORIZONTAL, but continue below to update y.
} else {
boolean canBeLeftAligned = x + width + insets.left
- < dragLayer.getRight() - insets.right;
- boolean canBeRightAligned = x > dragLayer.getLeft() + insets.left;
+ < dragLayer.getWidth() - insets.right;
+ boolean canBeRightAligned = x > insets.left;
boolean alignmentStillValid = mIsLeftAligned && canBeLeftAligned
|| !mIsLeftAligned && canBeRightAligned;
if (!alignmentStillValid) {
@@ -367,8 +367,10 @@
super.onLayout(changed, l, t, r, b);
// enforce contained is within screen
- ViewGroup dragLayer = getPopupContainer();
- if (getTranslationX() + l < 0 || getTranslationX() + r > dragLayer.getWidth()) {
+ BaseDragLayer dragLayer = getPopupContainer();
+ Rect insets = dragLayer.getInsets();
+ if (getTranslationX() + l < insets.left
+ || getTranslationX() + r > dragLayer.getWidth() - insets.right) {
// If we are still off screen, center horizontally too.
mGravity |= Gravity.CENTER_HORIZONTAL;
}
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index 6d3bc14..5ed6f2e 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -144,7 +144,7 @@
infos = Collections.emptyList();
} else {
infos = notificationListener.getNotificationsForKeys(notificationKeys).stream()
- .map(sbn -> new NotificationInfo(launcher, sbn))
+ .map(sbn -> new NotificationInfo(launcher, sbn, originalInfo))
.collect(Collectors.toList());
}
uiHandler.post(() -> container.applyNotificationInfos(infos));
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 4a15af1..21ad275 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -296,8 +296,8 @@
}
@Override
- public void bindAllApplications(AppInfo[] apps) {
- mAppsView.getAppsStore().setApps(apps);
+ public void bindAllApplications(AppInfo[] apps, int flags) {
+ mAppsView.getAppsStore().setApps(apps, flags);
}
public PopupDataProvider getPopupDataProvider() {
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index ddde6d3..86f3431 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,7 +16,6 @@
package com.android.launcher3.util;
-import static android.content.pm.PackageInstaller.SessionInfo;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import android.app.AppOpsManager;
@@ -45,8 +44,6 @@
import android.util.Pair;
import android.widget.Toast;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -348,15 +345,4 @@
}
return false;
}
-
- /**
- * Returns the created time in millis of given session info. Returns 0 if not available.
- */
- public static long getSessionCreatedTimeInMillis(@NonNull final SessionInfo info) {
- try {
- return (long) SessionInfo.class.getDeclaredMethod("getCreatedMillis").invoke(info);
- } catch (Exception e) {
- return 0;
- }
- }
}
diff --git a/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java
index 86995b7..53cc157 100644
--- a/src/com/android/launcher3/util/SystemUiController.java
+++ b/src/com/android/launcher3/util/SystemUiController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.util;
-import android.text.TextUtils;
import android.view.View;
import android.view.Window;
@@ -33,8 +32,7 @@
public static final int UI_STATE_BASE_WINDOW = 0;
public static final int UI_STATE_ALL_APPS = 1;
public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
- public static final int UI_STATE_ROOT_VIEW = 3;
- public static final int UI_STATE_OVERVIEW = 4;
+ public static final int UI_STATE_OVERVIEW = 3;
public static final int FLAG_LIGHT_NAV = 1 << 0;
public static final int FLAG_DARK_NAV = 1 << 1;
@@ -42,7 +40,7 @@
public static final int FLAG_DARK_STATUS = 1 << 3;
private final Window mWindow;
- private final int[] mStates = new int[5];
+ private final int[] mStates = new int[4];
public SystemUiController(Window window) {
mWindow = window;
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index da59afe..b74686f 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -113,10 +113,17 @@
* Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255].
*/
public static int getAlpha(Context context, int attr) {
+ return (int) (255 * getFloat(context, attr, 0) + 0.5f);
+ }
+
+ /**
+ * Returns the alpha corresponding to the theme attribute {@param attr}
+ */
+ public static float getFloat(Context context, int attr, float defValue) {
TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
- float alpha = ta.getFloat(0, 0);
+ float value = ta.getFloat(0, defValue);
ta.recycle();
- return (int) (255 * alpha + 0.5f);
+ return value;
}
/**
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 7467186..5431ba1 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -17,8 +17,8 @@
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_FLAVOR;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_OFFSET;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WALLPAPER_BUTTON_TAP_OR_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_BUTTON_TAP_OR_LONGPRESS;
import android.content.Context;
@@ -38,10 +38,12 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogManager.EventEnum;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.testing.TestLogging;
@@ -157,7 +159,7 @@
int resDrawable = Utilities.existsStyleWallpapers(launcher) ?
R.drawable.ic_palette : R.drawable.ic_wallpaper;
options.add(new OptionItem(resString, resDrawable,
- LAUNCHER_WALLPAPER_BUTTON_TAP_OR_LONGPRESS,
+ IGNORE,
OptionsPopupView::startWallpaperPicker));
if (!WidgetsModel.GO_DISABLE_WIDGETS) {
options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget,
@@ -218,7 +220,15 @@
if (!TextUtils.isEmpty(pickerPackage)) {
intent.setPackage(pickerPackage);
}
- return launcher.startActivitySafely(v, intent, null, null);
+ return launcher.startActivitySafely(v, intent, dummyInfo(intent), null);
+ }
+
+ static WorkspaceItemInfo dummyInfo(Intent intent) {
+ WorkspaceItemInfo dummyInfo = new WorkspaceItemInfo();
+ dummyInfo.intent = intent;
+ dummyInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+ dummyInfo.container = LauncherSettings.Favorites.CONTAINER_SETTINGS;
+ return dummyInfo;
}
public static class OptionItem {
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index 536b766..68a3ec5 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -24,7 +24,6 @@
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -39,10 +38,8 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.TopRoundedCornerView;
@@ -135,7 +132,7 @@
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthUsed;
if (mInsets.bottom > 0) {
- widthUsed = 0;
+ widthUsed = mInsets.left + mInsets.right;
} else {
Rect padding = mLauncher.getDeviceProfile().workspacePadding;
widthUsed = Math.max(padding.left + padding.right,
@@ -156,7 +153,7 @@
// Content is laid out as center bottom aligned
int contentWidth = mContent.getMeasuredWidth();
- int contentLeft = (width - contentWidth) / 2;
+ int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left;
mContent.layout(contentLeft, height - mContent.getMeasuredHeight(),
contentLeft + contentWidth, height);
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index df11557..a4aa9f2 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -265,14 +265,12 @@
private void verifyWidgetPresent(LauncherAppWidgetProviderInfo info) {
final Widget widget = mLauncher.getWorkspace().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT);
- if (widget == null) mLauncher.dumpViewHierarchy(); // b/152645831
assertTrue("Widget is not present",
widget != null);
}
private void verifyPendingWidgetPresent() {
final Widget widget = mLauncher.getWorkspace().tryGetPendingWidget(DEFAULT_UI_TIMEOUT);
- if (widget == null) mLauncher.dumpViewHierarchy(); // b/152645831
assertTrue("Pending widget is not present",
widget != null);
}