Merge changes I705b7a65,I98a2e71a into ub-launcher3-qt-dev
* changes:
Allow touches on launcher while animating to home
End window animation to home when handler invalidated
diff --git a/go/quickstep/res/layout/icon_recents_root_view.xml b/go/quickstep/res/layout/icon_recents_root_view.xml
index b64b7fd..595a380 100644
--- a/go/quickstep/res/layout/icon_recents_root_view.xml
+++ b/go/quickstep/res/layout/icon_recents_root_view.xml
@@ -18,14 +18,16 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:clipChildren="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recent_task_recycler_view"
android:layout_width="@dimen/recents_list_width"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:scrollbars="none"
- android:clipToPadding="false"/>
+ android:clipToPadding="false"
+ android:clipChildren="false"/>
<TextView
android:id="@+id/recent_task_empty_view"
android:layout_width="match_parent"
diff --git a/go/quickstep/res/values-sw480dp/dimens.xml b/go/quickstep/res/values-sw480dp/dimens.xml
index be27d4b..b48dafb 100644
--- a/go/quickstep/res/values-sw480dp/dimens.xml
+++ b/go/quickstep/res/values-sw480dp/dimens.xml
@@ -25,6 +25,6 @@
<dimen name="clear_all_item_view_height">48dp</dimen>
<dimen name="clear_all_item_view_top_margin">28dp</dimen>
- <dimen name="clear_all_item_view_landscape_bottom_margin">28dp</dimen>
+ <dimen name="clear_all_item_view_bottom_margin">28dp</dimen>
<dimen name="clear_all_button_width">140dp</dimen>
</resources>
\ No newline at end of file
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
index 60e997a..91040f2 100644
--- a/go/quickstep/res/values/dimens.xml
+++ b/go/quickstep/res/values/dimens.xml
@@ -25,6 +25,6 @@
<dimen name="clear_all_item_view_height">36dp</dimen>
<dimen name="clear_all_item_view_top_margin">20dp</dimen>
- <dimen name="clear_all_item_view_landscape_bottom_margin">20dp</dimen>
+ <dimen name="clear_all_item_view_bottom_margin">20dp</dimen>
<dimen name="clear_all_button_width">106dp</dimen>
</resources>
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/quickstep/TaskListLoader.java b/go/quickstep/src/com/android/quickstep/TaskListLoader.java
index 850c7e6..1335cac 100644
--- a/go/quickstep/src/com/android/quickstep/TaskListLoader.java
+++ b/go/quickstep/src/com/android/quickstep/TaskListLoader.java
@@ -80,7 +80,8 @@
return;
}
// TODO: Look into error checking / more robust handling for when things go wrong.
- mTaskListChangeId = mRecentsModel.getTasks(tasks -> {
+ mTaskListChangeId = mRecentsModel.getTasks(loadedTasks -> {
+ ArrayList<Task> tasks = new ArrayList<>(loadedTasks);
// Reverse tasks to put most recent at the bottom of the view
Collections.reverse(tasks);
// Load task content
diff --git a/go/quickstep/src/com/android/quickstep/TaskSwipeCallback.java b/go/quickstep/src/com/android/quickstep/TaskSwipeCallback.java
index 19951bb..7686543 100644
--- a/go/quickstep/src/com/android/quickstep/TaskSwipeCallback.java
+++ b/go/quickstep/src/com/android/quickstep/TaskSwipeCallback.java
@@ -19,6 +19,8 @@
import static com.android.quickstep.TaskAdapter.ITEM_TYPE_CLEAR_ALL;
+import android.graphics.Canvas;
+
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
@@ -50,6 +52,18 @@
}
@Override
+ public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView,
+ @NonNull ViewHolder viewHolder, float dX, float dY, int actionState,
+ boolean isCurrentlyActive) {
+ if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
+ float alpha = 1.0f - dX / (float) viewHolder.itemView.getWidth();
+ viewHolder.itemView.setAlpha(alpha);
+ }
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY,
+ actionState, isCurrentlyActive);
+ }
+
+ @Override
public int getSwipeDirs(@NonNull RecyclerView recyclerView,
@NonNull ViewHolder viewHolder) {
if (viewHolder.getItemViewType() == ITEM_TYPE_CLEAR_ALL) {
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
index ce22489..f951304 100644
--- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -16,7 +16,6 @@
package com.android.quickstep.views;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
@@ -32,7 +31,6 @@
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.ArraySet;
@@ -125,6 +123,7 @@
private boolean mTransitionedFromApp;
private AnimatorSet mLayoutAnimation;
private final ArraySet<View> mLayingOutViews = new ArraySet<>();
+ private Rect mInsets;
private final RecentsModel.TaskThumbnailChangeListener listener = (taskId, thumbnailData) -> {
ArrayList<TaskItemView> itemViews = getTaskViews();
for (int i = 0, size = itemViews.size(); i < size; i++) {
@@ -194,13 +193,25 @@
case ITEM_TYPE_CLEAR_ALL:
outRect.top = (int) res.getDimension(
R.dimen.clear_all_item_view_top_margin);
- if (res.getConfiguration().orientation == ORIENTATION_LANDSCAPE) {
- outRect.bottom = (int) res.getDimension(
- R.dimen.clear_all_item_view_landscape_bottom_margin);
+ int desiredBottomMargin = (int) res.getDimension(
+ R.dimen.clear_all_item_view_bottom_margin);
+ // Only add bottom margin if insets aren't enough.
+ if (mInsets.bottom < desiredBottomMargin) {
+ outRect.bottom = desiredBottomMargin - mInsets.bottom;
}
break;
case ITEM_TYPE_TASK:
- outRect.top = (int) res.getDimension(R.dimen.task_item_top_margin);
+ int desiredTopMargin = (int) res.getDimension(
+ R.dimen.task_item_top_margin);
+ if (mTaskRecyclerView.getChildAdapterPosition(view) ==
+ state.getItemCount() - 1) {
+ // Only add top margin to top task view if insets aren't enough.
+ if (mInsets.top < desiredTopMargin) {
+ outRect.top = desiredTopMargin - mInsets.bottom;
+ }
+ return;
+ }
+ outRect.top = desiredTopMargin;
break;
default:
}
@@ -233,11 +244,6 @@
}
}
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- mTaskRecyclerView.invalidateItemDecorations();
- }
-
/**
* Set activity helper for the view to callback to.
*
@@ -522,6 +528,8 @@
@Override
public void setInsets(Rect insets) {
+ mInsets = insets;
mTaskRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
+ mTaskRecyclerView.invalidateItemDecorations();
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
index bd78573..0b8c1c5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionAppTracker.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.appprediction;
-import static com.android.launcher3.appprediction.PredictionUiStateManager.KEY_APP_SUGGESTION;
+import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import android.annotation.TargetApi;
import android.app.prediction.AppPredictionContext;
@@ -26,8 +26,6 @@
import android.app.prediction.AppTargetId;
import android.content.ComponentName;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
@@ -35,12 +33,10 @@
import android.util.Log;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.util.UiThreadHelper;
-import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
-
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
@@ -48,8 +44,7 @@
* Subclass of app tracker which publishes the data to the prediction engine and gets back results.
*/
@TargetApi(Build.VERSION_CODES.Q)
-public class PredictionAppTracker extends AppLaunchTracker
- implements OnSharedPreferenceChangeListener {
+public class PredictionAppTracker extends AppLaunchTracker {
private static final String TAG = "PredictionAppTracker";
private static final boolean DBG = false;
@@ -62,8 +57,6 @@
private final Context mContext;
private final Handler mMessageHandler;
- private boolean mEnabled;
-
// Accessed only on worker thread
private AppPredictor mHomeAppPredictor;
private AppPredictor mRecentsOverviewPredictor;
@@ -71,24 +64,16 @@
public PredictionAppTracker(Context context) {
mContext = context;
mMessageHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleMessage);
-
- SharedPreferences prefs = Utilities.getPrefs(context);
- setEnabled(prefs.getBoolean(KEY_APP_SUGGESTION, true));
- prefs.registerOnSharedPreferenceChangeListener(this);
InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
+
+ mMessageHandler.sendEmptyMessage(MSG_INIT);
}
@UiThread
private void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
- // Reinitialize everything
- setEnabled(mEnabled);
- }
-
- @Override
- @UiThread
- public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (KEY_APP_SUGGESTION.equals(key)) {
- setEnabled(prefs.getBoolean(KEY_APP_SUGGESTION, true));
+ if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
+ // Reinitialize everything
+ mMessageHandler.sendEmptyMessage(MSG_INIT);
}
}
@@ -137,13 +122,13 @@
return true;
}
case MSG_LAUNCH: {
- if (mEnabled && mHomeAppPredictor != null) {
+ if (mHomeAppPredictor != null) {
mHomeAppPredictor.notifyAppTargetEvent((AppTargetEvent) msg.obj);
}
return true;
}
case MSG_PREDICT: {
- if (mEnabled && mHomeAppPredictor != null) {
+ if (mHomeAppPredictor != null) {
String client = (String) msg.obj;
if (Client.HOME.id.equals(client)) {
mHomeAppPredictor.requestPredictionUpdate();
@@ -168,18 +153,6 @@
}
}
- @UiThread
- public void setEnabled(boolean isEnabled) {
- mEnabled = isEnabled;
- if (isEnabled) {
- mMessageHandler.removeMessages(MSG_DESTROY);
- mMessageHandler.sendEmptyMessage(MSG_INIT);
- } else {
- mMessageHandler.removeMessages(MSG_INIT);
- mMessageHandler.sendEmptyMessage(MSG_DESTROY);
- }
- }
-
@Override
@UiThread
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
index 54fd845..48a163d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
@@ -24,8 +24,7 @@
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Handler;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import com.android.launcher3.AppInfo;
@@ -61,9 +60,10 @@
* that client id.
*/
public class PredictionUiStateManager implements OnGlobalLayoutListener, ItemInfoUpdateReceiver,
- OnSharedPreferenceChangeListener, OnIDPChangeListener, OnUpdateListener {
+ OnIDPChangeListener, OnUpdateListener {
- public static final String KEY_APP_SUGGESTION = "pref_show_predictions";
+ public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
+ private static final long INITIAL_CALLBACK_WAIT_TIMEOUT_MS = 5000;
// TODO (b/129421797): Update the client constants
public enum Client {
@@ -81,7 +81,6 @@
new MainThreadInitializedObject<>(PredictionUiStateManager::new);
private final Context mContext;
- private final SharedPreferences mMainPrefs;
private final DynamicItemCache mDynamicItemCache;
private final List[] mPredictionServicePredictions;
@@ -94,9 +93,10 @@
private PredictionState mPendingState;
private PredictionState mCurrentState;
+ private boolean mGettingValidPredictionResults;
+
private PredictionUiStateManager(Context context) {
mContext = context;
- mMainPrefs = Utilities.getPrefs(context);
mDynamicItemCache = new DynamicItemCache(context, this::onAppsUpdated);
@@ -110,8 +110,14 @@
for (int i = 0; i < mPredictionServicePredictions.length; i++) {
mPredictionServicePredictions[i] = Collections.emptyList();
}
- // Listens for enable/disable signal, and predictions if using AiAi is disabled.
- mMainPrefs.registerOnSharedPreferenceChangeListener(this);
+
+ mGettingValidPredictionResults = Utilities.getDevicePrefs(context)
+ .getBoolean(LAST_PREDICTION_ENABLED_STATE, true);
+ if (mGettingValidPredictionResults) {
+ new Handler().postDelayed(
+ this::updatePredictionStateAfterCallback, INITIAL_CALLBACK_WAIT_TIMEOUT_MS);
+ }
+
// Call this last
mCurrentState = parseLastState();
}
@@ -177,13 +183,6 @@
}
}
- @Override
- public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (KEY_APP_SUGGESTION.equals(key)) {
- dispatchOnChange(true);
- }
- }
-
private void applyState(PredictionState state) {
boolean wasEnabled = mCurrentState.isEnabled;
mCurrentState = state;
@@ -198,10 +197,24 @@
}
}
+ private void updatePredictionStateAfterCallback() {
+ boolean validResults = false;
+ for (List l : mPredictionServicePredictions) {
+ validResults |= l != null && !l.isEmpty();
+ }
+ if (validResults != mGettingValidPredictionResults) {
+ mGettingValidPredictionResults = validResults;
+ Utilities.getDevicePrefs(mContext).edit()
+ .putBoolean(LAST_PREDICTION_ENABLED_STATE, true)
+ .apply();
+ }
+ dispatchOnChange(true);
+ }
+
public AppPredictor.Callback appPredictorCallback(Client client) {
return targets -> {
mPredictionServicePredictions[client.ordinal()] = targets;
- dispatchOnChange(true);
+ updatePredictionStateAfterCallback();
};
}
@@ -217,7 +230,7 @@
private PredictionState parseLastState() {
PredictionState state = new PredictionState();
- state.isEnabled = mMainPrefs.getBoolean(KEY_APP_SUGGESTION, true);
+ state.isEnabled = mGettingValidPredictionResults;
if (!state.isEnabled) {
state.apps = Collections.EMPTY_LIST;
return state;
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 e5747dc..624b3dc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -137,7 +137,7 @@
Rect targetRect = new Rect();
mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity, targetRect);
clipHelper.updateTargetRect(targetRect);
- clipHelper.prepareAnimation(false /* isOpening */);
+ clipHelper.prepareAnimation(mActivity.getDeviceProfile(), false /* isOpening */);
ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
.setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index 3d2659d..50f25fb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -116,10 +116,12 @@
} else {
workspaceView = null;
}
- final Rect iconLocation = new Rect();
- final FloatingIconView floatingView = workspaceView == null ? null
- : FloatingIconView.getFloatingIconView(activity, workspaceView,
- true /* hideOriginal */, iconLocation, false /* isOpening */, null /* recycle */);
+ final RectF iconLocation = new RectF();
+ boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
+ final FloatingIconView floatingView = canUseWorkspaceView
+ ? FloatingIconView.getFloatingIconView(activity, workspaceView,
+ true /* hideOriginal */, iconLocation, false /* isOpening */, null /* recycle */)
+ : null;
return new HomeAnimationFactory() {
@Nullable
@@ -135,8 +137,8 @@
final float targetCenterX = dp.availableWidthPx / 2f;
final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx;
- if (workspaceView != null) {
- return new RectF(iconLocation);
+ if (canUseWorkspaceView) {
+ return iconLocation;
} else {
// Fallback to animate to center of screen.
return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize,
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
index 507535e..833a468 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OtherActivityInputConsumer.java
@@ -35,19 +35,15 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.PointF;
-import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
-import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.WindowManager;
-import androidx.annotation.UiThread;
-
import com.android.launcher3.R;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RaceConditionTracker;
@@ -62,10 +58,11 @@
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.WindowManagerWrapper;
import java.util.function.Consumer;
+import androidx.annotation.UiThread;
+
/**
* Input consumer for handling events originating from an activity other than Launcher
*/
@@ -81,14 +78,12 @@
private final Intent mHomeIntent;
private final ActivityControlHelper mActivityControlHelper;
private final OverviewCallbacks mOverviewCallbacks;
- private final TaskOverlayFactory mTaskOverlayFactory;
private final InputConsumerController mInputConsumer;
private final SwipeSharedState mSwipeSharedState;
private final InputMonitorCompat mInputMonitorCompat;
private final SysUINavigationMode.Mode mMode;
private final int mDisplayRotation;
- private final Rect mStableInsets = new Rect();
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
private final MotionPauseDetector mMotionPauseDetector;
@@ -123,7 +118,7 @@
public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo,
RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
- TaskOverlayFactory taskOverlayFactory, InputConsumerController inputConsumer,
+ InputConsumerController inputConsumer,
Consumer<OtherActivityInputConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat) {
super(base);
@@ -145,14 +140,10 @@
boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null;
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
mOverviewCallbacks = overviewCallbacks;
- mTaskOverlayFactory = taskOverlayFactory;
mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
- Display display = getSystemService(WindowManager.class).getDefaultDisplay();
- mDisplayRotation = display.getRotation();
- WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
-
+ mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
mDragSlop = QuickStepContract.getQuickStepDragSlopPx();
mTouchSlop = QuickStepContract.getQuickStepTouchSlopPx();
@@ -171,16 +162,15 @@
}
// Proxy events to recents view
- if (!isNavBarOnLeft() && !isNavBarOnRight()) {
- if (mPassedDragSlop && mInteractionHandler != null
- && !mRecentsViewDispatcher.hasConsumer()) {
- mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher());
- }
- int edgeFlags = ev.getEdgeFlags();
- ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
- mRecentsViewDispatcher.dispatchEvent(ev);
- ev.setEdgeFlags(edgeFlags);
+ if (mPassedDragSlop && mInteractionHandler != null
+ && !mRecentsViewDispatcher.hasConsumer()) {
+ mRecentsViewDispatcher.setConsumer(mInteractionHandler
+ .getRecentsViewDispatcher(isNavBarOnLeft() || isNavBarOnRight()));
}
+ int edgeFlags = ev.getEdgeFlags();
+ ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
+ mRecentsViewDispatcher.dispatchEvent(ev);
+ ev.setEdgeFlags(edgeFlags);
mVelocityTracker.addMovement(ev);
if (ev.getActionMasked() == ACTION_POINTER_UP) {
@@ -302,13 +292,11 @@
}
private boolean isNavBarOnRight() {
- return SysUINavigationMode.INSTANCE.get(getBaseContext()).getMode() != NO_BUTTON
- && mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
}
private boolean isNavBarOnLeft() {
- return SysUINavigationMode.INSTANCE.get(getBaseContext()).getMode() != NO_BUTTON
- && mDisplayRotation == Surface.ROTATION_270 && mStableInsets.left > 0;
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
@@ -414,13 +402,13 @@
}
private float getDisplacement(MotionEvent ev) {
- float eventX = ev.getX();
- float eventY = ev.getY();
- float displacement = eventY - mDownPos.y;
+ final float displacement;
if (isNavBarOnRight()) {
- displacement = eventX - mDownPos.x;
+ displacement = ev.getX() - mDownPos.x;
} else if (isNavBarOnLeft()) {
- displacement = mDownPos.x - eventX;
+ displacement = mDownPos.x - ev.getX();
+ } else {
+ displacement = ev.getY() - mDownPos.y;
}
return displacement;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index 5b94002..f95f9c2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -26,8 +26,11 @@
import android.graphics.RectF;
import android.view.View;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
@@ -134,7 +137,9 @@
{
inOutHelper.setTaskAlphaCallback((t, alpha) -> mTaskAlpha.value);
- inOutHelper.prepareAnimation(true /* isOpening */);
+ inOutHelper.prepareAnimation(
+ BaseActivity.fromContext(v.getContext()).getDeviceProfile(),
+ true /* isOpening */);
inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(),
targetSet.apps.length == 0 ? null : targetSet.apps[0]);
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 c91bb1b..09a1f3b 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.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
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;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -436,9 +435,9 @@
}
private boolean isInValidSystemUiState() {
- return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0;
+ return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
+ && !ActivityManagerWrapper.getInstance().isLockToAppActive();
}
private InputConsumer newConsumer(boolean useSharedState, MotionEvent event) {
@@ -492,8 +491,8 @@
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewComponentObserver.getOverviewIntent(), activityControl,
- shouldDefer, mOverviewCallbacks, mTaskOverlayFactory, mInputConsumer,
- this::onConsumerInactive, mSwipeSharedState, mInputMonitorCompat);
+ shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
+ mSwipeSharedState, mInputMonitorCompat);
}
/**
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 5783f60..30fce52 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -533,8 +533,8 @@
return TaskView.getCurveScaleForInterpolation(interpolation);
}
- public Consumer<MotionEvent> getRecentsViewDispatcher() {
- return mRecentsView != null ? mRecentsView::dispatchTouchEvent : null;
+ public Consumer<MotionEvent> getRecentsViewDispatcher(boolean isTransposed) {
+ return mRecentsView != null ? mRecentsView.getEventDispatcher(isTransposed) : null;
}
@UiThread
@@ -732,7 +732,7 @@
if (runningTaskTarget != null) {
mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
}
- mClipAnimationHelper.prepareAnimation(false /* isOpening */);
+ mClipAnimationHelper.prepareAnimation(dp, false /* isOpening */);
initTransitionEndpoints(dp);
mRecentsAnimationWrapper.setController(targetSet);
@@ -1089,7 +1089,9 @@
@Override
public void onAnimationStart(Animator animation) {
homeAnim.dispatchOnStart();
- mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
+ if (mActivity != null) {
+ mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
+ }
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
index 1242d79..cb2bf1f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -81,6 +81,7 @@
private final RectF mClipRectF = new RectF();
private final RectFEvaluator mRectFEvaluator = new RectFEvaluator();
private final Matrix mTmpMatrix = new Matrix();
+ private final Rect mTmpRect = new Rect();
private final RectF mTmpRectF = new RectF();
private final RectF mCurrentRectWithInsets = new RectF();
// Corner radius of windows, in pixels
@@ -89,6 +90,8 @@
private final float mTaskCornerRadius;
// If windows can have real time rounded corners.
private final boolean mSupportsRoundedCornersOnWindows;
+ // Whether or not to actually use the rounded cornders on windows
+ private boolean mUseRoundedCornersOnWindows;
// Corner radius currently applied to transformed window.
private float mCurrentCornerRadius;
@@ -103,6 +106,7 @@
mWindowCornerRadius = getWindowCornerRadius(context.getResources());
mSupportsRoundedCornersOnWindows = supportsRoundedCornersOnWindows(context.getResources());
mTaskCornerRadius = TaskCornerRadius.get(context);
+ mUseRoundedCornersOnWindows = mSupportsRoundedCornersOnWindows;
}
private void updateSourceStack(RemoteAnimationTargetCompat target) {
@@ -144,8 +148,9 @@
mSourceRect.set(scaledTargetRect);
}
- public void prepareAnimation(boolean isOpening) {
+ public void prepareAnimation(DeviceProfile dp, boolean isOpening) {
mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING;
+ mUseRoundedCornersOnWindows = mSupportsRoundedCornersOnWindows && !dp.isMultiWindowMode;
}
public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params) {
@@ -177,7 +182,9 @@
for (int i = 0; i < targetSet.unfilteredApps.length; i++) {
RemoteAnimationTargetCompat app = targetSet.unfilteredApps[i];
mTmpMatrix.setTranslate(app.position.x, app.position.y);
- Rect crop = app.sourceContainerBounds;
+ Rect crop = mTmpRect;
+ crop.set(app.sourceContainerBounds);
+ crop.offsetTo(0, 0);
float alpha = 1f;
int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
float cornerRadius = 0f;
@@ -188,7 +195,9 @@
mTmpMatrix.postTranslate(app.position.x, app.position.y);
mClipRectF.roundOut(crop);
if (mSupportsRoundedCornersOnWindows) {
- cornerRadius = Utilities.mapRange(params.progress, mWindowCornerRadius,
+ float windowCornerRadius = mUseRoundedCornersOnWindows
+ ? mWindowCornerRadius : 0;
+ cornerRadius = Utilities.mapRange(params.progress, windowCornerRadius,
mTaskCornerRadius);
mCurrentCornerRadius = cornerRadius;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewDrawable.java
index 10283bf..2ac61c5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewDrawable.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/TaskViewDrawable.java
@@ -52,7 +52,7 @@
private final RecentsView mParent;
private final View mIconView;
- private final int[] mIconPos;
+ private final float[] mIconPos;
private final TaskView mTaskView;
private final TaskThumbnailView mThumbnailView;
@@ -68,7 +68,7 @@
mParent = parent;
mTaskView = tv;
mIconView = tv.getIconView();
- mIconPos = new int[2];
+ mIconPos = new float[2];
mIconScale = mIconView.getScaleX();
Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true);
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 08a7616..2fdfda1 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
@@ -45,6 +45,7 @@
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -70,9 +71,6 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ListView;
-import androidx.annotation.Nullable;
-import androidx.dynamicanimation.animation.SpringForce;
-
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
@@ -111,6 +109,9 @@
import java.util.ArrayList;
import java.util.function.Consumer;
+import androidx.annotation.Nullable;
+import androidx.dynamicanimation.animation.SpringForce;
+
/**
* A list of recent tasks.
*/
@@ -1639,4 +1640,26 @@
public ClearAllButton getClearAllButton() {
return mClearAllButton;
}
+
+ public Consumer<MotionEvent> getEventDispatcher(boolean isTransposed) {
+ if (isTransposed) {
+ Matrix transform = new Matrix();
+ transform.setRotate(90);
+
+ if (getWidth() > 0 && getHeight() > 0) {
+ float scale = ((float) getWidth()) / getHeight();
+ transform.postScale(scale, 1 / scale);
+ }
+
+ Matrix inverse = new Matrix();
+ transform.invert(inverse);
+ return e -> {
+ e.transform(transform);
+ super.onTouchEvent(e);
+ e.transform(inverse);
+ };
+ } else {
+ return super::onTouchEvent;
+ }
+ }
}
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 ed68d87..1117855 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
@@ -51,7 +51,6 @@
import com.android.quickstep.util.TaskCornerRadius;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.QuickStepContract;
/**
* A task in the Recents view.
@@ -60,6 +59,7 @@
private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
+ private final static Rect EMPTY_RECT = new Rect();
public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
new FloatProperty<TaskThumbnailView>("dimAlpha") {
@@ -83,12 +83,13 @@
private final Paint mBackgroundPaint = new Paint();
private final Paint mClearPaint = new Paint();
private final Paint mDimmingPaintAfterClearing = new Paint();
- private final float mWindowCornerRadius;
private final Matrix mMatrix = new Matrix();
private float mClipBottom = -1;
private Rect mScaledInsets = new Rect();
+ private Rect mCurrentDrawnInsets = new Rect();
+ private float mCurrentDrawnCornerRadius;
private boolean mIsRotated;
private Task mTask;
@@ -117,7 +118,7 @@
mDimmingPaintAfterClearing.setColor(Color.BLACK);
mActivity = BaseActivity.fromContext(context);
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
- mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
+ setCurrentDrawnInsetsAndRadius(EMPTY_RECT, mCornerRadius);
}
public void bind(Task task) {
@@ -200,25 +201,24 @@
@Override
protected void onDraw(Canvas canvas) {
- TaskView taskView = (TaskView) getParent();
- float fullscreenProgress = taskView.getFullscreenProgress();
- if (mIsRotated) {
- // Don't show insets in the wrong orientation.
- fullscreenProgress = 0;
- }
- if (fullscreenProgress > 0) {
- // Draw the insets if we're being drawn fullscreen (we do this for quick switch).
- float cornerRadius = Utilities.mapRange(fullscreenProgress, mCornerRadius,
- mWindowCornerRadius);
- drawOnCanvas(canvas,
- -mScaledInsets.left * fullscreenProgress,
- -mScaledInsets.top * fullscreenProgress,
- getMeasuredWidth() + mScaledInsets.right * fullscreenProgress,
- getMeasuredHeight() + mScaledInsets.bottom * fullscreenProgress,
- cornerRadius / taskView.getRecentsView().getScaleX());
- } else {
- drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
- }
+ // Draw the insets if we're being drawn fullscreen (we do this for quick switch).
+ drawOnCanvas(canvas,
+ -mCurrentDrawnInsets.left,
+ -mCurrentDrawnInsets.top,
+ getMeasuredWidth() + mCurrentDrawnInsets.right,
+ getMeasuredHeight() + mCurrentDrawnInsets.bottom,
+ mCurrentDrawnCornerRadius);
+ }
+
+ public Rect getInsetsToDrawInFullscreen() {
+ // Don't show insets in the wrong orientation.
+ return mIsRotated ? EMPTY_RECT : mScaledInsets;
+ }
+
+ public void setCurrentDrawnInsetsAndRadius(Rect insets, float radius) {
+ mCurrentDrawnInsets.set(insets);
+ mCurrentDrawnCornerRadius = radius;
+ invalidate();
}
public float getCornerRadius() {
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 298c562..c448f7a 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
@@ -17,7 +17,6 @@
package com.android.quickstep.views;
import static android.widget.Toast.LENGTH_SHORT;
-
import static com.android.launcher3.BaseActivity.fromContext;
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
@@ -32,6 +31,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Outline;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -47,6 +47,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -54,7 +55,6 @@
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.PendingAnimation;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.ViewPool.Reusable;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TaskIconCache;
@@ -62,12 +62,15 @@
import com.android.quickstep.TaskSystemShortcut;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.util.TaskCornerRadius;
import com.android.quickstep.views.RecentsView.PageCallbacks;
import com.android.quickstep.views.RecentsView.ScrollState;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.QuickStepContract;
+import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -96,6 +99,9 @@
public static final long SCALE_ICON_DURATION = 120;
private static final long DIM_ANIM_DURATION = 700;
+ private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
+ Collections.singletonList(new Rect());
+
public static final Property<TaskView, Float> ZOOM_SCALE =
new FloatProperty<TaskView>("zoomScale") {
@Override
@@ -150,6 +156,8 @@
}
};
+ private final TaskOutlineProvider mOutlineProvider;
+
private Task mTask;
private TaskThumbnailView mSnapshotView;
private TaskMenuView mMenuView;
@@ -158,6 +166,9 @@
private float mCurveScale;
private float mZoomScale;
private float mFullscreenProgress;
+ private final Rect mCurrentDrawnInsets = new Rect();
+ private float mCornerRadius;
+ private float mWindowCornerRadius;
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
@@ -199,7 +210,10 @@
fromContext(context).getStatsLogManager().logTaskLaunch(getRecentsView(),
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
});
- setOutlineProvider(new TaskOutlineProvider(context, getResources()));
+ mCornerRadius = TaskCornerRadius.get(context);
+ mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
+ mOutlineProvider = new TaskOutlineProvider(getResources(), mCornerRadius);
+ setOutlineProvider(mOutlineProvider);
}
@Override
@@ -481,6 +495,10 @@
super.onLayout(changed, left, top, right, bottom);
setPivotX((right - left) * 0.5f);
setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f);
+ if (Utilities.ATLEAST_Q) {
+ SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(0, 0, getWidth(), getHeight());
+ setSystemGestureExclusionRects(SYSTEM_GESTURE_EXCLUSION_RECT);
+ }
}
public static float getCurveScaleForInterpolation(float linearInterpolation) {
@@ -521,17 +539,26 @@
private static final class TaskOutlineProvider extends ViewOutlineProvider {
private final int mMarginTop;
- private final float mRadius;
+ private final Rect mInsets = new Rect();
+ private float mRadius;
- TaskOutlineProvider(Context context, Resources res) {
+ TaskOutlineProvider(Resources res, float radius) {
mMarginTop = res.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
- mRadius = Themes.getDialogCornerRadius(context);
+ mRadius = radius;
+ }
+
+ public void setCurrentDrawnInsetsAndRadius(Rect insets, float radius) {
+ mInsets.set(insets);
+ mRadius = radius;
}
@Override
public void getOutline(View view, Outline outline) {
- outline.setRoundRect(0, mMarginTop, view.getWidth(),
- view.getHeight(), mRadius);
+ outline.setRoundRect(-mInsets.left,
+ mMarginTop - mInsets.top,
+ view.getWidth() + mInsets.right,
+ view.getHeight() + mInsets.bottom,
+ mRadius);
}
}
@@ -629,11 +656,19 @@
mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
setClipChildren(!isFullscreen);
setClipToPadding(!isFullscreen);
- getThumbnail().invalidate();
- }
- public float getFullscreenProgress() {
- return mFullscreenProgress;
+ TaskThumbnailView thumbnail = getThumbnail();
+ Rect insets = thumbnail.getInsetsToDrawInFullscreen();
+ mCurrentDrawnInsets.set((int) (insets.left * mFullscreenProgress),
+ (int) (insets.top * mFullscreenProgress),
+ (int) (insets.right * mFullscreenProgress),
+ (int) (insets.bottom * mFullscreenProgress));
+ float cornerRadius = Utilities.mapRange(mFullscreenProgress, mCornerRadius,
+ mWindowCornerRadius) / getRecentsView().getScaleX();
+
+ thumbnail.setCurrentDrawnInsetsAndRadius(mCurrentDrawnInsets, cornerRadius);
+ mOutlineProvider.setCurrentDrawnInsetsAndRadius(mCurrentDrawnInsets, cornerRadius);
+ invalidateOutline();
}
public boolean isRunningTask() {
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 886dcc3..e1a115a 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -408,7 +408,7 @@
*/
private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets,
Rect windowTargetBounds, boolean toggleVisibility) {
- Rect bounds = new Rect();
+ RectF bounds = new RectF();
mFloatingView = FloatingIconView.getFloatingIconView(mLauncher, v, toggleVisibility,
bounds, true /* isOpening */, mFloatingView);
Rect crop = new Rect();
@@ -422,10 +422,9 @@
// Scale the app icon to take up the entire screen. This simplifies the math when
// animating the app window position / scale.
- float maxScaleX = windowTargetBounds.width() / (float) bounds.width();
- // We use windowTargetBounds.width for scaleY too since we start off the animation where the
- // window is clipped to a square.
- float maxScaleY = windowTargetBounds.width() / (float) bounds.height();
+ float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
+ float maxScaleX = smallestSize / bounds.width();
+ float maxScaleY = smallestSize / bounds.height();
float scale = Math.max(maxScaleX, maxScaleY);
float startScale = 1f;
if (v instanceof BubbleTextView && !(v.getParent() instanceof DeepShortcutView)) {
diff --git a/quickstep/src/com/android/quickstep/TestInformationProvider.java b/quickstep/src/com/android/quickstep/TestInformationProvider.java
index a948570..b37ddda 100644
--- a/quickstep/src/com/android/quickstep/TestInformationProvider.java
+++ b/quickstep/src/com/android/quickstep/TestInformationProvider.java
@@ -111,14 +111,6 @@
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance);
break;
}
-
- case TestProtocol.REQUEST_ENABLE_DRAG_LOGGING:
- TestProtocol.sDebugTracing = true;
- break;
-
- case TestProtocol.REQUEST_DISABLE_DRAG_LOGGING:
- TestProtocol.sDebugTracing = false;
- break;
}
return response;
}
diff --git a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
index 72de80b..e028fcd 100644
--- a/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
+++ b/quickstep/tests/src/com/android/quickstep/AppPredictionsUITests.java
@@ -17,6 +17,7 @@
package com.android.quickstep;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
@@ -25,7 +26,9 @@
import android.content.pm.LauncherActivityInfo;
import android.os.Process;
import android.view.View;
-import android.widget.ProgressBar;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
@@ -44,13 +47,9 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class AppPredictionsUITests extends AbstractQuickStepTest {
- private static final String TAG = "AppPredictionsUITests";
+public class AppPredictionsUITests extends AbstractQuickStepTest {
private LauncherActivityInfo mSampleApp1;
private LauncherActivityInfo mSampleApp2;
@@ -86,28 +85,21 @@
* Test that prediction UI is updated as soon as we get predictions from the system
*/
@Test
- @Ignore // b/131188880
public void testPredictionExistsInAllApps() {
mActivityMonitor.startLauncher();
mLauncher.pressHome().switchToAllApps();
- // There has not been any update, verify that progress bar is showing
- waitForLauncherCondition("Prediction is not in loading state", launcher -> {
- ProgressBar p = findLoadingBar(launcher);
- return p != null && p.isShown();
- });
-
// Dispatch an update
sendPredictionUpdate(mSampleApp1, mSampleApp2);
+ // The first update should apply immediately.
waitForLauncherCondition("Predictions were not updated in loading state",
launcher -> getPredictedApp(launcher).size() == 2);
}
/**
- * Test tat prediction update is deferred if it is already visible
+ * Test that prediction update is deferred if it is already visible
*/
@Test
- @Ignore // b/131188880
public void testPredictionsDeferredUntilHome() {
mActivityMonitor.startLauncher();
sendPredictionUpdate(mSampleApp1, mSampleApp2);
@@ -124,6 +116,20 @@
assertEquals(3, getFromLauncher(this::getPredictedApp).size());
}
+ @Test
+ @Ignore
+ public void testPredictionsDisabled() {
+ mActivityMonitor.startLauncher();
+ sendPredictionUpdate();
+ mLauncher.pressHome().switchToAllApps();
+
+ waitForLauncherCondition("Predictions were not updated in loading state",
+ launcher -> launcher.getAppsView().getFloatingHeaderView()
+ .findFixedRowByType(PredictionRowView.class).getVisibility() == View.GONE);
+ assertFalse(PredictionUiStateManager.INSTANCE.get(mTargetContext)
+ .getCurrentState().isEnabled);
+ }
+
public ArrayList<BubbleTextView> getPredictedApp(Launcher launcher) {
PredictionRowView container = launcher.getAppsView().getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class);
@@ -138,20 +144,6 @@
return predictedAppViews;
}
- private ProgressBar findLoadingBar(Launcher launcher) {
- PredictionRowView container = launcher.getAppsView().getFloatingHeaderView()
- .findFixedRowByType(PredictionRowView.class);
-
- for (int i = 0; i < container.getChildCount(); i++) {
- View view = container.getChildAt(i);
- if (view instanceof ProgressBar) {
- return (ProgressBar) view;
- }
- }
- return null;
- }
-
-
private void sendPredictionUpdate(LauncherActivityInfo... activities) {
getOnUiThread(() -> {
List<AppTarget> targets = new ArrayList<>(activities.length);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index b0ce5f5..4b6b3ee 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -64,7 +64,7 @@
private void startTestApps() throws Exception {
startAppFast(getAppPackageName());
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS));
+ startTestActivity(2);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
@@ -130,8 +130,8 @@
OverviewTask task = mLauncher.pressHome().switchToOverview().getCurrentTask();
assertNotNull("overview.getCurrentTask() returned null (1)", task);
assertNotNull("OverviewTask.open returned null", task.open());
- assertTrue("Contacts app didn't open from Overview", mDevice.wait(Until.hasObject(
- By.pkg(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS)).depth(0)),
+ assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject(
+ By.pkg(getAppPackageName()).text("TestActivity2")),
LONG_WAIT_TIME_MS));
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index c6fd906..ccd9e25 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -36,6 +36,7 @@
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.uioverrides.DisplayRotationListener;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
+import com.android.launcher3.util.Themes;
import androidx.annotation.Nullable;
@@ -69,7 +70,7 @@
// Update theme
WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this);
wallpaperColorInfo.addOnChangeListener(this);
- int themeRes = getThemeRes(wallpaperColorInfo);
+ int themeRes = Themes.getActivityThemeRes(this);
if (themeRes != mThemeRes) {
mThemeRes = themeRes;
setTheme(themeRes);
@@ -88,31 +89,11 @@
}
private void updateTheme() {
- WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this);
- if (mThemeRes != getThemeRes(wallpaperColorInfo)) {
+ if (mThemeRes != Themes.getActivityThemeRes(this)) {
recreate();
}
}
- protected int getThemeRes(WallpaperColorInfo wallpaperColorInfo) {
- boolean darkTheme;
- if (Utilities.ATLEAST_Q) {
- Configuration configuration = getResources().getConfiguration();
- int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
- darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES;
- } else {
- darkTheme = wallpaperColorInfo.isDark();
- }
-
- if (darkTheme) {
- return wallpaperColorInfo.supportsDarkText() ?
- R.style.AppTheme_Dark_DarkText : R.style.AppTheme_Dark;
- } else {
- return wallpaperColorInfo.supportsDarkText() ?
- R.style.AppTheme_DarkText : R.style.AppTheme;
- }
- }
-
@Override
public void onActionModeStarted(ActionMode mode) {
super.onActionModeStarted(mode);
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index f300ef7..c84be4d 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -123,12 +123,12 @@
* @param ev MotionEvent in {@param eventSource}
*/
public boolean shouldContainerScroll(MotionEvent ev, View eventSource) {
- int[] point = new int[2];
- point[0] = (int) ev.getX();
- point[1] = (int) ev.getY();
+ float[] point = new float[2];
+ point[0] = ev.getX();
+ point[1] = ev.getY();
Utilities.mapCoordInSelfToDescendant(mScrollbar, eventSource, point);
// IF the MotionEvent is inside the thumb, container should not be pulled down.
- if (mScrollbar.shouldBlockIntercept(point[0], point[1])) {
+ if (mScrollbar.shouldBlockIntercept((int) point[0], (int) point[1])) {
return false;
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 3611ad4..8291acc 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -142,7 +142,6 @@
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mActivity = ActivityContext.lookupContext(context);
- DeviceProfile grid = mActivity.getDeviceProfile();
mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
TypedArray a = context.obtainStyledAttributes(attrs,
@@ -150,18 +149,24 @@
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
- int defaultIconSize = grid.iconSizePx;
+ final int defaultIconSize;
if (display == DISPLAY_WORKSPACE) {
+ DeviceProfile grid = mActivity.getWallpaperDeviceProfile();
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
+ defaultIconSize = grid.iconSizePx;
} else if (display == DISPLAY_ALL_APPS) {
+ DeviceProfile grid = mActivity.getDeviceProfile();
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
defaultIconSize = grid.allAppsIconSizePx;
} else if (display == DISPLAY_FOLDER) {
+ DeviceProfile grid = mActivity.getDeviceProfile();
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx);
setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx);
defaultIconSize = grid.folderChildIconSizePx;
+ } else {
+ defaultIconSize = mActivity.getDeviceProfile().iconSizePx;
}
mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false);
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 9d9a639..fe6bbc0 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -57,12 +57,14 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.util.CellAndSpan;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ParcelableSparseArray;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.Transposable;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.lang.annotation.Retention;
@@ -76,7 +78,7 @@
import androidx.annotation.IntDef;
import androidx.core.view.ViewCompat;
-public class CellLayout extends ViewGroup {
+public class CellLayout extends ViewGroup implements Transposable {
public static final int WORKSPACE_ACCESSIBILITY_DRAG = 2;
public static final int FOLDER_ACCESSIBILITY_DRAG = 1;
@@ -182,6 +184,7 @@
// Related to accessible drag and drop
private DragAndDropAccessibilityDelegate mTouchHelper;
private boolean mUseTouchHelper = false;
+ private RotationMode mRotationMode = RotationMode.NORMAL;
public CellLayout(Context context) {
this(context, null);
@@ -203,7 +206,7 @@
setClipToPadding(false);
mActivity = ActivityContext.lookupContext(context);
- DeviceProfile grid = mActivity.getDeviceProfile();
+ DeviceProfile grid = mActivity.getWallpaperDeviceProfile();
mCellWidth = mCellHeight = -1;
mFixedCellWidth = mFixedCellHeight = -1;
@@ -317,6 +320,24 @@
}
}
+ public void setRotationMode(RotationMode mode) {
+ if (mRotationMode != mode) {
+ mRotationMode = mode;
+ requestLayout();
+ }
+ }
+
+ @Override
+ public RotationMode getRotationMode() {
+ return mRotationMode;
+ }
+
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ mRotationMode.mapRect(left, top, right, bottom, mTempRect);
+ super.setPadding(mTempRect.left, mTempRect.top, mTempRect.right, mTempRect.bottom);
+ }
+
@Override
public boolean dispatchHoverEvent(MotionEvent event) {
// Always attempt to dispatch hover events to accessibility first.
@@ -745,6 +766,14 @@
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int childWidthSize = widthSize - (getPaddingLeft() + getPaddingRight());
int childHeightSize = heightSize - (getPaddingTop() + getPaddingBottom());
+
+ mShortcutsAndWidgets.setRotation(mRotationMode.surfaceRotation);
+ if (mRotationMode.isTransposed) {
+ int tmp = childWidthSize;
+ childWidthSize = childHeightSize;
+ childHeightSize = tmp;
+ }
+
if (mFixedCellWidth < 0 || mFixedCellHeight < 0) {
int cw = DeviceProfile.calculateCellWidth(childWidthSize, mCountX);
int ch = DeviceProfile.calculateCellHeight(childHeightSize, mCountY);
@@ -787,7 +816,6 @@
int top = getPaddingTop();
int bottom = b - t - getPaddingBottom();
- mShortcutsAndWidgets.layout(left, top, right, bottom);
// Expand the background drawing bounds by the padding baked into the background drawable
mBackground.getPadding(mTempRect);
mBackground.setBounds(
@@ -795,6 +823,16 @@
top - mTempRect.top - getPaddingTop(),
right + mTempRect.right + getPaddingRight(),
bottom + mTempRect.bottom + getPaddingBottom());
+
+ if (mRotationMode.isTransposed) {
+ int halfW = mShortcutsAndWidgets.getMeasuredWidth() / 2;
+ int halfH = mShortcutsAndWidgets.getMeasuredHeight() / 2;
+ int cX = (left + right) / 2;
+ int cY = (top + bottom) / 2;
+ mShortcutsAndWidgets.layout(cX - halfW, cY - halfH, cX + halfW, cY + halfH);
+ } else {
+ mShortcutsAndWidgets.layout(left, top, right, bottom);
+ }
}
/**
@@ -929,7 +967,7 @@
if (resize) {
cellToRect(cellX, cellY, spanX, spanY, r);
if (v instanceof LauncherAppWidgetHostView) {
- DeviceProfile profile = mActivity.getDeviceProfile();
+ DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
}
} else {
diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java
index b86e7c0..639c173 100644
--- a/src/com/android/launcher3/CheckLongPressHelper.java
+++ b/src/com/android/launcher3/CheckLongPressHelper.java
@@ -33,20 +33,12 @@
class CheckForLongPress implements Runnable {
public void run() {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "CheckForLongPress1");
- }
if ((mView.getParent() != null) && mView.hasWindowFocus()
&& !mHasPerformedLongPress) {
boolean handled;
if (mListener != null) {
handled = mListener.onLongClick(mView);
} else {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "CheckForLongPress2");
- }
handled = mView.performLongClick();
}
if (handled) {
@@ -81,21 +73,11 @@
}
mView.postDelayed(mPendingCheckForLongPress,
(long) (ViewConfiguration.getLongPressTimeout() * mLongPressTimeoutFactor));
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "postCheckForLongPress: " + ViewConfiguration.getLongPressTimeout() + " "
- + mLongPressTimeoutFactor);
- }
}
public void cancelLongPress() {
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress != null) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "cancelLongPress @ " + android.util.Log.getStackTraceString(
- new Throwable()));
- }
mView.removeCallbacks(mPendingCheckForLongPress);
mPendingCheckForLongPress = null;
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 6a3a26f..c0affb9 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -419,6 +419,10 @@
updateWorkspacePadding();
}
+ /**
+ * The current device insets. This is generally same as the insets being dispatched to
+ * {@link Insettable} elements, but can differ if the element is using a different profile.
+ */
public Rect getInsets() {
return mInsets;
}
@@ -582,45 +586,6 @@
}
}
- /**
- * Gets an item's location on the home screen. This is useful if the home screen
- * is animating, otherwise use {@link View#getLocationOnScreen(int[])}.
- * @param pageDiff The page difference relative to the current page.
- */
- public void getItemLocation(int cellX, int cellY, int spanX, int spanY, int container,
- int pageDiff, Rect outBounds) {
- outBounds.setEmpty();
- if (container == CONTAINER_HOTSEAT) {
- final int actualHotseatCellHeight;
- if (isVerticalBarLayout()) {
- actualHotseatCellHeight = availableHeightPx / inv.numRows;
- if (mIsSeascape) {
- outBounds.left = mHotseatPadding.left;
- } else {
- outBounds.left = availableWidthPx - hotseatBarSizePx + mHotseatPadding.left;
- }
- outBounds.right = outBounds.left + iconSizePx;
- outBounds.top = mHotseatPadding.top
- + actualHotseatCellHeight * (inv.numRows - cellX - 1);
- outBounds.bottom = outBounds.top + actualHotseatCellHeight;
- } else {
- actualHotseatCellHeight = hotseatBarSizePx - hotseatBarBottomPaddingPx
- - hotseatBarTopPaddingPx;
- outBounds.left = mInsets.left + workspacePadding.left + cellLayoutPaddingLeftRightPx
- + (cellX * getCellSize().x);
- outBounds.right = outBounds.left + getCellSize().x;
- outBounds.top = mInsets.top + availableHeightPx - hotseatBarSizePx;
- outBounds.bottom = outBounds.top + actualHotseatCellHeight;
- }
- } else {
- outBounds.left = mInsets.left + workspacePadding.left + cellLayoutPaddingLeftRightPx
- + (cellX * getCellSize().x) + (pageDiff * availableWidthPx);
- outBounds.right = outBounds.left + (getCellSize().x * spanX);
- outBounds.top = mInsets.top + workspacePadding.top + (cellY * getCellSize().y);
- outBounds.bottom = outBounds.top + (getCellSize().y * spanY);
- }
- }
-
private static Context getContext(Context c, int orientation) {
Configuration context = new Configuration(c.getResources().getConfiguration());
context.orientation = orientation;
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index 0543e8d..ca001a3 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -204,7 +204,7 @@
return visibleCount;
}
- private void animateToVisibility(boolean isVisible) {
+ public void animateToVisibility(boolean isVisible) {
if (mVisible != isVisible) {
mVisible = isVisible;
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 4da7907..00acdcd 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -26,11 +26,13 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.views.Transposable;
-public class Hotseat extends CellLayout implements LogContainerProvider, Insettable {
+public class Hotseat extends CellLayout implements LogContainerProvider, Insettable, Transposable {
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
@@ -77,7 +79,8 @@
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- DeviceProfile grid = mActivity.getDeviceProfile();
+ DeviceProfile grid = mActivity.getWallpaperDeviceProfile();
+ insets = grid.getInsets();
if (grid.isVerticalBarLayout()) {
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
@@ -105,4 +108,9 @@
// Don't let if follow through to workspace
return true;
}
+
+ @Override
+ public RotationMode getRotationMode() {
+ return Launcher.getLauncher(getContext()).getRotationMode();
+ }
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index fda674f..417c5a2 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -53,6 +53,7 @@
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Point;
+import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -71,6 +72,7 @@
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
@@ -93,6 +95,7 @@
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
@@ -272,6 +275,9 @@
private float mCurrentAssistantVisibility = 0f;
+ private DeviceProfile mStableDeviceProfile;
+ private RotationMode mRotationMode = RotationMode.NORMAL;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
RaceConditionTracker.onEvent(ON_CREATE_EVT, ENTER);
@@ -390,6 +396,12 @@
}
}
});
+
+ if (FeatureFlags.FAKE_LANDSCAPE_UI.get()) {
+ WindowManager.LayoutParams lp = getWindow().getAttributes();
+ lp.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+ getWindow().setAttributes(lp);
+ }
}
@Override
@@ -418,6 +430,10 @@
@Override
protected void reapplyUi() {
+ if (FeatureFlags.FAKE_LANDSCAPE_UI.get()) {
+ mRotationMode = mStableDeviceProfile == null ? RotationMode.NORMAL :
+ (mDeviceProfile.isSeascape() ? RotationMode.SEASCAPE : RotationMode.LANDSCAPE);
+ }
getRootView().dispatchInsets();
getStateManager().reapplyState(true /* cancelCurrentAnimation */);
}
@@ -469,8 +485,41 @@
display.getSize(mwSize);
mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
}
+
+ if (FeatureFlags.FAKE_LANDSCAPE_UI.get() && mDeviceProfile.isVerticalBarLayout()
+ && !mDeviceProfile.isMultiWindowMode) {
+ mStableDeviceProfile = mDeviceProfile.inv.portraitProfile;
+ mRotationMode = mDeviceProfile.isSeascape()
+ ? RotationMode.SEASCAPE : RotationMode.LANDSCAPE;
+ } else {
+ mStableDeviceProfile = null;
+ mRotationMode = RotationMode.NORMAL;
+ }
+
onDeviceProfileInitiated();
- mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout(), true);
+ mModelWriter = mModel.getWriter(getWallpaperDeviceProfile().isVerticalBarLayout(), true);
+ }
+
+ public void updateInsets(Rect insets) {
+ mDeviceProfile.updateInsets(insets);
+ if (mStableDeviceProfile != null) {
+ mStableDeviceProfile.updateInsets(insets);
+ }
+ }
+
+ @Override
+ public RotationMode getRotationMode() {
+ return mRotationMode;
+ }
+
+ /**
+ * Device profile to be used by UI elements which are shown directly on top of the wallpaper
+ * and whose presentation is tied to the wallpaper (and physical device) and not the activity
+ * configuration.
+ */
+ @Override
+ public DeviceProfile getWallpaperDeviceProfile() {
+ return mStableDeviceProfile == null ? mDeviceProfile : mStableDeviceProfile;
}
public RotationHelper getRotationHelper() {
@@ -879,7 +928,7 @@
super.onPause();
mDragController.cancelDrag();
mDragController.resetLastGestureUpTime();
-
+ mDropTargetBar.animateToVisibility(false);
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onPause();
}
@@ -1812,7 +1861,7 @@
mAppWidgetHost.clearViews();
if (mHotseat != null) {
- mHotseat.resetLayout(mDeviceProfile.isVerticalBarLayout());
+ mHotseat.resetLayout(getWallpaperDeviceProfile().isVerticalBarLayout());
}
TraceHelper.endSection("startBinding");
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index e788ceb..e7b4ff4 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -213,7 +213,6 @@
synchronized (mLock) {
Preconditions.assertUIThread();
mCallbacks = new WeakReference<>(callbacks);
- android.util.Log.d("b/131170582", "mCallbacks = " + mCallbacks);
}
}
@@ -331,7 +330,6 @@
// Stop any existing loaders first, so they don't set mModelLoaded to true later
stopLoader();
mModelLoaded = false;
- android.util.Log.d("b/131170582", "1 mModelLoaded = " + mModelLoaded);
}
// Start the loader if launcher is already running, otherwise the loader will run,
@@ -392,7 +390,6 @@
synchronized (mLock) {
LoaderTask oldTask = mLoaderTask;
mLoaderTask = null;
- android.util.Log.d("b/131170582", "1 mLoaderTask = " + mLoaderTask);
if (oldTask != null) {
oldTask.stopLocked();
}
@@ -403,7 +400,6 @@
synchronized (mLock) {
stopLoader();
mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);
- android.util.Log.d("b/131170582", "2 mLoaderTask = " + mLoaderTask);
runOnWorkerThread(mLoaderTask);
}
}
@@ -448,7 +444,6 @@
mTask = task;
mIsLoaderTaskRunning = true;
mModelLoaded = false;
- android.util.Log.d("b/131170582", "2 mModelLoaded = " + mModelLoaded);
}
}
@@ -456,7 +451,6 @@
synchronized (mLock) {
// Everything loaded bind the data.
mModelLoaded = true;
- android.util.Log.d("b/131170582", "3 mModelLoaded = " + mModelLoaded);
}
}
@@ -466,7 +460,6 @@
// If we are still the last one to be scheduled, remove ourselves.
if (mLoaderTask == mTask) {
mLoaderTask = null;
- android.util.Log.d("b/131170582", "3 mLoaderTask = " + mLoaderTask);
}
mIsLoaderTaskRunning = false;
}
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index 90e673b..20eec05 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -81,7 +81,7 @@
UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
// Update device profile before notifying th children.
- mLauncher.getDeviceProfile().updateInsets(insets);
+ mLauncher.updateInsets(insets);
boolean resetState = !insets.equals(mInsets);
setInsets(insets);
@@ -114,7 +114,7 @@
}
public void dispatchInsets() {
- mLauncher.getDeviceProfile().updateInsets(mInsets);
+ mLauncher.updateInsets(mInsets);
super.setInsets(mInsets);
}
@@ -186,14 +186,4 @@
void onWindowVisibilityChanged(int visibility);
}
-
- @Override
- public void requestLayout() {
- super.requestLayout();
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "requestLayout @ " + android.util.Log.getStackTraceString(
- new Throwable()));
- }
- }
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 3a02b07..b640430 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1088,10 +1088,8 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- super.onTouchEvent(ev);
-
// Skip touch handling if there are no pages to swipe
- if (getChildCount() <= 0) return super.onTouchEvent(ev);
+ if (getChildCount() <= 0) return false;
acquireVelocityTrackerAndAddMovement(ev);
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 30f418d..1bd8263 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -93,7 +93,7 @@
public void setupLp(View child) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
if (child instanceof LauncherAppWidgetHostView) {
- DeviceProfile profile = mActivity.getDeviceProfile();
+ DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
profile.appWidgetScale.x, profile.appWidgetScale.y);
} else {
@@ -108,12 +108,12 @@
public int getCellContentHeight() {
return Math.min(getMeasuredHeight(),
- mActivity.getDeviceProfile().getCellHeight(mContainerType));
+ mActivity.getWallpaperDeviceProfile().getCellHeight(mContainerType));
}
public void measureChild(View child) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
- final DeviceProfile profile = mActivity.getDeviceProfile();
+ final DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
if (child instanceof LauncherAppWidgetHostView) {
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
diff --git a/src/com/android/launcher3/TestProtocol.java b/src/com/android/launcher3/TestProtocol.java
index dab4282..ecbaa5b 100644
--- a/src/com/android/launcher3/TestProtocol.java
+++ b/src/com/android/launcher3/TestProtocol.java
@@ -63,9 +63,4 @@
"all-apps-to-overview-swipe-height";
public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT =
"home-to-all-apps-swipe-height";
-
- public static boolean sDebugTracing = false;
- public static final String NO_DRAG_TAG = "b/129434166";
- public static final String REQUEST_ENABLE_DRAG_LOGGING = "enable-drag-logging";
- public static final String REQUEST_DISABLE_DRAG_LOGGING = "disable-drag-logging";
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 382eedd..26364be 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,9 +16,6 @@
package com.android.launcher3;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
-
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.WallpaperManager;
@@ -63,13 +60,12 @@
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.ShortcutConfigActivityInfo;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
-import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.shortcuts.DeepShortcutManager;
-import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.IntArray;
+import com.android.launcher3.views.Transposable;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.io.Closeable;
@@ -97,7 +93,6 @@
private static final int[] sLoc0 = new int[2];
private static final int[] sLoc1 = new int[2];
- private static final float[] sPoint = new float[2];
private static final Matrix sMatrix = new Matrix();
private static final Matrix sInverseMatrix = new Matrix();
@@ -143,7 +138,7 @@
*/
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
- TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
+ TimeUnit.SECONDS, new LinkedBlockingQueue<>());
public static boolean IS_RUNNING_IN_TEST_HARNESS =
ActivityManager.isRunningInTestHarness();
@@ -170,37 +165,60 @@
* assumption fails, we will need to return a pair of scale factors.
*/
public static float getDescendantCoordRelativeToAncestor(
- View descendant, View ancestor, int[] coord, boolean includeRootScroll) {
- sPoint[0] = coord[0];
- sPoint[1] = coord[1];
+ View descendant, View ancestor, float[] coord, boolean includeRootScroll) {
+ return getDescendantCoordRelativeToAncestor(descendant, ancestor, coord, includeRootScroll,
+ false);
+ }
+ /**
+ * Given a coordinate relative to the descendant, find the coordinate in a parent view's
+ * coordinates.
+ *
+ * @param descendant The descendant to which the passed coordinate is relative.
+ * @param ancestor The root view to make the coordinates relative to.
+ * @param coord The coordinate that we want mapped.
+ * @param includeRootScroll Whether or not to account for the scroll of the descendant:
+ * sometimes this is relevant as in a child's coordinates within the descendant.
+ * @param ignoreTransform If true, view transform is ignored
+ * @return The factor by which this descendant is scaled relative to this DragLayer. Caution
+ * this scale factor is assumed to be equal in X and Y, and so if at any point this
+ * assumption fails, we will need to return a pair of scale factors.
+ */
+ public static float getDescendantCoordRelativeToAncestor(View descendant, View ancestor,
+ float[] coord, boolean includeRootScroll, boolean ignoreTransform) {
float scale = 1.0f;
View v = descendant;
while(v != ancestor && v != null) {
// For TextViews, scroll has a meaning which relates to the text position
// which is very strange... ignore the scroll.
if (v != descendant || includeRootScroll) {
- sPoint[0] -= v.getScrollX();
- sPoint[1] -= v.getScrollY();
+ offsetPoints(coord, -v.getScrollX(), -v.getScrollY());
}
- v.getMatrix().mapPoints(sPoint);
- sPoint[0] += v.getLeft();
- sPoint[1] += v.getTop();
+ if (ignoreTransform) {
+ if (v instanceof Transposable) {
+ RotationMode m = ((Transposable) v).getRotationMode();
+ if (m.isTransposed) {
+ sMatrix.setRotate(m.surfaceRotation, v.getPivotX(), v.getPivotY());
+ sMatrix.mapPoints(coord);
+ }
+ }
+ } else {
+ v.getMatrix().mapPoints(coord);
+ }
+ offsetPoints(coord, v.getLeft(), v.getTop());
scale *= v.getScaleX();
v = (View) v.getParent();
}
-
- coord[0] = Math.round(sPoint[0]);
- coord[1] = Math.round(sPoint[1]);
return scale;
}
+
/**
- * Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, int[], boolean)}.
+ * Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}.
*/
- public static void mapCoordInSelfToDescendant(View descendant, View root, int[] coord) {
+ public static void mapCoordInSelfToDescendant(View descendant, View root, float[] coord) {
sMatrix.reset();
View v = descendant;
while(v != root) {
@@ -211,12 +229,23 @@
}
sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY());
sMatrix.invert(sInverseMatrix);
+ sInverseMatrix.mapPoints(coord);
+ }
- sPoint[0] = coord[0];
- sPoint[1] = coord[1];
- sInverseMatrix.mapPoints(sPoint);
- coord[0] = Math.round(sPoint[0]);
- coord[1] = Math.round(sPoint[1]);
+ /**
+ * Sets {@param out} to be same as {@param in} by rounding individual values
+ */
+ public static void roundArray(float[] in, int[] out) {
+ for (int i = 0; i < in.length; i++) {
+ out[i] = Math.round(in[i]);
+ }
+ }
+
+ public static void offsetPoints(float[] points, float offsetX, float offsetY) {
+ for (int i = 0; i < points.length; i += 2) {
+ points[i] += offsetX;
+ points[i + 1] += offsetY;
+ }
}
/**
@@ -569,53 +598,6 @@
return String.format(Locale.ENGLISH, "%d,%d", x, y);
}
- /**
- * Returns the location bounds of a view.
- * - For DeepShortcutView, we return the bounds of the icon view.
- * - For BubbleTextView, we return the icon bounds.
- */
- public static void getLocationBoundsForView(Launcher launcher, View v, Rect outRect) {
- final DragLayer dragLayer = launcher.getDragLayer();
- final boolean isBubbleTextView = v instanceof BubbleTextView;
- final boolean isFolderIcon = v instanceof FolderIcon;
- final Rect rect = new Rect();
-
- // Deep shortcut views have their icon drawn in a separate view.
- final boolean fromDeepShortcutView = v.getParent() instanceof DeepShortcutView;
- if (v instanceof DeepShortcutView) {
- dragLayer.getDescendantRectRelativeToSelf(((DeepShortcutView) v).getIconView(), rect);
- } else if (fromDeepShortcutView) {
- DeepShortcutView view = (DeepShortcutView) v.getParent();
- dragLayer.getDescendantRectRelativeToSelf(view.getIconView(), rect);
- } else if ((isBubbleTextView || isFolderIcon) && v.getTag() instanceof ItemInfo
- && (((ItemInfo) v.getTag()).container == CONTAINER_DESKTOP
- || ((ItemInfo) v.getTag()).container == CONTAINER_HOTSEAT)) {
- CellLayout pageViewIsOn = ((CellLayout) v.getParent().getParent());
- int pageNum = launcher.getWorkspace().indexOfChild(pageViewIsOn);
-
- DeviceProfile dp = launcher.getDeviceProfile();
- ItemInfo info = ((ItemInfo) v.getTag());
- dp.getItemLocation(info.cellX, info.cellY, info.spanX, info.spanY,
- info.container, pageNum - launcher.getCurrentWorkspaceScreen(), rect);
- } else {
- dragLayer.getDescendantRectRelativeToSelf(v, rect);
- }
- int viewLocationLeft = rect.left;
- int viewLocationTop = rect.top;
-
- if (isBubbleTextView && !fromDeepShortcutView) {
- ((BubbleTextView) v).getIconBounds(rect);
- } else if (isFolderIcon) {
- ((FolderIcon) v).getPreviewBounds(rect);
- } else {
- rect.set(0, 0, rect.width(), rect.height());
- }
- viewLocationLeft += rect.left;
- viewLocationTop += rect.top;
- outRect.set(viewLocationLeft, viewLocationTop, viewLocationLeft + rect.width(),
- viewLocationTop + rect.height());
- }
-
public static void unregisterReceiverSafely(Context context, BroadcastReceiver receiver) {
try {
context.unregisterReceiver(receiver);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 8849768..0f4c42d 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -82,6 +82,7 @@
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.graphics.PreloadIconDrawable;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.pageindicators.WorkspacePageIndicator;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
@@ -175,7 +176,9 @@
@Thunk final Launcher mLauncher;
@Thunk DragController mDragController;
+ private final Rect mTempRect = new Rect();
private final int[] mTempXY = new int[2];
+ private final float[] mTempFXY = new float[2];
@Thunk float[] mDragViewVisualCenter = new float[2];
private final float[] mTempTouchCoordinates = new float[2];
@@ -285,18 +288,23 @@
@Override
public void setInsets(Rect insets) {
- mInsets.set(insets);
-
DeviceProfile grid = mLauncher.getDeviceProfile();
- mMaxDistanceForFolderCreation = grid.isTablet
- ? 0.75f * grid.iconSizePx
- : 0.55f * grid.iconSizePx;
+ DeviceProfile stableGrid = mLauncher.getWallpaperDeviceProfile();
+
+ mMaxDistanceForFolderCreation = stableGrid.isTablet
+ ? 0.75f * stableGrid.iconSizePx
+ : 0.55f * stableGrid.iconSizePx;
mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
- Rect padding = grid.workspacePadding;
- setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ Rect padding = stableGrid.workspacePadding;
- if (grid.shouldFadeAdjacentWorkspaceScreens()) {
+ RotationMode rotationMode = mLauncher.getRotationMode();
+
+ rotationMode.mapRect(padding, mTempRect);
+ setPadding(mTempRect.left, mTempRect.top, mTempRect.right, mTempRect.bottom);
+ rotationMode.mapRect(insets, mInsets);
+
+ if (mWorkspaceFadeInAdjacentScreens) {
// In landscape mode the page spacing is set to the default.
setPageSpacing(grid.edgeMarginPx);
} else {
@@ -306,11 +314,13 @@
setPageSpacing(Math.max(grid.edgeMarginPx, padding.left + 1));
}
- int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
- int paddingBottom = grid.cellLayoutBottomPaddingPx;
+
+ int paddingLeftRight = stableGrid.cellLayoutPaddingLeftRightPx;
+ int paddingBottom = stableGrid.cellLayoutBottomPaddingPx;
for (int i = mWorkspaceScreens.size() - 1; i >= 0; i--) {
- mWorkspaceScreens.valueAt(i)
- .setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom);
+ CellLayout page = mWorkspaceScreens.valueAt(i);
+ page.setRotationMode(rotationMode);
+ page.setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom);
}
}
@@ -330,7 +340,7 @@
float scale = 1;
if (isWidget) {
- DeviceProfile profile = mLauncher.getDeviceProfile();
+ DeviceProfile profile = mLauncher.getWallpaperDeviceProfile();
scale = Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
}
size[0] = r.width();
@@ -550,8 +560,10 @@
// created CellLayout.
CellLayout newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
R.layout.workspace_screen, this, false /* attachToRoot */);
- int paddingLeftRight = mLauncher.getDeviceProfile().cellLayoutPaddingLeftRightPx;
- int paddingBottom = mLauncher.getDeviceProfile().cellLayoutBottomPaddingPx;
+ DeviceProfile grid = mLauncher.getWallpaperDeviceProfile();
+ int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
+ int paddingBottom = grid.cellLayoutBottomPaddingPx;
+ newScreen.setRotationMode(mLauncher.getRotationMode());
newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom);
mWorkspaceScreens.put(screenId, newScreen);
@@ -1440,10 +1452,6 @@
public DragView beginDragShared(View child, DragSource source, ItemInfo dragObject,
DragPreviewProvider previewProvider, DragOptions dragOptions) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "beginDragShared");
- }
float iconScale = 1f;
if (child instanceof BubbleTextView) {
Drawable icon = ((BubbleTextView) child).getIcon();
@@ -1934,18 +1942,9 @@
if (child == null) {
return;
}
+
ShortcutAndWidgetContainer boundingLayout = child.getShortcutsAndWidgets();
-
- // Use the absolute left instead of the child left, as we want the visible area
- // irrespective of the visible child. Since the view can only scroll horizontally, the
- // top position is not affected.
- mTempXY[0] = getPaddingLeft() + boundingLayout.getLeft();
- mTempXY[1] = child.getTop() + boundingLayout.getTop();
-
- float scale = mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY);
- outArea.set(mTempXY[0], mTempXY[1],
- (int) (mTempXY[0] + scale * boundingLayout.getMeasuredWidth()),
- (int) (mTempXY[1] + scale * boundingLayout.getMeasuredHeight()));
+ mLauncher.getDragLayer().getDescendantRectRelativeToSelf(boundingLayout, outArea);
}
@Override
@@ -2098,14 +2097,14 @@
}
boolean isPointInSelfOverHotseat(int x, int y) {
- mTempXY[0] = x;
- mTempXY[1] = y;
- mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true);
+ mTempFXY[0] = x;
+ mTempFXY[1] = y;
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempFXY, true);
View hotseat = mLauncher.getHotseat();
- return mTempXY[0] >= hotseat.getLeft() &&
- mTempXY[0] <= hotseat.getRight() &&
- mTempXY[1] >= hotseat.getTop() &&
- mTempXY[1] <= hotseat.getBottom();
+ return mTempFXY[0] >= hotseat.getLeft() &&
+ mTempFXY[0] <= hotseat.getRight() &&
+ mTempFXY[1] >= hotseat.getTop() &&
+ mTempFXY[1] <= hotseat.getBottom();
}
/**
@@ -2115,13 +2114,8 @@
*/
private void mapPointFromDropLayout(CellLayout layout, float[] xy) {
if (mLauncher.isHotseatLayout(layout)) {
- mTempXY[0] = (int) xy[0];
- mTempXY[1] = (int) xy[1];
- mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempXY, true);
- mLauncher.getDragLayer().mapCoordInSelfToDescendant(layout, mTempXY);
-
- xy[0] = mTempXY[0];
- xy[1] = mTempXY[1];
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, xy, true);
+ mLauncher.getDragLayer().mapCoordInSelfToDescendant(layout, xy);
} else {
mapPointFromSelfToChild(layout, xy);
}
@@ -2612,13 +2606,14 @@
DeviceProfile profile = mLauncher.getDeviceProfile();
Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
}
- loc[0] = r.left;
- loc[1] = r.top;
+ mTempFXY[0] = r.left;
+ mTempFXY[1] = r.top;
setFinalTransitionTransform();
float cellLayoutScale =
- mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(layout, loc, true);
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(layout, mTempFXY, true);
resetTransitionTransform();
+ Utilities.roundArray(mTempFXY, loc);
if (scale) {
float dragViewScaleX = (1.0f * r.width()) / dragView.getMeasuredWidth();
@@ -2911,14 +2906,11 @@
&& info.user.equals(user);
final Workspace.ItemOperator packageAndUserAndApp = (ItemInfo info, View view) ->
packageAndUser.evaluate(info, view) && info.itemType == ITEM_TYPE_APPLICATION;
- final Workspace.ItemOperator packageAndUserAndShortcut = (ItemInfo info, View view) ->
- packageAndUser.evaluate(info, view) && (info.itemType == ITEM_TYPE_SHORTCUT
- || info.itemType == ITEM_TYPE_DEEP_SHORTCUT);
- final Workspace.ItemOperator packageAndUserInFolder = (info, view) -> {
+ final Workspace.ItemOperator packageAndUserAndAppInFolder = (info, view) -> {
if (info instanceof FolderInfo) {
FolderInfo folderInfo = (FolderInfo) info;
for (WorkspaceItemInfo shortcutInfo : folderInfo.contents) {
- if (packageAndUser.evaluate(shortcutInfo, view)) {
+ if (packageAndUserAndApp.evaluate(shortcutInfo, view)) {
return true;
}
}
@@ -2926,15 +2918,15 @@
return false;
};
- // Order: App icons, shortcuts, app/shortcut in folder. Items in hotseat get returned first.
+ // Order: App icons, app in folder. Items in hotseat get returned first.
if (ADAPTIVE_ICON_WINDOW_ANIM.get()) {
return getFirstMatch(new CellLayout[] { getHotseat(), currentPage },
- packageAndUserAndApp, packageAndUserAndShortcut, packageAndUserInFolder);
+ packageAndUserAndApp, packageAndUserAndAppInFolder);
} else {
// Do not use Folder as a criteria, since it'll cause a crash when trying to draw
// FolderAdaptiveIcon as the background.
return getFirstMatch(new CellLayout[] { getHotseat(), currentPage },
- packageAndUserAndApp, packageAndUserAndShortcut);
+ packageAndUserAndApp);
}
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 99a8801..8d0259d 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -93,14 +93,16 @@
Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
- // Set the hotseat's pivot point to match the workspace's, so that it scales together.
- DragLayer dragLayer = mLauncher.getDragLayer();
- int[] workspacePivot = new int[]{(int) mWorkspace.getPivotX(),
- (int) mWorkspace.getPivotY()};
- dragLayer.getDescendantCoordRelativeToSelf(mWorkspace, workspacePivot);
- dragLayer.mapCoordInSelfToDescendant(hotseat, workspacePivot);
- hotseat.setPivotX(workspacePivot[0]);
- hotseat.setPivotY(workspacePivot[1]);
+ if (!hotseat.getRotationMode().isTransposed) {
+ // Set the hotseat's pivot point to match the workspace's, so that it scales together.
+ DragLayer dragLayer = mLauncher.getDragLayer();
+ float[] workspacePivot =
+ new float[]{ mWorkspace.getPivotX(), mWorkspace.getPivotY() };
+ dragLayer.getDescendantCoordRelativeToSelf(mWorkspace, workspacePivot);
+ dragLayer.mapCoordInSelfToDescendant(hotseat, workspacePivot);
+ hotseat.setPivotX(workspacePivot[0]);
+ hotseat.setPivotY(workspacePivot[1]);
+ }
float hotseatScale = hotseatScaleAndTranslation.scale;
propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, scaleInterpolator);
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index a55ea82..70df97a 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -110,6 +110,10 @@
"ENABLE_HINTS_IN_OVERVIEW", false,
"Show chip hints and gleams on the overview screen");
+ public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag(
+ "FAKE_LANDSCAPE_UI", false,
+ "Rotate launcher UI instead of using transposed layout");
+
public static void initialize(Context context) {
// Avoid the disk read for user builds
if (Utilities.IS_DEBUG_DEVICE) {
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 7210759..f92e00a 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -219,9 +219,6 @@
}
private void callOnDragStart() {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, "callOnDragStart");
- }
if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
}
@@ -475,9 +472,6 @@
}
private void handleMoveEvent(int x, int y) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG, "handleMoveEvent1");
- }
mDragObject.dragView.move(x, y);
// Drop on someone?
@@ -494,10 +488,6 @@
if (mIsInPreDrag && mOptions.preDragCondition != null
&& mOptions.preDragCondition.shouldStartDrag(mDistanceSinceScroll)) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "handleMoveEvent2");
- }
callOnDragStart();
}
}
@@ -535,10 +525,6 @@
* Call this from a drag source view.
*/
public boolean onControllerTouchEvent(MotionEvent ev) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onControllerTouchEvent1");
- }
if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) {
return false;
}
@@ -559,10 +545,6 @@
break;
}
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onControllerTouchEvent2");
- }
return mDragDriver.onTouchEvent(ev);
}
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 551f2d0..84fc94d 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -45,18 +45,10 @@
public void onDragViewAnimationEnd() { }
public boolean onTouchEvent(MotionEvent ev) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onTouchEvent " + ev);
- }
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onTouchEvent MOVE");
- }
mEventListener.onDriverDragMove(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_UP:
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 9f902ed..8de2f57 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -17,6 +17,10 @@
package com.android.launcher3.dragndrop;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.getMode;
+import static android.view.View.MeasureSpec.getSize;
+
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import android.animation.Animator;
@@ -29,12 +33,14 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
@@ -42,6 +48,7 @@
import com.android.launcher3.DropTargetBar;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
@@ -52,6 +59,7 @@
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.views.Transposable;
import java.util.ArrayList;
@@ -126,10 +134,6 @@
protected boolean findActiveController(MotionEvent ev) {
if (mActivity.getStateManager().getState().disableInteraction) {
// You Shall Not Pass!!!
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "mActiveController = null");
- }
mActiveController = null;
return true;
}
@@ -264,10 +268,10 @@
Rect r = new Rect();
getViewRectRelativeToSelf(dragView, r);
- int coord[] = new int[2];
+ float coord[] = new float[2];
float childScale = child.getScaleX();
- coord[0] = lp.x + (int) (child.getMeasuredWidth() * (1 - childScale) / 2);
- coord[1] = lp.y + (int) (child.getMeasuredHeight() * (1 - childScale) / 2);
+ coord[0] = lp.x + (child.getMeasuredWidth() * (1 - childScale) / 2);
+ coord[1] = lp.y + (child.getMeasuredHeight() * (1 - childScale) / 2);
// Since the child hasn't necessarily been laid out, we force the lp to be updated with
// the correct coordinates (above) and use these to determine the final location
@@ -275,8 +279,8 @@
// We need to account for the scale of the child itself, as the above only accounts for
// for the scale in parents.
scale *= childScale;
- int toX = coord[0];
- int toY = coord[1];
+ int toX = Math.round(coord[0]);
+ int toY = Math.round(coord[1]);
float toScale = scale;
if (child instanceof TextView) {
TextView tv = (TextView) child;
@@ -555,4 +559,159 @@
public WorkspaceAndHotseatScrim getScrim() {
return mScrim;
}
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ RotationMode rotation = mActivity.getRotationMode();
+ int count = getChildCount();
+
+ if (!rotation.isTransposed
+ || getMode(widthMeasureSpec) != EXACTLY
+ || getMode(heightMeasureSpec) != EXACTLY) {
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ child.setRotation(rotation.surfaceRotation);
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ } else {
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+ if (!(child instanceof Transposable)) {
+ measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
+ } else {
+ measureChildWithMargins(child, heightMeasureSpec, 0, widthMeasureSpec, 0);
+
+ child.setPivotX(child.getMeasuredWidth() / 2);
+ child.setPivotY(child.getMeasuredHeight() / 2);
+ child.setRotation(rotation.surfaceRotation);
+ }
+ }
+ setMeasuredDimension(getSize(widthMeasureSpec), getSize(heightMeasureSpec));
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ RotationMode rotation = mActivity.getRotationMode();
+ if (!rotation.isTransposed) {
+ super.onLayout(changed, left, top, right, bottom);
+ return;
+ }
+
+ final int count = getChildCount();
+
+ final int parentWidth = right - left;
+ final int parentHeight = bottom - top;
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+
+ final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) child.getLayoutParams();
+
+ if (lp instanceof LayoutParams) {
+ final LayoutParams dlp = (LayoutParams) lp;
+ if (dlp.customPosition) {
+ child.layout(dlp.x, dlp.y, dlp.x + dlp.width, dlp.y + dlp.height);
+ continue;
+ }
+ }
+
+ final int width = child.getMeasuredWidth();
+ final int height = child.getMeasuredHeight();
+
+ int childLeft;
+ int childTop;
+
+ int gravity = lp.gravity;
+ if (gravity == -1) {
+ gravity = Gravity.TOP | Gravity.START;
+ }
+
+ final int layoutDirection = getLayoutDirection();
+
+ int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+ int horizontalGravity = absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+ int verticalGravity = absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+ if (child instanceof Transposable) {
+ if (rotation == RotationMode.SEASCAPE) {
+ if (horizontalGravity == Gravity.RIGHT) {
+ horizontalGravity = Gravity.LEFT;
+ } else if (horizontalGravity == Gravity.LEFT) {
+ horizontalGravity = Gravity.RIGHT;
+ }
+
+ if (verticalGravity == Gravity.TOP) {
+ verticalGravity = Gravity.BOTTOM;
+ } else if (verticalGravity == Gravity.BOTTOM) {
+ verticalGravity = Gravity.TOP;
+ }
+ }
+
+ switch (horizontalGravity) {
+ case Gravity.CENTER_HORIZONTAL:
+ childTop = (parentHeight - height) / 2 +
+ lp.topMargin - lp.bottomMargin;
+ break;
+ case Gravity.RIGHT:
+ childTop = width / 2 + lp.rightMargin - height / 2;
+ break;
+ case Gravity.LEFT:
+ default:
+ childTop = parentHeight - lp.leftMargin - width / 2 - height / 2;
+ }
+
+ switch (verticalGravity) {
+ case Gravity.CENTER_VERTICAL:
+ childLeft = (parentWidth - width) / 2 +
+ lp.leftMargin - lp.rightMargin;
+ break;
+ case Gravity.BOTTOM:
+ childLeft = parentWidth - width / 2 - height / 2 - lp.bottomMargin;
+ break;
+ case Gravity.TOP:
+ default:
+ childLeft = height / 2 - width / 2 + lp.topMargin;
+ }
+ } else {
+ switch (horizontalGravity) {
+ case Gravity.CENTER_HORIZONTAL:
+ childLeft = (parentWidth - width) / 2 +
+ lp.leftMargin - lp.rightMargin;
+ break;
+ case Gravity.RIGHT:
+ childLeft = parentWidth - width - lp.rightMargin;
+ break;
+ case Gravity.LEFT:
+ default:
+ childLeft = lp.leftMargin;
+ }
+
+ switch (verticalGravity) {
+ case Gravity.TOP:
+ childTop = lp.topMargin;
+ break;
+ case Gravity.CENTER_VERTICAL:
+ childTop = (parentHeight - height) / 2 +
+ lp.topMargin - lp.bottomMargin;
+ break;
+ case Gravity.BOTTOM:
+ childTop = parentHeight - height - lp.bottomMargin;
+ break;
+ default:
+ childTop = lp.topMargin;
+ }
+ }
+
+ child.layout(childLeft, childTop, childLeft + width, childTop + height);
+ }
+ }
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 4dbff1c..f2eae17 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -869,7 +869,7 @@
DeviceProfile grid = mLauncher.getDeviceProfile();
DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
- DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+ DragLayer parent = mLauncher.getDragLayer();
int width = getFolderWidth();
int height = getFolderHeight();
@@ -881,8 +881,7 @@
// We need to bound the folder to the currently visible workspace area
if (mLauncher.getStateManager().getState().overviewUi) {
- mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mLauncher.getOverviewPanel(),
- sTempRect);
+ parent.getDescendantRectRelativeToSelf(mLauncher.getOverviewPanel(), sTempRect);
} else {
mLauncher.getWorkspace().getPageAreaRelativeToDragLayer(sTempRect);
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 02242a3..6fa9ba9 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -159,7 +159,7 @@
"is dependent on this");
}
- DeviceProfile grid = launcher.getDeviceProfile();
+ DeviceProfile grid = launcher.getWallpaperDeviceProfile();
FolderIcon icon = (FolderIcon) LayoutInflater.from(group.getContext())
.inflate(resId, group, false);
@@ -174,7 +174,7 @@
icon.setOnClickListener(ItemClickHandler.INSTANCE);
icon.mInfo = folderInfo;
icon.mLauncher = launcher;
- icon.mDotRenderer = launcher.getDeviceProfile().mDotRenderer;
+ icon.mDotRenderer = grid.mDotRenderer;
icon.setContentDescription(launcher.getString(R.string.folder_name_format, folderInfo.title));
Folder folder = Folder.fromXml(launcher);
folder.setDragController(launcher.getDragController());
@@ -508,7 +508,8 @@
public void drawDot(Canvas canvas) {
if ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0) {
Rect iconBounds = mDotParams.iconBounds;
- BubbleTextView.getIconBounds(this, iconBounds, mLauncher.getDeviceProfile().iconSizePx);
+ BubbleTextView.getIconBounds(this, iconBounds,
+ mLauncher.getWallpaperDeviceProfile().iconSizePx);
// If we are animating to the accepting state, animate the dot out.
mDotParams.scale = Math.max(0, mDotScale - mBackground.getScaleProgress());
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index ac908f4..46df77a 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -42,7 +42,6 @@
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
/**
@@ -135,7 +134,7 @@
mBgColor = ta.getColor(R.styleable.FolderIconPreview_android_colorPrimary, 0);
ta.recycle();
- DeviceProfile grid = activity.getDeviceProfile();
+ DeviceProfile grid = activity.getWallpaperDeviceProfile();
previewSize = grid.folderIconSizePx;
basePreviewOffsetX = (availableSpaceX - previewSize) / 2;
diff --git a/src/com/android/launcher3/graphics/RotationMode.java b/src/com/android/launcher3/graphics/RotationMode.java
new file mode 100644
index 0000000..1b2cbdb
--- /dev/null
+++ b/src/com/android/launcher3/graphics/RotationMode.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.graphics;
+
+import android.graphics.Rect;
+
+public abstract class RotationMode {
+
+ public final float surfaceRotation;
+ public final boolean isTransposed;
+
+ private RotationMode(float surfaceRotation) {
+ this.surfaceRotation = surfaceRotation;
+ isTransposed = surfaceRotation != 0;
+ }
+
+ public final void mapRect(Rect rect, Rect out) {
+ mapRect(rect.left, rect.top, rect.right, rect.bottom, out);
+ }
+
+ public void mapRect(int left, int top, int right, int bottom, Rect out) {
+ out.set(left, top, right, bottom);
+ }
+
+ public static RotationMode NORMAL = new RotationMode(0) { };
+
+ public static RotationMode LANDSCAPE = new RotationMode(-90) {
+ @Override
+ public void mapRect(int left, int top, int right, int bottom, Rect out) {
+ out.left = top;
+ out.top = right;
+ out.right = bottom;
+ out.bottom = left;
+ }
+ };
+
+ public static RotationMode SEASCAPE = new RotationMode(90) {
+ @Override
+ public void mapRect(int left, int top, int right, int bottom, Rect out) {
+ out.left = bottom;
+ out.top = left;
+ out.right = top;
+ out.bottom = right;
+ }
+ };
+}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index c7d93fe..047f486 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -190,10 +190,6 @@
* @return the container if shown or null.
*/
public static PopupContainerWithArrow showForIcon(BubbleTextView icon) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "PopupContainerWithArrow.showForIcon");
- }
Launcher launcher = Launcher.getLauncher(icon.getContext());
if (getOpen(launcher) != null) {
// There is already an items container open, so don't open this one.
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index a1871ff..35fc873 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -233,11 +233,6 @@
@Override
public void onDragStart(boolean start) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "AbstractStateChangeTouchController.onDragStart() called with: start = [" +
- start + "]");
- }
mStartState = mLauncher.getStateManager().getState();
if (mStartState == ALL_APPS) {
mStartContainerType = LauncherLogProto.ContainerType.ALLAPPS;
@@ -269,11 +264,6 @@
public boolean onDrag(float displacement) {
float deltaProgress = mProgressMultiplier * (displacement - mDisplacementShift);
float progress = deltaProgress + mStartProgress;
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "AbstractStateChangeTouchController.onDrag() called with: displacement = [" +
- displacement + "], progress = [" + progress + "]");
- }
updateProgress(progress);
boolean isDragTowardPositive = mSwipeDirection.isPositive(
displacement - mDisplacementShift);
@@ -393,12 +383,6 @@
? MIN_PROGRESS_TO_ALL_APPS : SUCCESS_TRANSITION_PROGRESS;
targetState = (interpolatedProgress > successProgress) ? mToState : mFromState;
}
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "AbstractStateChangeTouchController.onDragEnd() called with: velocity = [" +
- velocity + "], fling = [" + fling + "], target state: " +
- targetState.getClass().getSimpleName());
- }
final float endProgress;
final float startProgress;
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 026770c..0650001 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -66,14 +66,6 @@
}
private static void onClick(View v, String sourceContainer) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onClick() called with: v = [" + v.getClass().getSimpleName() +
- "], sourceContainer = [" +
- (sourceContainer != null ?
- sourceContainer.getClass().getSimpleName() : "null")
- + "]");
- }
// Make sure that rogue clicks don't get through while allapps is launching, or after the
// view has detached (it's possible for this to happen if the view is removed mid touch).
if (v.getWindowToken() == null) {
diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java
index 003b442..babbcdd 100644
--- a/src/com/android/launcher3/touch/ItemLongClickListener.java
+++ b/src/com/android/launcher3/touch/ItemLongClickListener.java
@@ -74,10 +74,6 @@
}
private static boolean onAllAppsItemLongClick(View v) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "onAllAppsItemLongClick");
- }
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!canStartDrag(launcher)) return false;
// When we have exited all apps or are in transition, disregard long clicks
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index a45f17d..0c44012 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -17,6 +17,7 @@
package com.android.launcher3.util;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.ColorMatrix;
@@ -26,12 +27,34 @@
import android.util.TypedValue;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.WallpaperColorInfo;
/**
* Various utility methods associated with theming.
*/
public class Themes {
+ public static int getActivityThemeRes(Context context) {
+ WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(context);
+ boolean darkTheme;
+ if (Utilities.ATLEAST_Q) {
+ Configuration configuration = context.getResources().getConfiguration();
+ int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES;
+ } else {
+ darkTheme = wallpaperColorInfo.isDark();
+ }
+
+ if (darkTheme) {
+ return wallpaperColorInfo.supportsDarkText() ?
+ R.style.AppTheme_Dark_DarkText : R.style.AppTheme_Dark;
+ } else {
+ return wallpaperColorInfo.supportsDarkText() ?
+ R.style.AppTheme_DarkText : R.style.AppTheme;
+ }
+ }
+
public static String getDefaultBodyFont(Context context) {
TypedArray ta = context.obtainStyledAttributes(android.R.style.TextAppearance_DeviceDefault,
new int[]{android.R.attr.fontFamily});
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index c9cdeff..0331a86 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -22,6 +22,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ItemInfo;
+import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.dot.DotInfo;
/**
@@ -56,6 +57,19 @@
DeviceProfile getDeviceProfile();
+ /**
+ * Device profile to be used by UI elements which are shown directly on top of the wallpaper
+ * and whose presentation is tied to the wallpaper (and physical device) and not the activity
+ * configuration.
+ */
+ default DeviceProfile getWallpaperDeviceProfile() {
+ return getDeviceProfile();
+ }
+
+ default RotationMode getRotationMode() {
+ return RotationMode.NORMAL;
+ }
+
static ActivityContext lookupContext(Context context) {
if (context instanceof ActivityContext) {
return (ActivityContext) context;
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 8a15220..3c81bcf 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -88,7 +88,8 @@
// Touch is being dispatched through a proxy from InputMonitor
private static final int TOUCH_DISPATCHING_PROXY = 1 << 2;
- protected final int[] mTmpXY = new int[2];
+ protected final float[] mTmpXY = new float[2];
+ protected final float[] mTmpRectPoints = new float[4];
protected final Rect mHitRect = new Rect();
@ViewDebug.ExportedProperty(category = "launcher")
@@ -148,23 +149,13 @@
}
protected boolean findActiveController(MotionEvent ev) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "mActiveController = null");
- }
mActiveController = null;
if ((mTouchDispatchState & (TOUCH_DISPATCHING_GESTURE | TOUCH_DISPATCHING_PROXY)) == 0) {
// Only look for controllers if we are not dispatching from gesture area and proxy is
// not active
mActiveController = findControllerToHandleTouch(ev);
- if (mActiveController != null) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "setting controller1: " + mActiveController.getClass().getSimpleName());
- }
- return true;
- }
+ if (mActiveController != null) return true;
}
return false;
}
@@ -231,17 +222,8 @@
}
if (mActiveController != null) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "BaseDragLayer before onControllerTouchEvent " +
- mActiveController.getClass().getSimpleName());
- }
return mActiveController.onControllerTouchEvent(ev);
} else {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "BaseDragLayer no controller");
- }
// In case no child view handled the touch event, we may not get onIntercept anymore
return findActiveController(ev);
}
@@ -325,14 +307,16 @@
* @return The factor by which this descendant is scaled relative to this DragLayer.
*/
public float getDescendantRectRelativeToSelf(View descendant, Rect r) {
- mTmpXY[0] = 0;
- mTmpXY[1] = 0;
- float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY);
-
- r.set(mTmpXY[0], mTmpXY[1],
- (int) (mTmpXY[0] + scale * descendant.getMeasuredWidth()),
- (int) (mTmpXY[1] + scale * descendant.getMeasuredHeight()));
- return scale;
+ mTmpRectPoints[0] = 0;
+ mTmpRectPoints[1] = 0;
+ mTmpRectPoints[2] = descendant.getWidth();
+ mTmpRectPoints[3] = descendant.getHeight();
+ float s = getDescendantCoordRelativeToSelf(descendant, mTmpRectPoints);
+ r.left = Math.round(Math.min(mTmpRectPoints[0], mTmpRectPoints[2]));
+ r.top = Math.round(Math.min(mTmpRectPoints[1], mTmpRectPoints[3]));
+ r.right = Math.round(Math.max(mTmpRectPoints[0], mTmpRectPoints[2]));
+ r.bottom = Math.round(Math.max(mTmpRectPoints[1], mTmpRectPoints[3]));
+ return s;
}
public float getLocationInDragLayer(View child, int[] loc) {
@@ -342,6 +326,14 @@
}
public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) {
+ mTmpXY[0] = coord[0];
+ mTmpXY[1] = coord[1];
+ float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY);
+ Utilities.roundArray(mTmpXY, coord);
+ return scale;
+ }
+
+ public float getDescendantCoordRelativeToSelf(View descendant, float[] coord) {
return getDescendantCoordRelativeToSelf(descendant, coord, false);
}
@@ -357,17 +349,27 @@
* this scale factor is assumed to be equal in X and Y, and so if at any point this
* assumption fails, we will need to return a pair of scale factors.
*/
- public float getDescendantCoordRelativeToSelf(View descendant, int[] coord,
+ public float getDescendantCoordRelativeToSelf(View descendant, float[] coord,
boolean includeRootScroll) {
return Utilities.getDescendantCoordRelativeToAncestor(descendant, this,
coord, includeRootScroll);
}
/**
+ * Inverse of {@link #getDescendantCoordRelativeToSelf(View, float[])}.
+ */
+ public void mapCoordInSelfToDescendant(View descendant, float[] coord) {
+ Utilities.mapCoordInSelfToDescendant(descendant, this, coord);
+ }
+
+ /**
* Inverse of {@link #getDescendantCoordRelativeToSelf(View, int[])}.
*/
public void mapCoordInSelfToDescendant(View descendant, int[] coord) {
- Utilities.mapCoordInSelfToDescendant(descendant, this, coord);
+ mTmpXY[0] = coord[0];
+ mTmpXY[1] = coord[1];
+ Utilities.mapCoordInSelfToDescendant(descendant, this, mTmpXY);
+ Utilities.roundArray(mTmpXY, coord);
}
public void getViewRectRelativeToSelf(View v, Rect r) {
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index f2fc718..2574665 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.views;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
@@ -23,6 +26,7 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -61,12 +65,10 @@
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
-import static com.android.launcher3.Utilities.mapToRange;
-
/**
* A view that is created to look like another view with the purpose of creating fluid animations.
*/
-
+@TargetApi(Build.VERSION_CODES.Q)
public class FloatingIconView extends View implements Animator.AnimatorListener, ClipPathView {
public static final float SHAPE_PROGRESS_DURATION = 0.15f;
@@ -78,6 +80,7 @@
private final int mBlurSizeOutline;
+ private boolean mIsVerticalBarLayout = false;
private boolean mIsAdaptiveIcon = false;
private @Nullable Drawable mForeground;
@@ -185,14 +188,16 @@
* @param v The view to copy
* @param positionOut Rect that will hold the size and position of v.
*/
- private void matchPositionOf(Launcher launcher, View v, Rect positionOut) {
- Utilities.getLocationBoundsForView(launcher, v, positionOut);
- final LayoutParams lp = new LayoutParams(positionOut.width(), positionOut.height());
+ private void matchPositionOf(Launcher launcher, View v, RectF positionOut) {
+ getLocationBoundsForView(launcher, v, positionOut);
+ final LayoutParams lp = new LayoutParams(
+ Math.round(positionOut.width()),
+ Math.round(positionOut.height()));
lp.ignoreInsets = true;
// Position the floating view exactly on top of the original
- lp.leftMargin = positionOut.left;
- lp.topMargin = positionOut.top;
+ lp.leftMargin = Math.round(positionOut.left);
+ lp.topMargin = Math.round(positionOut.top);
setLayoutParams(lp);
// Set the properties here already to make sure they are available when running the first
// animation frame.
@@ -200,6 +205,57 @@
+ lp.height);
}
+ /**
+ * Returns the location bounds of a view.
+ * - For DeepShortcutView, we return the bounds of the icon view.
+ * - For BubbleTextView, we return the icon bounds.
+ */
+ private void getLocationBoundsForView(Launcher launcher, View v, RectF outRect) {
+ final boolean isBubbleTextView = v instanceof BubbleTextView;
+ final boolean isFolderIcon = v instanceof FolderIcon;
+
+ // Deep shortcut views have their icon drawn in a separate view.
+ final boolean fromDeepShortcutView = v.getParent() instanceof DeepShortcutView;
+
+ final View targetView;
+ boolean ignoreTransform = false;
+
+ if (v instanceof DeepShortcutView) {
+ targetView = ((DeepShortcutView) v).getIconView();
+ } else if (fromDeepShortcutView) {
+ DeepShortcutView view = (DeepShortcutView) v.getParent();
+ targetView = view.getIconView();
+ } else if ((isBubbleTextView || isFolderIcon) && v.getTag() instanceof ItemInfo
+ && (((ItemInfo) v.getTag()).container == CONTAINER_DESKTOP
+ || ((ItemInfo) v.getTag()).container == CONTAINER_HOTSEAT)) {
+ targetView = v;
+ ignoreTransform = true;
+ } else {
+ targetView = v;
+ }
+
+ float[] points = new float[] {0, 0, targetView.getWidth(), targetView.getHeight()};
+ Utilities.getDescendantCoordRelativeToAncestor(targetView, launcher.getDragLayer(), points,
+ false, ignoreTransform);
+
+ float viewLocationLeft = Math.min(points[0], points[2]);
+ float viewLocationTop = Math.min(points[1], points[3]);
+
+ final Rect iconRect = new Rect();
+ if (isBubbleTextView && !fromDeepShortcutView) {
+ ((BubbleTextView) v).getIconBounds(iconRect);
+ } else if (isFolderIcon) {
+ ((FolderIcon) v).getPreviewBounds(iconRect);
+ } else {
+ iconRect.set(0, 0, Math.abs(Math.round(points[2] - points[0])),
+ Math.abs(Math.round(points[3] - points[1])));
+ }
+ viewLocationLeft += iconRect.left;
+ viewLocationTop += iconRect.top;
+ outRect.set(viewLocationLeft, viewLocationTop, viewLocationLeft + iconRect.width(),
+ viewLocationTop + iconRect.height());
+ }
+
@WorkerThread
private void getIcon(Launcher launcher, View v, ItemInfo info, boolean isOpening,
Runnable onIconLoadedRunnable, CancellationSignal loadIconSignal) {
@@ -273,7 +329,7 @@
}
float aspectRatio = launcher.getDeviceProfile().aspectRatio;
- if (launcher.getDeviceProfile().isVerticalBarLayout()) {
+ if (mIsVerticalBarLayout) {
lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
@@ -318,8 +374,13 @@
mBgDrawableBounds.set(mFinalDrawableBounds);
Utilities.scaleRectAboutCenter(mBgDrawableBounds, scale);
// Since the drawable is at the top of the view, we need to offset to keep it centered.
- mBgDrawableBounds.offsetTo(mBgDrawableBounds.left,
- (int) (mFinalDrawableBounds.top * scale));
+ if (mIsVerticalBarLayout) {
+ mBgDrawableBounds.offsetTo((int) (mFinalDrawableBounds.left * scale),
+ mBgDrawableBounds.top);
+ } else {
+ mBgDrawableBounds.offsetTo(mBgDrawableBounds.left,
+ (int) (mFinalDrawableBounds.top * scale));
+ }
mBackground.setBounds(mBgDrawableBounds);
}
@@ -405,11 +466,12 @@
* @param isOpening True if this view replaces the icon for app open animation.
*/
public static FloatingIconView getFloatingIconView(Launcher launcher, View originalView,
- boolean hideOriginal, Rect positionOut, boolean isOpening, FloatingIconView recycle) {
+ boolean hideOriginal, RectF positionOut, boolean isOpening, FloatingIconView recycle) {
if (recycle != null) {
recycle.recycle();
}
FloatingIconView view = recycle != null ? recycle : new FloatingIconView(launcher);
+ view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
// Match the position of the original view.
view.matchPositionOf(launcher, originalView, positionOut);
diff --git a/src/com/android/launcher3/views/Transposable.java b/src/com/android/launcher3/views/Transposable.java
new file mode 100644
index 0000000..929c1aa
--- /dev/null
+++ b/src/com/android/launcher3/views/Transposable.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import com.android.launcher3.graphics.RotationMode;
+
+/**
+ * Indicates that a view can be transposed.
+ */
+public interface Transposable {
+
+ RotationMode getRotationMode();
+}
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 3686493..75ff66e 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -99,7 +99,8 @@
</activity>
<activity
android:name="com.android.launcher3.testcomponent.BaseTestingActivity"
- android:label="LauncherTestApp">
+ android:label="LauncherTestApp"
+ android:taskAffinity="com.android.launcher3.testcomponent.Affinity1">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
@@ -111,5 +112,77 @@
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
</activity>
+ <activity-alias android:name="Activity2"
+ android:label="TestActivity2"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity3"
+ android:label="TestActivity3"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity4"
+ android:label="TestActivity4"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity5"
+ android:label="TestActivity5"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity6"
+ android:label="TestActivity6"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity7"
+ android:label="TestActivity7"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity8"
+ android:label="TestActivity8"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity9"
+ android:label="TestActivity9"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
+ <activity-alias android:name="Activity10"
+ android:label="TestActivity10"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity-alias>
</application>
</manifest>
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity1.java b/tests/src/com/android/launcher3/testcomponent/MainActivity1.java
deleted file mode 100644
index 7ef0ab6..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity1.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity1 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity10.java b/tests/src/com/android/launcher3/testcomponent/MainActivity10.java
deleted file mode 100644
index 11df0d2..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity10.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity10 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity2.java b/tests/src/com/android/launcher3/testcomponent/MainActivity2.java
deleted file mode 100644
index dfbba3e..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity2.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity2 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity3.java b/tests/src/com/android/launcher3/testcomponent/MainActivity3.java
deleted file mode 100644
index 87d77d9..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity3.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity3 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity4.java b/tests/src/com/android/launcher3/testcomponent/MainActivity4.java
deleted file mode 100644
index dabd2c5..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity4.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity4 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity5.java b/tests/src/com/android/launcher3/testcomponent/MainActivity5.java
deleted file mode 100644
index e58210c..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity5.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity5 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity6.java b/tests/src/com/android/launcher3/testcomponent/MainActivity6.java
deleted file mode 100644
index 005d248..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity6.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity6 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity7.java b/tests/src/com/android/launcher3/testcomponent/MainActivity7.java
deleted file mode 100644
index 0f21549..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity7.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity7 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity8.java b/tests/src/com/android/launcher3/testcomponent/MainActivity8.java
deleted file mode 100644
index 5ba5c55..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity8.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity8 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/MainActivity9.java b/tests/src/com/android/launcher3/testcomponent/MainActivity9.java
deleted file mode 100644
index 82b1fcd..0000000
--- a/tests/src/com/android/launcher3/testcomponent/MainActivity9.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.testcomponent;
-
-import android.app.Activity;
-
-/**
- * Base activity with utility methods to help automate testing.
- */
-public class MainActivity9 extends Activity {
-}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index dedc6b3..43bdb9f 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -17,6 +17,7 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
+import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_GESTURAL_OVERLAY;
@@ -28,6 +29,7 @@
import android.app.Instrumentation;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -426,6 +428,22 @@
mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), LONG_WAIT_TIME_MS));
}
+ protected void startTestActivity(int activityNumber) {
+ final String packageName = getAppPackageName();
+ final Instrumentation instrumentation = getInstrumentation();
+ final Intent intent = instrumentation.getContext().getPackageManager().
+ getLaunchIntentForPackage(packageName);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setComponent(new ComponentName(packageName,
+ "com.android.launcher3.tests.Activity" + activityNumber));
+ instrumentation.getTargetContext().startActivity(intent);
+ assertTrue(packageName + " didn't start",
+ mDevice.wait(
+ Until.hasObject(By.pkg(packageName).text("TestActivity" + activityNumber)),
+ LONG_WAIT_TIME_MS));
+ }
+
protected static String resolveSystemApp(String category) {
return getInstrumentation().getContext().getPackageManager().resolveActivity(
new Intent(Intent.ACTION_MAIN).addCategory(category),
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 2a69757..581e886 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -33,7 +33,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.TestProtocol;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.AppIcon;
@@ -323,24 +322,19 @@
@Test
@PortraitLandscape
public void testDragAppIcon() throws Throwable {
- try {
- TestProtocol.sDebugTracing = true;
- // 1. Open all apps and wait for load complete.
- // 2. Drag icon to homescreen.
- // 3. Verify that the icon works on homescreen.
- mLauncher.getWorkspace().
- switchToAllApps().
- getAppIcon(APP_NAME).
- dragToWorkspace().
- getWorkspaceAppIcon(APP_NAME).
- launch(getAppPackageName());
- executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the "
- + "top one",
- isInBackground(launcher)));
- } finally {
- TestProtocol.sDebugTracing = false;
- }
+ // 1. Open all apps and wait for load complete.
+ // 2. Drag icon to homescreen.
+ // 3. Verify that the icon works on homescreen.
+ mLauncher.getWorkspace().
+ switchToAllApps().
+ getAppIcon(APP_NAME).
+ dragToWorkspace().
+ getWorkspaceAppIcon(APP_NAME).
+ launch(getAppPackageName());
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top "
+ + "one",
+ isInBackground(launcher)));
}
@Test
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 85e112a..9a47aef 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -143,7 +143,6 @@
static void dragIconToWorkspace(
LauncherInstrumentation launcher, Launchable launchable, Point dest,
String longPressIndicator) {
- launcher.getTestInfo(TestProtocol.REQUEST_ENABLE_DRAG_LOGGING);
LauncherInstrumentation.log("dragIconToWorkspace: begin");
final Point launchableCenter = launchable.getObject().getVisibleCenter();
final long downTime = SystemClock.uptimeMillis();
@@ -157,7 +156,6 @@
downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest);
LauncherInstrumentation.log("dragIconToWorkspace: end");
launcher.waitUntilGone("drop_target_bar");
- launcher.getTestInfo(TestProtocol.REQUEST_DISABLE_DRAG_LOGGING);
}
/**