Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-dev
diff --git a/go/quickstep/res/values-bn/strings.xml b/go/quickstep/res/values-bn/strings.xml
index 6067191..8c27e63 100644
--- a/go/quickstep/res/values-bn/strings.xml
+++ b/go/quickstep/res/values-bn/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"অ্যাপ শেয়ার করুন"</string>
<string name="action_listen" msgid="2370304050784689486">"শুনুন"</string>
<string name="action_translate" msgid="8028378961867277746">"অনুবাদ করুন"</string>
- <string name="action_search" msgid="6269564710943755464">"লেন্স"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"বুঝেছি"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"বাতিল করুন"</string>
<string name="dialog_settings" msgid="6564397136021186148">"সেটিংস"</string>
diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml
index faa66fc..80d9e2e 100644
--- a/go/quickstep/res/values-gu/strings.xml
+++ b/go/quickstep/res/values-gu/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"ઍપ શેર કરો"</string>
<string name="action_listen" msgid="2370304050784689486">"સાંભળો"</string>
<string name="action_translate" msgid="8028378961867277746">"અનુવાદ કરો"</string>
- <string name="action_search" msgid="6269564710943755464">"લેન્સ"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"સમજાઈ ગયું"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"રદ કરો"</string>
<string name="dialog_settings" msgid="6564397136021186148">"સેટિંગ"</string>
diff --git a/go/quickstep/res/values-kk/strings.xml b/go/quickstep/res/values-kk/strings.xml
index 2361cbb..2a2f96d 100644
--- a/go/quickstep/res/values-kk/strings.xml
+++ b/go/quickstep/res/values-kk/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"Қолданбаны бөлісу"</string>
<string name="action_listen" msgid="2370304050784689486">"Тыңдау"</string>
<string name="action_translate" msgid="8028378961867277746">"Аудару"</string>
- <string name="action_search" msgid="6269564710943755464">"Объектив"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"ТҮСІНІКТІ"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"БАС ТАРТУ"</string>
<string name="dialog_settings" msgid="6564397136021186148">"ПАРАМЕТРЛЕР"</string>
diff --git a/go/quickstep/res/values-ml/strings.xml b/go/quickstep/res/values-ml/strings.xml
index 19d0b75..ed57395 100644
--- a/go/quickstep/res/values-ml/strings.xml
+++ b/go/quickstep/res/values-ml/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"ആപ്പ് പങ്കിടുക"</string>
<string name="action_listen" msgid="2370304050784689486">"കേൾക്കുക"</string>
<string name="action_translate" msgid="8028378961867277746">"വിവർത്തനം ചെയ്യുക"</string>
- <string name="action_search" msgid="6269564710943755464">"ലെൻസ്"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"മനസ്സിലായി"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"റദ്ദാക്കുക"</string>
<string name="dialog_settings" msgid="6564397136021186148">"ക്രമീകരണം"</string>
diff --git a/go/quickstep/res/values-mn/strings.xml b/go/quickstep/res/values-mn/strings.xml
index 2eb3c98..d03b2d2 100644
--- a/go/quickstep/res/values-mn/strings.xml
+++ b/go/quickstep/res/values-mn/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"Аппыг хуваалцах"</string>
<string name="action_listen" msgid="2370304050784689486">"Сонсох"</string>
<string name="action_translate" msgid="8028378961867277746">"Орчуулах"</string>
- <string name="action_search" msgid="6269564710943755464">"Дуран"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"ОЙЛГОЛОО"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"ЦУЦЛАХ"</string>
<string name="dialog_settings" msgid="6564397136021186148">"ТОХИРГОО"</string>
diff --git a/go/quickstep/res/values-ms/strings.xml b/go/quickstep/res/values-ms/strings.xml
index 36e1678..3b0a7fb 100644
--- a/go/quickstep/res/values-ms/strings.xml
+++ b/go/quickstep/res/values-ms/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"Kongsi Apl"</string>
<string name="action_listen" msgid="2370304050784689486">"Dengar"</string>
<string name="action_translate" msgid="8028378961867277746">"Terjemah"</string>
- <string name="action_search" msgid="6269564710943755464">"Kanta"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"BATAL"</string>
<string name="dialog_settings" msgid="6564397136021186148">"TETAPAN"</string>
diff --git a/go/quickstep/res/values-ta/strings.xml b/go/quickstep/res/values-ta/strings.xml
index 9d04e9a..cd97aa3 100644
--- a/go/quickstep/res/values-ta/strings.xml
+++ b/go/quickstep/res/values-ta/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"ஆப்ஸைப் பகிருங்கள்"</string>
<string name="action_listen" msgid="2370304050784689486">"கேளுங்கள்"</string>
<string name="action_translate" msgid="8028378961867277746">"மொழிபெயர்"</string>
- <string name="action_search" msgid="6269564710943755464">"லென்ஸ்"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"சரி"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"ரத்துசெய்"</string>
<string name="dialog_settings" msgid="6564397136021186148">"அமைப்புகள்"</string>
diff --git a/go/quickstep/res/values-zu/strings.xml b/go/quickstep/res/values-zu/strings.xml
index d496b64..1be7898 100644
--- a/go/quickstep/res/values-zu/strings.xml
+++ b/go/quickstep/res/values-zu/strings.xml
@@ -4,7 +4,7 @@
<string name="app_share_drop_target_label" msgid="5804774105974539508">"Yabelana nge-App"</string>
<string name="action_listen" msgid="2370304050784689486">"Lalela"</string>
<string name="action_translate" msgid="8028378961867277746">"Humusha"</string>
- <string name="action_search" msgid="6269564710943755464">"Ilensi"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
<string name="dialog_acknowledge" msgid="2804025517675853172">"NGIYITHOLILE"</string>
<string name="dialog_cancel" msgid="6464336969134856366">"KHANSELA"</string>
<string name="dialog_settings" msgid="6564397136021186148">"AMASETHINGI"</string>
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 4597422..32ebbe8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_OPEN_DURATION;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.appprediction.AppsDividerView;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.taskbar.TaskbarStashController;
@@ -83,6 +84,8 @@
mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true);
mTaskbarStashController.applyState(DEFAULT_OPEN_DURATION);
mSlideInView.setOnCloseBeginListener(() -> {
+ AbstractFloatingView.closeOpenContainer(
+ mContext, AbstractFloatingView.TYPE_ACTION_POPUP);
mTaskbarStashController.updateStateForFlag(
FLAG_STASHED_IN_APP_ALL_APPS, false);
mTaskbarStashController.applyState(DEFAULT_CLOSE_DURATION);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
index 7836ece..3785de4 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
@@ -48,7 +48,7 @@
super(delegate, inputMonitor);
mTaskbarActivityContext = taskbarActivityContext;
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
- mScreenWidth = context.getResources().getDisplayMetrics().widthPixels;
+ mScreenWidth = taskbarActivityContext.getDeviceProfile().widthPx;
mUnstashArea = context.getResources()
.getDimensionPixelSize(R.dimen.taskbar_unstash_input_area);
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
index b797f0c..b3f2354 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
@@ -15,13 +15,21 @@
*/
package com.android.quickstep.interaction;
+import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.View;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the Home gesture interactive tutorial. */
public class AssistantGestureTutorialFragment extends TutorialFragment {
+
+ protected AssistantGestureTutorialFragment(
+ SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ super(sharedPrefs, statsLogManager);
+ }
+
@Override
TutorialController createController(TutorialType type) {
return new AssistantGestureTutorialController(this, type);
@@ -39,4 +47,14 @@
}
return super.onTouch(view, motionEvent);
}
+
+ @Override
+ void logTutorialStepShown() {
+ // No-Op: tutorial step not currently shown to users
+ }
+
+ @Override
+ void logTutorialStepCompleted() {
+ // No-Op: tutorial step not currently shown to users
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index f54734d..e7ed0b4 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -19,12 +19,14 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.ArrayList;
@@ -32,6 +34,11 @@
/** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment {
+ protected BackGestureTutorialFragment(
+ SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ super(sharedPrefs, statsLogManager);
+ }
+
@Nullable
@Override
Integer getEdgeAnimationResId() {
@@ -117,4 +124,16 @@
}
return super.onTouch(view, motionEvent);
}
+
+ @Override
+ void logTutorialStepShown() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_SHOWN);
+ }
+
+ @Override
+ void logTutorialStepCompleted() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_COMPLETED);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index c2524b1..002e8b7 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.interaction;
+import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
@@ -28,6 +29,8 @@
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.List;
@@ -46,17 +49,26 @@
private int mCurrentStep;
private int mNumSteps;
+ private SharedPreferences mSharedPrefs;
+ private StatsLogManager mStatsLogManager;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gesture_tutorial_activity);
+ mSharedPrefs = Utilities.getPrefs(this);
+ mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
+
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
mTutorialSteps = getTutorialSteps(args);
mCurrentTutorialStep = mTutorialSteps[mCurrentStep - 1];
mFragment = TutorialFragment.newInstance(
- mCurrentTutorialStep, args.getBoolean(KEY_GESTURE_COMPLETE, false));
+ mCurrentTutorialStep,
+ args.getBoolean(KEY_GESTURE_COMPLETE, false),
+ mSharedPrefs,
+ mStatsLogManager);
getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit();
@@ -105,13 +117,6 @@
}
/**
- * Closes the tutorial and this activity.
- */
- public void closeTutorial() {
- mFragment.closeTutorial();
- }
-
- /**
* Replaces the current TutorialFragment, continuing to the next tutorial step if there is one.
*
* If there is no following step, the tutorial is closed.
@@ -122,7 +127,8 @@
return;
}
mCurrentTutorialStep = mTutorialSteps[mCurrentStep];
- mFragment = TutorialFragment.newInstance(mCurrentTutorialStep, false);
+ mFragment = TutorialFragment.newInstance(
+ mCurrentTutorialStep, /* gestureComplete= */ false, mSharedPrefs, mStatsLogManager);
getSupportFragmentManager().beginTransaction()
.replace(R.id.gesture_tutorial_fragment_container, mFragment)
.runOnCommit(() -> mFragment.onAttachedToWindow())
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 423e66f..e987d5a 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -18,12 +18,14 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.ArrayList;
@@ -31,6 +33,11 @@
/** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment {
+ protected HomeGestureTutorialFragment(
+ SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ super(sharedPrefs, statsLogManager);
+ }
+
@Nullable
@Override
Integer getEdgeAnimationResId() {
@@ -99,4 +106,16 @@
releaseFeedbackAnimation();
return super.onTouch(view, motionEvent);
}
+
+ @Override
+ void logTutorialStepShown() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_SHOWN);
+ }
+
+ @Override
+ void logTutorialStepCompleted() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_COMPLETED);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index f63a945..c7e24db 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -18,12 +18,14 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
import java.util.ArrayList;
@@ -31,6 +33,11 @@
/** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment {
+ protected OverviewGestureTutorialFragment(
+ SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ super(sharedPrefs, statsLogManager);
+ }
+
@Nullable
@Override
Integer getEdgeAnimationResId() {
@@ -111,4 +118,16 @@
releaseFeedbackAnimation();
return super.onTouch(view, motionEvent);
}
+
+ @Override
+ void logTutorialStepShown() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_SHOWN);
+ }
+
+ @Override
+ void logTutorialStepCompleted() {
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_COMPLETED);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
index 955a2f7..92a2731 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
@@ -15,14 +15,21 @@
*/
package com.android.quickstep.interaction;
+import android.content.SharedPreferences;
import android.view.MotionEvent;
import android.view.View;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the general navigation gesture sandbox environment. */
public class SandboxModeTutorialFragment extends TutorialFragment {
+ protected SandboxModeTutorialFragment(
+ SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ super(sharedPrefs, statsLogManager);
+ }
+
@Override
TutorialController createController(TutorialType type) {
return new SandboxModeTutorialController(this, type);
@@ -40,4 +47,14 @@
}
return super.onTouch(view, motionEvent);
}
+
+ @Override
+ void logTutorialStepShown() {
+ // No-Op: tutorial step not currently shown to users
+ }
+
+ @Override
+ void logTutorialStepCompleted() {
+ // No-Op: tutorial step not currently shown to users
+ }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 3c88988..6a8894e 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -81,7 +81,8 @@
TutorialType mTutorialType;
final Context mContext;
- final TextView mCloseButton;
+ final TextView mSkipButton;
+ final Button mDoneButton;
final ViewGroup mFeedbackView;
final TextView mFeedbackTitleView;
final ImageView mEdgeGestureVideoView;
@@ -94,7 +95,6 @@
final AnimatedTaskView mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
- final Button mActionButton;
final TutorialStepIndicator mTutorialStepView;
final ImageView mFingerDotView;
private final AlertDialog mSkipTutorialDialog;
@@ -115,8 +115,8 @@
mContext = mTutorialFragment.getContext();
RootSandboxLayout rootView = tutorialFragment.getRootView();
- mCloseButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
- mCloseButton.setOnClickListener(button -> showSkipTutorialDialog());
+ mSkipButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
+ mSkipButton.setOnClickListener(button -> showSkipTutorialDialog());
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
mFeedbackTitleView = mFeedbackView.findViewById(
R.id.gesture_tutorial_fragment_feedback_title);
@@ -130,7 +130,7 @@
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
- mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
+ mDoneButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
mTutorialStepView =
rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
@@ -431,22 +431,22 @@
}
void updateCloseButton() {
- mCloseButton.setTextAppearance(Utilities.isDarkTheme(mContext)
+ mSkipButton.setTextAppearance(Utilities.isDarkTheme(mContext)
? R.style.TextAppearance_GestureTutorial_Feedback_Subtext
: R.style.TextAppearance_GestureTutorial_Feedback_Subtext_Dark);
}
void hideActionButton() {
- mCloseButton.setVisibility(View.VISIBLE);
+ mSkipButton.setVisibility(View.VISIBLE);
// Invisible to maintain the layout.
- mActionButton.setVisibility(View.INVISIBLE);
- mActionButton.setOnClickListener(null);
+ mDoneButton.setVisibility(View.INVISIBLE);
+ mDoneButton.setOnClickListener(null);
}
void showActionButton() {
- mCloseButton.setVisibility(GONE);
- mActionButton.setVisibility(View.VISIBLE);
- mActionButton.setOnClickListener(this::onActionButtonClicked);
+ mSkipButton.setVisibility(GONE);
+ mDoneButton.setVisibility(View.VISIBLE);
+ mDoneButton.setOnClickListener(this::onActionButtonClicked);
}
void hideFakeTaskbar(boolean animateToHotseat) {
@@ -609,7 +609,7 @@
R.id.gesture_tutorial_dialog_confirm_button);
if (confirmButton != null) {
confirmButton.setOnClickListener(v -> {
- sandboxActivity.closeTutorial();
+ mTutorialFragment.closeTutorial(true);
tutorialDialog.dismiss();
});
} else {
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 4b836e3..d79b946 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -20,11 +20,13 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.graphics.Insets;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -43,14 +45,24 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
+import java.util.Set;
+
abstract class TutorialFragment extends Fragment implements OnTouchListener {
private static final String LOG_TAG = "TutorialFragment";
static final String KEY_TUTORIAL_TYPE = "tutorial_type";
static final String KEY_GESTURE_COMPLETE = "gesture_complete";
+ private static final String TUTORIAL_SKIPPED_PREFERENCE_KEY = "pref_gestureTutorialSkipped";
+ private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY =
+ "pref_completedTutorialSteps";
+
+ private final SharedPreferences mSharedPrefs;
+ protected final StatsLogManager mStatsLogManager;
+
TutorialType mTutorialType;
boolean mGestureComplete = false;
@Nullable TutorialController mTutorialController = null;
@@ -71,10 +83,15 @@
private boolean mIsLargeScreen;
private boolean mIsFoldable;
- public static TutorialFragment newInstance(TutorialType tutorialType, boolean gestureComplete) {
- TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
+ public static TutorialFragment newInstance(
+ TutorialType tutorialType,
+ boolean gestureComplete,
+ SharedPreferences sharedPrefs,
+ StatsLogManager statsLogManager) {
+ TutorialFragment fragment =
+ getFragmentForTutorialType(tutorialType, sharedPrefs, statsLogManager);
if (fragment == null) {
- fragment = new BackGestureTutorialFragment();
+ fragment = new BackGestureTutorialFragment(sharedPrefs, statsLogManager);
tutorialType = TutorialType.BACK_NAVIGATION;
}
@@ -86,28 +103,36 @@
}
@Nullable
- private static TutorialFragment getFragmentForTutorialType(TutorialType tutorialType) {
+ private static TutorialFragment getFragmentForTutorialType(
+ TutorialType tutorialType,
+ SharedPreferences sharedPrefs,
+ StatsLogManager statsLogManager) {
switch (tutorialType) {
case BACK_NAVIGATION:
case BACK_NAVIGATION_COMPLETE:
- return new BackGestureTutorialFragment();
+ return new BackGestureTutorialFragment(sharedPrefs, statsLogManager);
case HOME_NAVIGATION:
case HOME_NAVIGATION_COMPLETE:
- return new HomeGestureTutorialFragment();
+ return new HomeGestureTutorialFragment(sharedPrefs, statsLogManager);
case OVERVIEW_NAVIGATION:
case OVERVIEW_NAVIGATION_COMPLETE:
- return new OverviewGestureTutorialFragment();
+ return new OverviewGestureTutorialFragment(sharedPrefs, statsLogManager);
case ASSISTANT:
case ASSISTANT_COMPLETE:
- return new AssistantGestureTutorialFragment();
+ return new AssistantGestureTutorialFragment(sharedPrefs, statsLogManager);
case SANDBOX_MODE:
- return new SandboxModeTutorialFragment();
+ return new SandboxModeTutorialFragment(sharedPrefs, statsLogManager);
default:
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
}
return null;
}
+ protected TutorialFragment(SharedPreferences sharedPrefs, StatsLogManager statsLogManager) {
+ mSharedPrefs = sharedPrefs;
+ mStatsLogManager = statsLogManager;
+ }
+
@Nullable Integer getEdgeAnimationResId() {
return null;
}
@@ -315,6 +340,7 @@
}
void onAttachedToWindow() {
+ logTutorialStepShown();
mEdgeBackGestureHandler.setViewGroupParent(getRootView());
}
@@ -348,8 +374,16 @@
}
void continueTutorial() {
- GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
+ Set<String> updatedCompletedSteps = new ArraySet<>(mSharedPrefs.getStringSet(
+ COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY, new ArraySet<>()));
+ updatedCompletedSteps.add(mTutorialType.toString());
+
+ mSharedPrefs.edit().putStringSet(
+ COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY, updatedCompletedSteps).apply();
+ logTutorialStepCompleted();
+
+ GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
if (gestureSandboxActivity == null) {
closeTutorial();
return;
@@ -358,6 +392,15 @@
}
void closeTutorial() {
+ closeTutorial(false);
+ }
+
+ void closeTutorial(boolean tutorialSkipped) {
+ if (tutorialSkipped) {
+ mSharedPrefs.edit().putBoolean(TUTORIAL_SKIPPED_PREFERENCE_KEY, true).apply();
+ mStatsLogManager.logger().log(
+ StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED);
+ }
FragmentActivity activity = getActivity();
if (activity != null) {
activity.setResult(Activity.RESULT_OK);
@@ -390,6 +433,10 @@
|| (mTutorialController != null && mTutorialController.isGestureCompleted());
}
+ abstract void logTutorialStepShown();
+
+ abstract void logTutorialStepCompleted();
+
@Nullable
private GestureSandboxActivity getGestureSandboxActivity() {
Context context = getContext();
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 21e3ea0..f3ad0f6 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
+import android.annotation.NonNull;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.PendingIntent;
@@ -163,7 +164,8 @@
: new int[]{taskId2, taskId1};
if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
RemoteSplitLaunchTransitionRunner animationRunner =
- new RemoteSplitLaunchTransitionRunner(taskId1, taskPendingIntent, taskId2);
+ new RemoteSplitLaunchTransitionRunner(taskId1, taskPendingIntent, taskId2,
+ callback);
mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio,
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR,
@@ -210,19 +212,26 @@
private final int mInitialTaskId;
private final PendingIntent mInitialTaskPendingIntent;
private final int mSecondTaskId;
+ private final Consumer<Boolean> mSuccessCallback;
RemoteSplitLaunchTransitionRunner(int initialTaskId, PendingIntent initialTaskPendingIntent,
- int secondTaskId) {
+ int secondTaskId, Consumer<Boolean> callback) {
mInitialTaskId = initialTaskId;
mInitialTaskPendingIntent = initialTaskPendingIntent;
mSecondTaskId = secondTaskId;
+ mSuccessCallback = callback;
}
@Override
- public void startAnimation(IBinder transition, TransitionInfo info,
- SurfaceControl.Transaction t, Runnable finishCallback) {
+ public void startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskId,
- mInitialTaskPendingIntent, mSecondTaskId, info, t, finishCallback);
+ mInitialTaskPendingIntent, mSecondTaskId, info, t, () -> {
+ finishCallback.run();
+ if (mSuccessCallback != null) {
+ mSuccessCallback.accept(true);
+ }
+ });
// After successful launch, call resetState
resetState();
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 6bb20fc..a6b8897 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3872,9 +3872,10 @@
float taskSplitScrollOffsetPrimary = 0f;
float clearAllSplitScrollOffsetPrimar = 0f;
if (isSplitPlaceholderFirstInGrid()) {
- taskSplitScrollOffsetPrimary = mSplitPlaceholderSize;
+ taskSplitScrollOffsetPrimary = mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
} else if (isSplitPlaceholderLastInGrid()) {
- clearAllSplitScrollOffsetPrimar = -mSplitPlaceholderSize;
+ clearAllSplitScrollOffsetPrimar =
+ mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
}
for (int i = 0; i < getTaskViewCount(); i++) {
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index a9e0fb8..9821526 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -15,6 +15,9 @@
-->
<resources>
-<!-- AllApps -->
- <dimen name="all_apps_top_padding">0dp</dimen>
+ <!-- Widget picker-->
+ <dimen name="widget_list_horizontal_margin">49dp</dimen>
+
+ <!-- Bottom sheet-->
+ <dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 5c314d5..7ebc3f8 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -16,6 +16,11 @@
<resources>
<!-- AllApps -->
- <dimen name="all_apps_top_padding">300dp</dimen>
<dimen name="all_apps_bottom_sheet_horizontal_padding">65dp</dimen>
+
+<!-- Widget picker-->
+ <dimen name="widget_list_horizontal_margin">30dp</dimen>
+
+<!-- Bottom sheet-->
+ <dimen name="bottom_sheet_extra_top_padding">300dp</dimen>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2b599bc..338e218 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -94,7 +94,6 @@
<!-- All Apps -->
<dimen name="all_apps_starting_vertical_translate">320dp</dimen>
- <dimen name="all_apps_top_padding">0dp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
<!-- all_apps_search_bar_field_height / 2 -->
<dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
@@ -368,6 +367,7 @@
<dimen name="padded_rounded_button_padding">8dp</dimen>
<!-- Bottom sheet related parameters -->
+ <dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
<dimen name="bottom_sheet_handle_width">32dp</dimen>
<dimen name="bottom_sheet_handle_height">4dp</dimen>
<dimen name="bottom_sheet_handle_margin">16dp</dimen>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index ceb38d0..e75348c 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -103,7 +103,7 @@
public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG
- | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS;
+ | TYPE_TASKBAR_EDUCATION_DIALOG;
// Usually we show the back button when a floating view is open. Instead, hide for these types.
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 42f7053..73d3e33 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -25,12 +24,7 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
-import android.content.pm.LauncherApps;
import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.util.Log;
import androidx.annotation.IntDef;
@@ -39,7 +33,7 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.AppLauncher;
import com.android.launcher3.views.ScrimView;
import java.io.PrintWriter;
@@ -50,7 +44,7 @@
/**
* Launcher BaseActivity
*/
-public abstract class BaseActivity extends Activity implements ActivityContext,
+public abstract class BaseActivity extends Activity implements AppLauncher,
DeviceProfileListenable {
private static final String TAG = "BaseActivity";
@@ -314,22 +308,6 @@
writer.println(prefix + "mForceInvisible: " + mForceInvisible);
}
- /**
- * A wrapper around the platform method with Launcher specific checks
- */
- public void startShortcut(String packageName, String id, Rect sourceBounds,
- Bundle startActivityOptions, UserHandle user) {
- if (GO_DISABLE_WIDGETS) {
- return;
- }
- try {
- getSystemService(LauncherApps.class).startShortcut(packageName, id, sourceBounds,
- startActivityOptions, user);
- } catch (SecurityException | IllegalStateException e) {
- Log.e(TAG, "Failed to start shortcut", e);
- }
- }
-
public static <T extends BaseActivity> T fromContext(Context context) {
if (context instanceof BaseActivity) {
return (T) context;
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index f53d01e..3af43c0 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -16,50 +16,33 @@
package com.android.launcher3;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import android.app.ActivityOptions;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.app.WallpaperManager.OnColorsChangedListener;
-import android.content.ActivityNotFoundException;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.os.Process;
-import android.os.StrictMode;
-import android.os.UserHandle;
-import android.util.Log;
import android.view.ActionMode;
import android.view.Display;
import android.view.View;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.InstanceIdSequence;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
@@ -162,112 +145,12 @@
// no-op
}
+ @Override
@NonNull
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- int left = 0, top = 0;
- int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof BubbleTextView) {
- // Launch from center of icon, not entire view
- Drawable icon = ((BubbleTextView) v).getIcon();
- if (icon != null) {
- Rect bounds = icon.getBounds();
- left = (width - bounds.width()) / 2;
- top = v.getPaddingTop();
- width = bounds.width();
- height = bounds.height();
- }
- }
- ActivityOptions options =
- ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
-
- options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
- RunnableList callback = new RunnableList();
- addOnResumeCallback(callback::executeAllAndDestroy);
- return new ActivityOptionsWrapper(options, callback);
- }
-
- public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
- if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
- Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
- return false;
- }
-
- Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
- UserHandle user = item == null ? null : item.user;
-
- // Prepare intent
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (v != null) {
- intent.setSourceBounds(Utilities.getViewBounds(v));
- }
- try {
- boolean isShortcut = (item instanceof WorkspaceItemInfo)
- && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
- || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
- && !((WorkspaceItemInfo) item).isPromise();
- if (isShortcut) {
- // Shortcuts need some special checks due to legacy reasons.
- startShortcutIntentSafely(intent, optsBundle, item);
- } else if (user == null || user.equals(Process.myUserHandle())) {
- // Could be launching some bookkeeping activity
- startActivity(intent, optsBundle);
- } else {
- getSystemService(LauncherApps.class).startMainActivity(
- intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
- }
- if (item != null) {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- logAppLaunch(getStatsLogManager(), item, instanceId);
- }
- return true;
- } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
- Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
- }
- return false;
- }
-
- /**
- * Creates and logs a new app launch event.
- */
- public void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
- InstanceId instanceId) {
- statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
- .log(LAUNCHER_APP_LAUNCH_TAP);
- }
-
- private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
- try {
- StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
- try {
- // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
- // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
- // is enabled by default on NYC.
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
- .penaltyLog().build());
-
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
- String packageName = intent.getPackage();
- startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
- } else {
- // Could be launching some bookkeeping activity
- startActivity(intent, optsBundle);
- }
- } finally {
- StrictMode.setVmPolicy(oldPolicy);
- }
- } catch (SecurityException e) {
- if (!onErrorStartingShortcut(intent, info)) {
- throw e;
- }
- }
- }
-
- protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
- return false;
+ ActivityOptionsWrapper wrapper = super.getActivityLaunchOptions(v, item);
+ addOnResumeCallback(wrapper.onEndCallback::executeAllAndDestroy);
+ return wrapper;
}
@Override
@@ -337,4 +220,9 @@
ActivityAllAppsContainerView<?> allApps) {
return new DefaultSearchAdapterProvider(this);
}
+
+ @Override
+ public boolean isAppBlockedForSafeMode() {
+ return mIsSafeModeEnabled;
+ }
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 041bee9..3bc0f6d 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -867,6 +867,11 @@
}
protected void applyCompoundDrawables(Drawable icon) {
+ if (icon == null) {
+ // Icon can be null when we use the BubbleTextView for text only.
+ return;
+ }
+
// If we had already set an icon before, disable relayout as the icon size is the
// same as before.
mDisableRelayout = mIcon != null;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 39020bd..0e9b5da 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -175,6 +175,7 @@
public Point allAppsBorderSpacePx;
public int allAppsShiftRange;
public int allAppsTopPadding;
+ public int bottomSheetTopPadding;
public int allAppsCellHeightPx;
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
@@ -256,7 +257,8 @@
// Some more constants.
context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
? Configuration.ORIENTATION_LANDSCAPE
- : Configuration.ORIENTATION_PORTRAIT);
+ : Configuration.ORIENTATION_PORTRAIT,
+ windowBounds);
final Resources res = context.getResources();
mMetrics = res.getDisplayMetrics();
@@ -294,8 +296,11 @@
desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
- allAppsTopPadding = res.getDimensionPixelSize(R.dimen.all_apps_top_padding)
- + (isTablet ? heightPx - availableHeightPx : 0);
+ bottomSheetTopPadding = windowBounds.insets.top // statusbar height
+ + res.getDimensionPixelSize(R.dimen.bottom_sheet_extra_top_padding)
+ + (isTablet ? 0 : edgeMarginPx); // phones need edgeMarginPx additional padding
+
+ allAppsTopPadding = isTablet ? bottomSheetTopPadding : 0;
allAppsShiftRange = isTablet
? heightPx - allAppsTopPadding
: res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
@@ -1227,10 +1232,11 @@
writer.println(prefix + pxToDpStr("overviewGridSideMargin", overviewGridSideMargin));
}
- private static Context getContext(Context c, Info info, int orientation) {
+ private static Context getContext(Context c, Info info, int orientation, WindowBounds bounds) {
Configuration config = new Configuration(c.getResources().getConfiguration());
config.orientation = orientation;
config.densityDpi = info.densityDpi;
+ config.smallestScreenWidthDp = (int) info.smallestSizeDp(bounds);
return c.createConfigurationContext(config);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5c406bd..2f9b563 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2065,7 +2065,7 @@
@TargetApi(Build.VERSION_CODES.M)
@Override
- protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
+ public boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
// Due to legacy reasons, direct call shortcuts require Launchers to have the
// corresponding permission. Show the appropriate permission prompt if that
// is the case.
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 3e0c9fc..de33ae5 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -89,20 +89,10 @@
public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag(
"ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps");
- public static final BooleanFlag ENABLE_ONE_SEARCH = new DeviceFlag("ENABLE_ONE_SEARCH", false,
- "Use homescreen search box to complete allApps searches");
-
public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
getDebugFlag("ENABLE_FLOATING_SEARCH_BAR", false,
"Keep All Apps search bar at the bottom (but above keyboard if open)");
- public static final BooleanFlag INJECT_WEB_TOP = new DeviceFlag("INJECT_WEB_TOP", false,
- "Show web suggestions on top of the search results");
-
- public static final BooleanFlag USE_FALLBACK_APP_SEARCH = new DeviceFlag(
- "USE_FALLBACK_APP_SEARCH", false,
- "Use fallback launcher app search results instead of AiAi app results");
-
public static final BooleanFlag ENABLE_QUICK_SEARCH = new DeviceFlag("ENABLE_QUICK_SEARCH",
true, "Use quick search behavior.");
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index f392e95..e6dc21e 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -529,6 +529,27 @@
@UiEvent(doc = "User clicks on the search icon on header to launch search in app.")
LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH(913),
+ @UiEvent(doc = "User is shown the back gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_SHOWN(959),
+
+ @UiEvent(doc = "User is shown the home gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_SHOWN(960),
+
+ @UiEvent(doc = "User is shown the overview gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_SHOWN(961),
+
+ @UiEvent(doc = "User completed the back gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_COMPLETED(962),
+
+ @UiEvent(doc = "User completed the home gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_COMPLETED(963),
+
+ @UiEvent(doc = "User completed the overview gesture navigation tutorial step.")
+ LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_COMPLETED(964),
+
+ @UiEvent(doc = "User skips the gesture navigation tutorial.")
+ LAUNCHER_GESTURE_TUTORIAL_SKIPPED(965),
+
@UiEvent(doc = "User scrolled on one of the all apps surfaces such as A-Z list, search "
+ "result page etc.")
LAUNCHER_ALLAPPS_SCROLLED(985);
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index 0369b21..e36d4cf 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -395,7 +395,8 @@
mTrgX = trgX;
mTrgY = trgY;
mNextStartX = 0;
- mNextStartY = mTrgY - 1;
+ mNextStartY = mScreenId == 0 && FeatureFlags.QSB_ON_FIRST_SCREEN
+ ? 1 /* smartspace */ : 0;
List<DbEntry> existedEntries = mDestReader.mWorkspaceEntriesByScreenId.get(screenId);
if (existedEntries != null) {
for (DbEntry entry : existedEntries) {
@@ -430,7 +431,7 @@
* to speed up the search.
*/
private boolean findPlacement(DbEntry entry) {
- for (int y = mNextStartY; y >= (mScreenId == 0 ? 1 /* smartspace */ : 0); y--) {
+ for (int y = mNextStartY; y < mTrgY; y++) {
for (int x = mNextStartX; x < mTrgX; x++) {
boolean fits = mOccupied.isRegionVacant(x, y, entry.spanX, entry.spanY);
boolean minFits = mOccupied.isRegionVacant(x, y, entry.minSpanX,
@@ -753,7 +754,7 @@
return Integer.compare(screenId, another.screenId);
}
if (cellY != another.cellY) {
- return -Integer.compare(cellY, another.cellY);
+ return Integer.compare(cellY, another.cellY);
}
return Integer.compare(cellX, another.cellX);
}
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index ebe45a5..bb2c37f 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -16,6 +16,8 @@
package com.android.launcher3.notification;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP;
+import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_LAUNCH_TAP;
import android.app.ActivityOptions;
@@ -116,7 +118,8 @@
popupDataProvider.cancelNotification(notificationKey);
}
}
- AbstractFloatingView.closeOpenContainer(context, AbstractFloatingView.TYPE_ACTION_POPUP);
+ AbstractFloatingView.closeOpenViews(
+ context, true, TYPE_ACTION_POPUP | TYPE_TASKBAR_ALL_APPS);
}
public Drawable getIconForBackground(Context context, int background) {
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 22e3de8..8b4ff85 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -345,16 +345,21 @@
* Returns {@code true} if the bounds represent a tablet.
*/
public boolean isTablet(WindowBounds bounds) {
- return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
- densityDpi) >= MIN_TABLET_WIDTH;
+ return smallestSizeDp(bounds) >= MIN_TABLET_WIDTH;
}
/**
* Returns {@code true} if the bounds represent a large tablet.
*/
public boolean isLargeTablet(WindowBounds bounds) {
- return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
- densityDpi) >= MIN_LARGE_TABLET_WIDTH;
+ return smallestSizeDp(bounds) >= MIN_LARGE_TABLET_WIDTH;
+ }
+
+ /**
+ * Returns smallest size in dp for given bounds.
+ */
+ public float smallestSizeDp(WindowBounds bounds) {
+ return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()), densityDpi);
}
}
diff --git a/src/com/android/launcher3/views/AppLauncher.java b/src/com/android/launcher3/views/AppLauncher.java
new file mode 100644
index 0000000..19e66ab
--- /dev/null
+++ b/src/com/android/launcher3/views/AppLauncher.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2022 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 static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
+
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.StrictMode;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.util.PackageManagerHelper;
+import com.android.launcher3.util.RunnableList;
+
+/** An {@link ActivityContext} that can also launch app activities and shortcuts safely. */
+public interface AppLauncher extends ActivityContext {
+
+ String TAG = "AppLauncher";
+
+ /**
+ * Safely starts an activity.
+ *
+ * @param v View starting the activity.
+ * @param intent Base intent being launched.
+ * @param item Item associated with the view.
+ * @return {@code true} if the activity starts successfully.
+ */
+ default boolean startActivitySafely(
+ View v, Intent intent, @Nullable ItemInfo item) {
+
+ Context context = (Context) this;
+ if (isAppBlockedForSafeMode() && !PackageManagerHelper.isSystemApp(context, intent)) {
+ Toast.makeText(context, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
+ UserHandle user = item == null ? null : item.user;
+
+ // Prepare intent
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (v != null) {
+ intent.setSourceBounds(Utilities.getViewBounds(v));
+ }
+ try {
+ boolean isShortcut = (item instanceof WorkspaceItemInfo)
+ && (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
+ || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
+ && !((WorkspaceItemInfo) item).isPromise();
+ if (isShortcut) {
+ // Shortcuts need some special checks due to legacy reasons.
+ startShortcutIntentSafely(intent, optsBundle, item);
+ } else if (user == null || user.equals(Process.myUserHandle())) {
+ // Could be launching some bookkeeping activity
+ context.startActivity(intent, optsBundle);
+ } else {
+ context.getSystemService(LauncherApps.class).startMainActivity(
+ intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
+ }
+ if (item != null) {
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ logAppLaunch(getStatsLogManager(), item, instanceId);
+ }
+ return true;
+ } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
+ Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
+ }
+ return false;
+ }
+
+ /** Returns {@code true} if an app launch is blocked due to safe mode. */
+ default boolean isAppBlockedForSafeMode() {
+ return false;
+ }
+
+ /**
+ * Creates and logs a new app launch event.
+ */
+ default void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
+ InstanceId instanceId) {
+ statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
+ .log(LAUNCHER_APP_LAUNCH_TAP);
+ }
+
+ /**
+ * Returns launch options for an Activity.
+ *
+ * @param v View initiating a launch.
+ * @param item Item associated with the view.
+ */
+ default ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
+ int left = 0, top = 0;
+ int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+ if (v instanceof BubbleTextView) {
+ // Launch from center of icon, not entire view
+ Drawable icon = ((BubbleTextView) v).getIcon();
+ if (icon != null) {
+ Rect bounds = icon.getBounds();
+ left = (width - bounds.width()) / 2;
+ top = v.getPaddingTop();
+ width = bounds.width();
+ height = bounds.height();
+ }
+ }
+ ActivityOptions options =
+ ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
+
+ options.setLaunchDisplayId(
+ (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
+ : Display.DEFAULT_DISPLAY);
+ RunnableList callback = new RunnableList();
+ return new ActivityOptionsWrapper(options, callback);
+ }
+
+ /**
+ * Safely launches an intent for a shortcut.
+ *
+ * @param intent Intent to start.
+ * @param optsBundle Optional launch arguments.
+ * @param info Shortcut information.
+ */
+ default void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
+ try {
+ StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
+ try {
+ // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
+ // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
+ // is enabled by default on NYC.
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
+ .penaltyLog().build());
+
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
+ String packageName = intent.getPackage();
+ startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
+ } else {
+ // Could be launching some bookkeeping activity
+ ((Context) this).startActivity(intent, optsBundle);
+ }
+ } finally {
+ StrictMode.setVmPolicy(oldPolicy);
+ }
+ } catch (SecurityException e) {
+ if (!onErrorStartingShortcut(intent, info)) {
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * A wrapper around the platform method with Launcher specific checks.
+ */
+ default void startShortcut(String packageName, String id, Rect sourceBounds,
+ Bundle startActivityOptions, UserHandle user) {
+ if (GO_DISABLE_WIDGETS) {
+ return;
+ }
+ try {
+ ((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id,
+ sourceBounds, startActivityOptions, user);
+ } catch (SecurityException | IllegalStateException e) {
+ Log.e(TAG, "Failed to start shortcut", e);
+ }
+ }
+
+ /**
+ * Invoked when a shortcut fails to launch.
+ * @param intent Shortcut intent that failed to start.
+ * @param info Shortcut information.
+ * @return {@code true} if the error is handled by this callback.
+ */
+ default boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
+ return false;
+ }
+}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 00a0050..b12574f 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -163,9 +163,8 @@
widthUsed = Math.max(widthUsed, minUsedWidth);
}
- int heightUsed = mInsets.top + deviceProfile.edgeMarginPx;
measureChildWithMargins(mContent, widthMeasureSpec,
- widthUsed, heightMeasureSpec, heightUsed);
+ widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 6e97774..341cb5c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -96,8 +96,6 @@
private static final String KEY_WIDGETS_EDUCATION_DIALOG_SEEN =
"launcher.widgets_education_dialog_seen";
- private final Rect mInsets = new Rect();
-
private final UserManagerState mUserManagerState = new UserManagerState();
private final boolean mHasWorkProfile;
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
index 345016b..90d7b43 100644
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
@@ -101,16 +101,21 @@
modelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI)
modelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
// Src grid icons
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage6, 6, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage8, 8, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage9, 9, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage10, 10, TMP_CONTENT_URI)
+ // _ _ _ _ _
+ // _ _ _ _ 5
+ // _ _ 6 _ 7
+ // _ _ 8 _ 9
+ // _ _ _ _ _
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage5, 5, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage6, 6, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage7, 7, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage8, 8, TMP_CONTENT_URI)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage9, 9, TMP_CONTENT_URI)
// Dest hotseat icons
modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2)
// Dest grid icons
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7)
+ modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage10)
idp.numDatabaseHotseatIcons = 4
idp.numColumns = 4
@@ -174,13 +179,18 @@
Point(c.getInt(cellXIndex), c.getInt(cellYIndex))
}
c.close()
+ // Expected dest grid icons
+ // _ _ _ _
+ // 5 6 7 8
+ // 9 _ 10_
+ // _ _ _ _
assertThat(locMap.size.toLong()).isEqualTo(6)
- assertThat(locMap[testPackage8]).isEqualTo(Point(0, 2))
- assertThat(locMap[testPackage6]).isEqualTo(Point(0, 3))
- assertThat(locMap[testPackage10]).isEqualTo(Point(1, 3))
- assertThat(locMap[testPackage7]).isEqualTo(Point(2, 2))
- assertThat(locMap[testPackage5]).isEqualTo(Point(2, 3))
- assertThat(locMap[testPackage9]).isEqualTo(Point(3, 3))
+ assertThat(locMap[testPackage5]).isEqualTo(Point(0, 1))
+ assertThat(locMap[testPackage6]).isEqualTo(Point(1, 1))
+ assertThat(locMap[testPackage7]).isEqualTo(Point(2, 1))
+ assertThat(locMap[testPackage8]).isEqualTo(Point(3, 1))
+ assertThat(locMap[testPackage9]).isEqualTo(Point(0, 2))
+ assertThat(locMap[testPackage10]).isEqualTo(Point(2, 2))
}
@Test