Merge "Fix class cast exception in a11y service for widget resize action" into sc-dev
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index 350e0d1..67e9d89 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -21,14 +21,18 @@
import android.annotation.SuppressLint;
import android.app.assist.AssistContent;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Matrix;
+import android.net.Uri;
import android.os.SystemClock;
+import android.provider.Settings;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.BuildConfig;
import com.android.launcher3.R;
import com.android.quickstep.util.AssistContentRequester;
import com.android.quickstep.views.OverviewActionsView;
@@ -45,7 +49,13 @@
public static final String ACTION_SEARCH = "com.android.quickstep.ACTION_SEARCH";
public static final String ELAPSED_NANOS = "niu_actions_elapsed_realtime_nanos";
public static final String ACTIONS_URL = "niu_actions_app_url";
+ public static final String ACTIONS_APP_PACKAGE = "niu_actions_app_package";
+ public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code";
+ public static final int ERROR_PERMISSIONS = 1;
private static final String TAG = "TaskOverlayFactoryGo";
+ private static final String URI_AUTHORITY =
+ BuildConfig.APPLICATION_ID + ".overview.fileprovider";
+ private static final String FAKE_FILEPATH = "shared_images/null.png";
// Empty constructor required for ResourceBasedOverride
public TaskOverlayFactoryGo(Context context) {}
@@ -63,7 +73,9 @@
*/
public static final class TaskOverlayGo<T extends OverviewActionsView> extends TaskOverlay {
private String mNIUPackageName;
+ private String mTaskPackageName;
private String mWebUrl;
+ private boolean mAssistPermissionsEnabled;
private TaskOverlayGo(TaskThumbnailView taskThumbnailView) {
super(taskThumbnailView);
@@ -77,7 +89,7 @@
boolean rotated) {
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
mNIUPackageName =
- mApplicationContext.getResources().getString(R.string.niu_actions_package);
+ mApplicationContext.getString(R.string.niu_actions_package);
if (thumbnail == null || TextUtils.isEmpty(mNIUPackageName)) {
return;
@@ -86,6 +98,12 @@
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
+ mTaskPackageName = task.key.getPackageName();
+
+ checkPermissions();
+ if (!mAssistPermissionsEnabled) {
+ return;
+ }
int taskId = task.key.id;
AssistContentRequester contentRequester =
@@ -112,7 +130,22 @@
@VisibleForTesting
public void sendNIUIntent(String actionType) {
Intent intent = createNIUIntent(actionType);
- mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
+ // Only add and send the image if the appropriate permissions are held
+ if (mAssistPermissionsEnabled) {
+ mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
+ } else {
+ intent.putExtra(ACTIONS_ERROR_CODE, ERROR_PERMISSIONS);
+ // The Intent recipient expects an image URI, and omitting one or using a
+ // completely invalid URI will cause the Intent parsing to crash.
+ // So we construct a URI for a nonexistent image.
+ Uri uri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(URI_AUTHORITY)
+ .path(FAKE_FILEPATH)
+ .build();
+ intent.setData(uri);
+ mApplicationContext.startActivity(intent);
+ }
}
private Intent createNIUIntent(String actionType) {
@@ -120,6 +153,7 @@
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
.setPackage(mNIUPackageName)
+ .putExtra(ACTIONS_APP_PACKAGE, mTaskPackageName)
.putExtra(ELAPSED_NANOS, SystemClock.elapsedRealtimeNanos());
if (mWebUrl != null) {
@@ -129,6 +163,19 @@
return intent;
}
+ /**
+ * Checks whether the Assistant has screen context permissions
+ */
+ @VisibleForTesting
+ public void checkPermissions() {
+ ContentResolver contentResolver = mApplicationContext.getContentResolver();
+ boolean structureEnabled = Settings.Secure.getInt(contentResolver,
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 0) != 0;
+ boolean screenshotEnabled = Settings.Secure.getInt(contentResolver,
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 0) != 0;
+ mAssistPermissionsEnabled = structureEnabled && screenshotEnabled;
+ }
+
protected class OverlayUICallbacksGoImpl extends OverlayUICallbacksImpl
implements OverlayUICallbacksGo {
public OverlayUICallbacksGoImpl(boolean isAllowedByPolicy, Task task) {
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index fe81b4c..fb47b0a 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -125,6 +125,22 @@
// Folder's label is empty(i.e., title == "").
// Not eligible for auto-labeling.
EMPTY_LABEL = 12;
+
+ ALL_APPS_SEARCH_RESULT_APPLICATION = 13;
+ ALL_APPS_SEARCH_RESULT_SHORTCUT = 14;
+ ALL_APPS_SEARCH_RESULT_PEOPLE = 15;
+ ALL_APPS_SEARCH_RESULT_ACTION = 16;
+ ALL_APPS_SEARCH_RESULT_SETTING = 17;
+ ALL_APPS_SEARCH_RESULT_SCREENSHOT = 18;
+ ALL_APPS_SEARCH_RESULT_SLICE = 19;
+ ALL_APPS_SEARCH_RESULT_WIDGETS = 20;
+ ALL_APPS_SEARCH_RESULT_PLAY = 21;
+ ALL_APPS_SEARCH_RESULT_SUGGEST = 22;
+ ALL_APPS_SEARCH_RESULT_ASSISTANT = 23;
+ ALL_APPS_SEARCH_RESULT_CHROMETAB = 24;
+ ALL_APPS_SEARCH_RESULT_NAVVYSITE = 25;
+ ALL_APPS_SEARCH_RESULT_TIPS = 26;
+ ALL_APPS_SEARCH_RESULT_PEOPLE_TILE = 27;
}
// Main app icons
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 842abc3..7ab09c5 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -103,16 +103,40 @@
android:clearTaskOnLaunch="true"
android:exported="false"/>
+ <!--
+ Activity for gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
- android:autoRemoveFromRecents="true"
- android:excludeFromRecents="true"
- android:screenOrientation="portrait"
- android:exported="true">
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
<intent-filter>
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+
+ <!--
+ Activity following gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
+ <activity android:name="com.android.quickstep.interaction.AllSetActivity"
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.quickstep.action.GESTURE_ONBOARDING_ALL_SET"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
<activity
android:name=".hybridhotseat.HotseatEduActivity"
android:theme="@android:style/Theme.NoDisplay"
diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml
new file mode 100644
index 0000000..a6852aa
--- /dev/null
+++ b/quickstep/res/drawable/ic_all_set.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="42dp"
+ android:height="40dp"
+ android:viewportWidth="42"
+ android:viewportHeight="40">
+ <path
+ android:pathData="M38,14H25.38L27.28,4.86L27.34,4.22C27.34,3.4 27,2.64 26.46,2.1L24.34,0C24.34,0 10.16,13.7 10,14H0V40H32C33.66,40 35.08,39 35.68,37.56L41.72,23.46C41.9,23 42,22.52 42,22V18C42,15.8 40.2,14 38,14ZM10,36H4V18H10V36ZM38,22L32,36H14V16L22.68,7.32L20,18H38V22Z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml
new file mode 100644
index 0000000..a6a17e5
--- /dev/null
+++ b/quickstep/res/layout/activity_allset.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/allset_page_margin_horizontal"
+ android:paddingEnd="@dimen/allset_page_margin_horizontal"
+ android:layoutDirection="locale"
+ android:textDirection="locale"
+ android:background="?android:attr/colorBackground">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="start"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_icon_margin_top"
+ android:src="@drawable/ic_all_set"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_title"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_subtitle_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_description"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/navigation_settings"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/hint"
+ android:gravity="center_horizontal"
+ android:layout_marginBottom="72dp"/>
+
+ <TextView
+ android:id="@id/hint"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/allset_hint_margin_bottom"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:text="@string/allset_hint"/>
+</RelativeLayout>
diff --git a/quickstep/res/layout/task_menu.xml b/quickstep/res/layout/task_menu.xml
index 3916ff9..a219bca 100644
--- a/quickstep/res/layout/task_menu.xml
+++ b/quickstep/res/layout/task_menu.xml
@@ -16,7 +16,7 @@
-->
<com.android.quickstep.views.TaskMenuView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@drawable/task_menu_bg"
@@ -35,12 +35,10 @@
<LinearLayout
android:id="@+id/menu_option_layout"
- style="@style/TaskMenu"
- android:divider="@drawable/all_apps_divider"
- android:showDividers="beginning"
- android:paddingStart="@dimen/task_card_menu_horizontal_padding"
- android:paddingEnd="@dimen/task_card_menu_horizontal_padding"
android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:divider="@drawable/all_apps_divider"
+ android:showDividers="beginning" />
</com.android.quickstep.views.TaskMenuView>
\ No newline at end of file
diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml
index 102ae9b..a7d6e89 100644
--- a/quickstep/res/layout/task_view_menu_option.xml
+++ b/quickstep/res/layout/task_view_menu_option.xml
@@ -16,9 +16,8 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/TaskMenu.Option"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
android:orientation="vertical"
android:paddingTop="@dimen/task_card_menu_option_vertical_padding"
android:paddingBottom="@dimen/task_card_menu_option_vertical_padding"
@@ -29,22 +28,19 @@
android:id="@+id/icon"
android:layout_width="@dimen/system_shortcut_icon_size"
android:layout_height="@dimen/system_shortcut_icon_size"
- android:layout_marginTop="@dimen/system_shortcut_header_icon_padding"
- android:layout_marginBottom="@dimen/deep_shortcut_drawable_padding"
+ android:layout_marginStart="@dimen/task_menu_option_start_margin"
android:layout_gravity="center_horizontal"
android:backgroundTint="?android:attr/textColorTertiary"/>
<TextView
style="@style/BaseIcon"
android:id="@+id/text"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingBottom="@dimen/popup_padding_end"
+ android:layout_marginStart="@dimen/task_menu_option_start_margin"
android:textSize="12sp"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="sans-serif"
- android:gravity="center_horizontal"
- android:layout_gravity="center_horizontal"
android:focusable="false" />
</LinearLayout>
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index 7cb01f6..668aea2 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -15,7 +15,5 @@
limitations under the License.
-->
<resources>
- <dimen name="task_card_menu_horizontal_padding">24dp</dimen>
-
<dimen name="overview_task_margin">8dp</dimen>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 99ad814..f3b1151 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -45,72 +45,40 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सिफारिस गरिएका एपहरू देखाउने सुविधा सक्षम पारिएका छन्"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सिफारिस गरिएका एपहरू देखाउने सुविधा असक्षम पारिएको छ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान गरिएको एप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <!-- no translation found for back_gesture_feedback_swipe_too_far_from_left_edge (340972404868601012) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_cancelled_left_edge (6671316150388702530) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_complete_left_edge (3220478647881674266) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_swipe_too_far_from_right_edge (4306700023773832353) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_cancelled_right_edge (4951916546256902552) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_complete (7261221999760772210) -->
- <skip />
- <!-- no translation found for back_gesture_feedback_swipe_in_nav_bar (1148198467090405643) -->
- <skip />
- <!-- no translation found for back_gesture_tutorial_confirm_subtitle (5181305411668713250) -->
- <skip />
- <!-- no translation found for back_gesture_intro_title (19551256430224428) -->
- <skip />
- <!-- no translation found for back_gesture_intro_subtitle (7912576483031802797) -->
- <skip />
- <!-- no translation found for home_gesture_feedback_swipe_too_far_from_edge (1446774096007065298) -->
- <skip />
- <!-- no translation found for home_gesture_feedback_overview_detected (1557523944897393013) -->
- <skip />
- <!-- no translation found for home_gesture_feedback_wrong_swipe_direction (6993979358080825438) -->
- <skip />
- <!-- no translation found for home_gesture_feedback_complete (2324789183070815517) -->
- <skip />
- <!-- no translation found for home_gesture_intro_title (836590312858441830) -->
- <skip />
- <!-- no translation found for home_gesture_intro_subtitle (2632238748497975326) -->
- <skip />
- <!-- no translation found for overview_gesture_feedback_swipe_too_far_from_edge (3032757898111577225) -->
- <skip />
- <!-- no translation found for overview_gesture_feedback_home_detected (1411130969354020489) -->
- <skip />
- <!-- no translation found for overview_gesture_feedback_wrong_swipe_direction (6725820500906747925) -->
- <skip />
- <!-- no translation found for overview_gesture_feedback_complete (5477014491632199169) -->
- <skip />
- <!-- no translation found for overview_gesture_intro_title (2902054412868489378) -->
- <skip />
- <!-- no translation found for overview_gesture_intro_subtitle (1579517193845186042) -->
- <skip />
- <!-- no translation found for gesture_tutorial_confirm_title (6201516182040074092) -->
- <skip />
- <!-- no translation found for gesture_tutorial_action_button_label_next (2556263116424738762) -->
- <skip />
- <!-- no translation found for gesture_tutorial_action_button_label_done (671834508127014231) -->
- <skip />
- <!-- no translation found for gesture_tutorial_action_button_label_settings (2923621047916486604) -->
- <skip />
- <!-- no translation found for gesture_tutorial_try_again (65962545858556697) -->
- <skip />
- <!-- no translation found for gesture_tutorial_nice (2936275692616928280) -->
- <skip />
- <!-- no translation found for gesture_tutorial_step (1279786122817620968) -->
- <skip />
+ <string name="back_gesture_feedback_swipe_too_far_from_left_edge" msgid="340972404868601012">"स्क्रिनको सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्।"</string>
+ <string name="back_gesture_feedback_cancelled_left_edge" msgid="6671316150388702530">"स्क्रिनको बायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्।"</string>
+ <string name="back_gesture_feedback_complete_left_edge" msgid="3220478647881674266">"यत्ति हो! अब दायाँ किनाराबाट स्वाइप गरी हेर्नुहोस्।"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_right_edge" msgid="4306700023773832353">"स्क्रिनको सबैभन्दा दायाँ किनाराबाट स्वाइप गर्नुहोस्।"</string>
+ <string name="back_gesture_feedback_cancelled_right_edge" msgid="4951916546256902552">"स्क्रिनको दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्।"</string>
+ <string name="back_gesture_feedback_complete" msgid="7261221999760772210">"तपाईंले \'पछाडि जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब होम स्क्रिनमा जाने तरिका सिक्नुहोस्।"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"स्क्रिनको फेदको धेरै नजिकसम्म स्वाइप नगर्नुहोस्।"</string>
+ <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'पछाडि\' नामक इसाराको संवेदनशीलता बदल्न सेटिङमा जानुहोस्"</string>
+ <string name="back_gesture_intro_title" msgid="19551256430224428">"पछाडि जान स्वाइप गर्नुहोस्"</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"यसअघिको स्क्रिनमा फर्कन स्क्रिनको बायाँ वा दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस्।"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"औँला उठाउनुअघि नरोकिनुहोस्।"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"सीधै माथितिर स्वाइप गर्नुहोस्।"</string>
+ <string name="home_gesture_feedback_complete" msgid="2324789183070815517">"तपाईंले \'होम स्क्रिनमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
+ <string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रिनमा जान स्वाइप गर्नुहोस्"</string>
+ <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्। यो इसारा प्रयोग गर्दा सधैँ होम स्क्रिन खुल्छ।"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"स्क्रिनबाट औँला उठाउनुअघि एपको विन्डोमा केही बेर छोइराख्नुहोस्।"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"सीधै माथितिर स्वाइप गर्नुहोस् अनि रोकिनुहोस्।"</string>
+ <string name="overview_gesture_feedback_complete" msgid="5477014491632199169">"तपाईंले \'एउटा एपबाट अर्को एपमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। तपाईं अब आफ्नो फोन चलाउन सक्नुहुन्छ!"</string>
+ <string name="overview_gesture_intro_title" msgid="2902054412868489378">"एउटा एपबाट अर्को एपमा जान स्वाइप गर्नुहोस्"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="1579517193845186042">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्, छोइराख्नुहोस् अनि औँला उठाउनुहोस्।"</string>
+ <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"सबै तयार छ"</string>
+ <string name="gesture_tutorial_action_button_label_next" msgid="2556263116424738762">"अर्को"</string>
+ <string name="gesture_tutorial_action_button_label_done" msgid="671834508127014231">"सम्पन्न भयो"</string>
+ <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिङ"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"फेरि प्रयास गर्नुहोस्"</string>
+ <string name="gesture_tutorial_nice" msgid="2936275692616928280">"राम्रो!"</string>
+ <string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्युटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="action_share" msgid="2648470652637092375">"सेयर गर्नुहोस्"</string>
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रिनसट"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन"</string>
- <!-- no translation found for skip_tutorial_dialog_title (2725643161260038458) -->
- <skip />
+ <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेभिगेसन ट्युटोरियल स्किप गर्ने हो?"</string>
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तपाईं पछि <xliff:g id="NAME">%1$s</xliff:g> एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ"</string>
- <!-- no translation found for gesture_tutorial_action_button_label_cancel (3809842569351264108) -->
- <skip />
- <!-- no translation found for gesture_tutorial_action_button_label_skip (394452764989751960) -->
- <skip />
+ <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द गर्नुहोस्"</string>
+ <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नु…"</string>
</resources>
diff --git a/quickstep/res/values-land/styles.xml b/quickstep/res/values/attrs.xml
similarity index 61%
rename from quickstep/res/values-land/styles.xml
rename to quickstep/res/values/attrs.xml
index 0824b4f..336fb57 100644
--- a/quickstep/res/values-land/styles.xml
+++ b/quickstep/res/values/attrs.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2018 The Android Open Source Project
+ Copyright (C) 2021 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.
@@ -15,14 +15,8 @@
limitations under the License.
-->
<resources>
- <!-- Task Menu layout styles. -->
- <style name="TaskMenu">
- <item name="android:orientation">horizontal</item>
- </style>
-
- <!-- Task Menu Option layout styles. -->
- <style name="TaskMenu.Option">
- <item name="android:layout_width">0dp</item>
- <item name="android:layout_weight">1</item>
- </style>
-</resources>
\ No newline at end of file
+ <declare-styleable name="AllSetLinkSpan">
+ <attr name="android:textSize"/>
+ <attr name="android:fontFamily"/>
+ </declare-styleable>
+</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 99be502..4f9b3eb 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -67,7 +67,7 @@
in various configurations -->
<dimen name="task_card_menu_option_vertical_padding">8dp</dimen>
<dimen name="task_card_menu_shadow_height">3dp</dimen>
- <dimen name="task_card_menu_horizontal_padding">0dp</dimen>
+ <dimen name="task_menu_option_start_margin">12dp</dimen>
<!-- Copied from framework resource:
docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
<dimen name="multi_window_task_divider_size">10dp</dimen>
@@ -99,6 +99,13 @@
<dimen name="gesture_tutorial_feedback_margin_start_end">24dp</dimen>
<dimen name="gesture_tutorial_button_margin_start_end">18dp</dimen>
+ <!-- All Set page -->
+ <dimen name="allset_page_margin_horizontal">40dp</dimen>
+ <dimen name="allset_title_margin_top">28dp</dimen>
+ <dimen name="allset_title_icon_margin_top">80dp</dimen>
+ <dimen name="allset_hint_margin_bottom">52dp</dimen>
+ <dimen name="allset_subtitle_margin_top">24dp</dimen>
+
<!-- All Apps Education tutorial -->
<dimen name="swipe_edu_padding">8dp</dimen>
<dimen name="swipe_edu_circle_size">64dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index a0f1638..7ada496 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -177,6 +177,15 @@
<!-- Feedback subtext displaying the current step and the total number of steps for the tutorial. [CHAR LIMIT=30] -->
<string name="gesture_tutorial_step">Tutorial <xliff:g id="current">%1$d</xliff:g>/<xliff:g id="total">%2$d</xliff:g></string>
+ <!-- Title of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_title">All set!</string>
+ <!-- Hint string at the bottom of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_hint">Swipe up to go home</string>
+ <!-- Description of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_description">You\u2019re ready to start using your phone</string>
+ <!-- String linking to navigation settings on "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_navigation_settings"><annotation id="link">Navigation settings for accessibility</annotation></string>
+
<!-- ******* Overview ******* -->
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
<string name="action_share">Share</string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 82a91a7..0a8ecb8 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -15,16 +15,6 @@
limitations under the License.
-->
<resources>
- <!-- Task Menu layout styles. -->
- <style name="TaskMenu">
- <item name="android:orientation">vertical</item>
- </style>
-
- <!-- Task Menu Option layout styles. -->
- <style name="TaskMenu.Option">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- </style>
<style name="TextAppearance.GestureTutorial"
parent="android:TextAppearance.Material.Body1" />
@@ -69,7 +59,7 @@
parent="TextAppearance.GestureTutorial">
<item name="android:gravity">start</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:fontFamily">google-sans</item>
+ <item name="android:fontFamily">google-sans-text</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:textSize">18sp</item>
<item name="android:lineHeight">24sp</item>
@@ -109,6 +99,11 @@
<item name="android:textColor">@color/gesture_tutorial_primary_color</item>
</style>
+ <style name="TextAppearance.GestureTutorial.LinkText"
+ parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
+ <item name="android:textSize">14sp</item>
+ </style>
+
<!--
Can be applied to views to color things like ripples and list highlights the workspace text
color.
diff --git a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
index 70a143e..7c97b93 100644
--- a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
+++ b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
@@ -36,6 +36,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -44,6 +45,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shadows.ShadowDeviceFlag;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -60,6 +62,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAppWidgetManager;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.util.ReflectionHelpers;
@@ -174,6 +177,41 @@
assertWidgetInfo(recommendedWidgets.get(2).info, mApp1Provider1);
}
+ @Test
+ public void widgetsRecommendationRan_localFilterDisabled_shouldReturnWidgetsInPredicationOrder()
+ throws Exception {
+ ShadowDeviceFlag shadowDeviceFlag = Shadow.extract(
+ FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER);
+ shadowDeviceFlag.setValue(false);
+
+ // WHEN newPredicationTask is executed with 5 predicated widgets.
+ AppTarget widget1 = new AppTarget(new AppTargetId("app1"), "app1", "provider1",
+ mUserHandle);
+ AppTarget widget2 = new AppTarget(new AppTargetId("app1"), "app1", "provider2",
+ mUserHandle);
+ // Not installed app
+ AppTarget widget3 = new AppTarget(new AppTargetId("app2"), "app3", "provider1",
+ mUserHandle);
+ // Not installed widget
+ AppTarget widget4 = new AppTarget(new AppTargetId("app4"), "app4", "provider3",
+ mUserHandle);
+ AppTarget widget5 = new AppTarget(new AppTargetId("app5"), "app5", "provider1",
+ mUserHandle);
+ mModelHelper.executeTaskForTest(
+ newWidgetsPredicationTask(List.of(widget5, widget3, widget2, widget4, widget1)))
+ .forEach(Runnable::run);
+
+ // THEN only 3 widgets are returned because the launcher only filters out non-exist widgets.
+ List<PendingAddWidgetInfo> recommendedWidgets = mCallback.mRecommendedWidgets.items
+ .stream()
+ .map(itemInfo -> (PendingAddWidgetInfo) itemInfo)
+ .collect(Collectors.toList());
+ assertThat(recommendedWidgets).hasSize(3);
+ assertWidgetInfo(recommendedWidgets.get(0).info, mApp5Provider1);
+ assertWidgetInfo(recommendedWidgets.get(1).info, mApp1Provider2);
+ assertWidgetInfo(recommendedWidgets.get(2).info, mApp1Provider1);
+ }
+
private void assertWidgetInfo(
LauncherAppWidgetProviderInfo actual, AppWidgetProviderInfo expected) {
assertThat(actual.provider).isEqualTo(expected.provider);
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 7aae38c..cd22196 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
+import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
@@ -240,7 +240,7 @@
public void onDisplayInfoChanged(Context context, DisplayController.Info info,
int flags) {
super.onDisplayInfoChanged(context, info, flags);
- if ((flags & CHANGE_SIZE) != 0) {
+ if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
addTaskbarIfNecessary();
}
}
@@ -443,11 +443,25 @@
if (info == null) {
return;
}
+ switch (info.container) {
+ case LauncherSettings.Favorites.CONTAINER_DESKTOP:
+ case LauncherSettings.Favorites.CONTAINER_HOTSEAT:
+ // Fall through and continue it's on the workspace (we don't support swiping back
+ // to other containers like all apps or the hotseat predictions (which can change)
+ break;
+ default:
+ if (info.container >= 0) {
+ // Also allow swiping to folders
+ break;
+ }
+ return;
+ }
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- // Fall through and continue if it's an app or shortcut
+ case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+ // Fall through and continue if it's an app, shortcut, or widget
break;
default:
return;
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index fb67645..36764a1 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -60,6 +60,7 @@
import android.os.Looper;
import android.os.SystemProperties;
import android.util.Pair;
+import android.util.Size;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -780,7 +781,9 @@
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
? 0 : getWindowCornerRadius(mLauncher.getResources());
final FloatingWidgetView floatingView = FloatingWidgetView.getFloatingWidgetView(mLauncher,
- v, widgetBackgroundBounds, windowTargetBounds, finalWindowRadius);
+ v, widgetBackgroundBounds,
+ new Size(windowTargetBounds.width(), windowTargetBounds.height()),
+ finalWindowRadius);
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
? floatingView.getInitialCornerRadius() : 0;
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index cc3ccea..6d5975f 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -33,7 +33,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
@@ -80,9 +79,9 @@
setOrientation(LinearLayout.HORIZONTAL);
mFocusHelper = new SimpleFocusIndicatorHelper(this);
- mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numAllAppsColumns;
mLauncher = Launcher.getLauncher(context);
mLauncher.addOnDeviceProfileChangeListener(this);
+ mNumPredictedAppsPerRow = mLauncher.getDeviceProfile().numShownAllAppsColumns;
updateVisibility();
}
@@ -174,7 +173,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
- mNumPredictedAppsPerRow = dp.inv.numAllAppsColumns;
+ mNumPredictedAppsPerRow = dp.numShownAllAppsColumns;
removeAllViews();
applyPredictionApps();
}
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 8c68872..b0c13f9 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -104,8 +104,8 @@
// TODO: Implement caching and preloading
super.loadItems(ums, pinnedShortcuts);
- WorkspaceItemFactory allAppsFactory =
- new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numAllAppsColumns);
+ WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(
+ mApp, ums, pinnedShortcuts, mIDP.numDatabaseAllAppsColumns);
mAllAppsState.items.setItems(
mAllAppsState.storage.read(mApp.getContext(), allAppsFactory, ums.allUsers::get));
mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
@@ -204,7 +204,7 @@
registerPredictor(mAllAppsState, apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("home")
- .setPredictedTargetCount(mIDP.numAllAppsColumns)
+ .setPredictedTargetCount(mIDP.numDatabaseAllAppsColumns)
.build()));
// TODO: get bundle
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index a29ac1a..22a8c9b 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -16,16 +16,17 @@
package com.android.launcher3.model;
import android.app.prediction.AppTarget;
+import android.content.ComponentName;
+import android.text.TextUtils;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.PendingAddWidgetInfo;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,25 +57,43 @@
Map<PackageUserKey, List<WidgetItem>> allWidgets =
dataModel.widgetsModel.getAllWidgetsWithoutShortcuts();
- ArrayList<ItemInfo> recommendedWidgetsInDescendingOrder = new ArrayList<>();
- for (AppTarget app : mTargets) {
- PackageUserKey packageUserKey = new PackageUserKey(app.getPackageName(), app.getUser());
- if (allWidgets.containsKey(packageUserKey)) {
- List<WidgetItem> notAddedWidgets = allWidgets.get(packageUserKey).stream()
- .filter(item ->
- !widgetsInWorkspace.contains(
- new ComponentKey(item.componentName, item.user)))
- .collect(Collectors.toList());
- if (notAddedWidgets.size() > 0) {
- // Even an apps have more than one widgets, we only include one widget.
- recommendedWidgetsInDescendingOrder.add(
- new PendingAddWidgetInfo(notAddedWidgets.get(0).widgetInfo));
+ FixedContainerItems fixedContainerItems = mPredictorState.items;
+ fixedContainerItems.items.clear();
+
+ if (FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER.get()) {
+ for (AppTarget app : mTargets) {
+ PackageUserKey packageUserKey = new PackageUserKey(app.getPackageName(),
+ app.getUser());
+ if (allWidgets.containsKey(packageUserKey)) {
+ List<WidgetItem> notAddedWidgets = allWidgets.get(packageUserKey).stream()
+ .filter(item ->
+ !widgetsInWorkspace.contains(
+ new ComponentKey(item.componentName, item.user)))
+ .collect(Collectors.toList());
+ if (notAddedWidgets.size() > 0) {
+ // Even an apps have more than one widgets, we only include one widget.
+ fixedContainerItems.items.add(
+ new PendingAddWidgetInfo(notAddedWidgets.get(0).widgetInfo));
+ }
+ }
+ }
+ } else {
+ Map<ComponentKey, WidgetItem> widgetItems =
+ allWidgets.values().stream().flatMap(List::stream)
+ .collect(Collectors.toMap(widget -> (ComponentKey) widget,
+ widget -> widget));
+ for (AppTarget app : mTargets) {
+ if (TextUtils.isEmpty(app.getClassName())) {
+ continue;
+ }
+ ComponentKey targetWidget = new ComponentKey(
+ new ComponentName(app.getPackageName(), app.getClassName()), app.getUser());
+ if (widgetItems.containsKey(targetWidget)) {
+ fixedContainerItems.items.add(
+ new PendingAddWidgetInfo(widgetItems.get(targetWidget).widgetInfo));
}
}
}
- FixedContainerItems fixedContainerItems = mPredictorState.items;
- fixedContainerItems.items.clear();
- fixedContainerItems.items.addAll(recommendedWidgetsInDescendingOrder);
bindExtraContainerItems(fixedContainerItems);
// Don't store widgets prediction to disk because it is not used frequently.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index 1e03b05..76a5782 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -18,13 +18,23 @@
import android.app.Person;
import android.content.pm.ShortcutInfo;
+import android.view.Display;
import com.android.launcher3.Utilities;
public class ApiWrapper {
+ public static final boolean TASKBAR_DRAWN_IN_PROCESS = true;
+
public static Person[] getPersons(ShortcutInfo si) {
Person[] persons = si.getPersons();
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
}
+
+ /**
+ * Returns true if the display is an internal displays
+ */
+ public static boolean isInternalDisplay(Display display) {
+ return display.getType() == Display.TYPE_INTERNAL;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
index bb1f6fc..c115bbb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
@@ -68,6 +68,12 @@
mListeners.remove(r);
}
+ @Override
+ public boolean get() {
+ // Override this method in order to let Robolectric ShadowDeviceFlag to stub it.
+ return super.get();
+ }
+
private void registerDeviceConfigChangedListener(Context context) {
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_LAUNCHER,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 66e4f4c..a54f963 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.widget.RemoteViews;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -49,6 +50,11 @@
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(hostView);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(mLauncher, hostView);
+ activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Object itemInfo = hostView.getTag();
+ if (itemInfo instanceof ItemInfo) {
+ mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
+ }
options = Pair.create(options.first, activityOptions.options);
return RemoteViews.startPendingIntent(hostView, pendingIntent, options);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index f09d9e0..d07cc35 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_WIDGET_APP_START;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_TWO_BUTTON_ORDINAL;
@@ -36,7 +37,6 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.os.SystemProperties;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -90,9 +90,6 @@
public class QuickstepLauncher extends BaseQuickstepLauncher {
- private static final boolean ENABLE_APP_WIDGET_LAUNCH_ANIMATION =
- SystemProperties.getBoolean("persist.debug.quickstep_app_widget_launch", false);
-
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
/**
* Reusable command for applying the shelf height on the background thread.
@@ -327,7 +324,7 @@
protected LauncherAppWidgetHost createAppWidgetHost() {
LauncherAppWidgetHost appWidgetHost = super.createAppWidgetHost();
- if (ENABLE_APP_WIDGET_LAUNCH_ANIMATION) {
+ if (ENABLE_QUICKSTEP_WIDGET_APP_START.get()) {
appWidgetHost.setInteractionHandler(new QuickstepInteractionHandler(this));
}
return appWidgetHost;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index ba61923..3ac7866 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -77,6 +77,7 @@
@Override
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
StateAnimationConfig config) {
+ RecentsView overview = mActivity.getOverviewPanel();
if (toState == NORMAL && fromState == OVERVIEW) {
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
@@ -85,7 +86,12 @@
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL);
if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
- config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
+ // Scrolling in tasks, so make visible straight away
+ if (overview.getTaskViewCount() > 0) {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
+ } else {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
+ }
} else {
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
}
@@ -122,13 +128,18 @@
config.setInterpolator(ANIM_WORKSPACE_SCALE,
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
- config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
+
+ // Scrolling in tasks, so show straight away
+ if (overview.getTaskViewCount() > 0) {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
+ } else {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
+ }
} else {
config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
// Scale up the recents, if it is not coming from the side
- RecentsView overview = mActivity.getOverviewPanel();
if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
RECENTS_SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 2d95ce2..729e2cb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -18,20 +18,11 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
-import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
-import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_HEADER_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@@ -45,7 +36,6 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
@@ -269,39 +259,4 @@
private float dpiFromPx(float pixels) {
return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics().densityDpi);
}
-
- @Override
- protected StateAnimationConfig getConfigForStates(
- LauncherState fromState, LauncherState toState) {
- if (fromState == NORMAL && toState == ALL_APPS) {
- StateAnimationConfig builder = new StateAnimationConfig();
- builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
- ACCEL,
- 0,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
- ACCEL,
- ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
-
- // Get workspace out of the way quickly, to prepare for potential pause.
- builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3);
- builder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, DEACCEL_3);
- builder.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_3);
- return builder;
- } else if (fromState == ALL_APPS && toState == NORMAL) {
- StateAnimationConfig builder = new StateAnimationConfig();
-
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
- DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
- DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1));
- return builder;
- }
- return super.getConfigForStates(fromState, toState);
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index b8f9452..3c83d25 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -24,6 +24,7 @@
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import android.view.MotionEvent;
@@ -56,13 +57,17 @@
/**
* Minimum clamping progress for fading in all apps content
*/
- protected static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.4f;
-
+ protected static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
/**
- * The progress at which recents will begin fading out when swiping up from overview.
+ * Minimum clamping progress for fading in all apps scrim
*/
- private static final float RECENTS_FADE_THRESHOLD = 0.88f;
+ protected static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = .1f;
+
+ /**
+ * Maximum clamping progress for opaque all apps scrim
+ */
+ protected static final float ALL_APPS_SCRIM_OPAQUE_THRESHOLD = .5f;
private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
@@ -122,14 +127,22 @@
private StateAnimationConfig getNormalToAllAppsAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
- 0, ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
+ ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
+ ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
+ ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
return builder;
}
private StateAnimationConfig getAllAppsToNormalAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD, 1));
+ 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
+ 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
+ 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
+ 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
return builder;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 9c79c32..10384a8 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -47,7 +47,6 @@
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_END;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_START;
-import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -55,7 +54,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -150,6 +148,9 @@
protected Runnable mGestureEndCallback;
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
+ // One time flag set when onConsumerAboutToBeSwitched() is called, indicating that certain
+ // shared animations should not be canceled when this handler is invalidated
+ private boolean mConsumerIsSwitching;
private boolean mRecentsViewScrollLinked = false;
private static int getFlagForIndex(int index, String name) {
@@ -461,8 +462,6 @@
mDeviceState.getRotationTouchHelper()
.onEndTargetCalculated(mGestureState.getEndTarget(),
mActivityInterface);
-
- mRecentsView.onGestureEndTargetCalculated(mGestureState.getEndTarget());
});
notifyGestureStartedAsync();
@@ -1002,7 +1001,14 @@
animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
}
- private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
+ private int getLogGestureTaskIndex(@Nullable TaskView targetTask) {
+ return mRecentsView == null || targetTask == null
+ ? LOG_NO_OP_PAGE_INDEX
+ : mRecentsView.indexOfChild(targetTask);
+ }
+
+ private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask,
+ int pageIndex) {
StatsLogManager.EventEnum event;
switch (endTarget) {
case HOME:
@@ -1031,9 +1037,6 @@
// We probably never received an animation controller, skip logging.
return;
}
- int pageIndex = endTarget == LAST_TASK
- ? LOG_NO_OP_PAGE_INDEX
- : mRecentsView.getNextPage();
// TODO: set correct container using the pageIndex
logger.log(event);
}
@@ -1088,8 +1091,10 @@
final RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets != null
? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
: null;
- HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(
- runningTaskTarget.taskInfo.launchCookies, duration);
+ final ArrayList<IBinder> cookies = runningTaskTarget != null
+ ? runningTaskTarget.taskInfo.launchCookies
+ : new ArrayList<>();
+ HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(cookies, duration);
mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome()
&& runningTaskTarget != null
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
@@ -1124,6 +1129,10 @@
}
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
mLauncherTransitionController = null;
+
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget());
+ }
} else {
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end);
@@ -1162,9 +1171,9 @@
}
});
animatorSet.play(windowAnim);
- S state = mActivityInterface.stateFromGestureEndTarget(mGestureState.getEndTarget());
- if (mRecentsView != null && state.displayOverviewTasksAsGrid(mDp)) {
- animatorSet.play(ObjectAnimator.ofFloat(mRecentsView, RECENTS_GRID_PROGRESS, 1));
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(
+ animatorSet, mGestureState.getEndTarget());
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
@@ -1278,18 +1287,18 @@
}
public void onConsumerAboutToBeSwitched() {
+ mConsumerIsSwitching = true;
if (mActivity != null) {
// In the off chance that the gesture ends before Launcher is started, we should clear
// the callback here so that it doesn't update with the wrong state
mActivity.clearRunOnceOnStartCallback();
- resetLauncherListeners();
}
if (mGestureState.getEndTarget() != null && !mGestureState.isRunningAnimationToLauncher()) {
cancelCurrentAnimation();
} else {
mStateCallback.setStateOnUiThread(STATE_FINISH_WITH_NO_END);
- reset();
}
+ reset();
}
public boolean isCanceled() {
@@ -1300,13 +1309,14 @@
private void resumeLastTask() {
mRecentsAnimationController.finish(false /* toRecents */, null);
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
- doLogGesture(LAST_TASK, null);
+ doLogGesture(LAST_TASK, null, getLogGestureTaskIndex(null));
reset();
}
@UiThread
private void startNewTask() {
TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
+ int taskPageIndex = getLogGestureTaskIndex(taskToLaunch);
startNewTask(success -> {
if (!success) {
reset();
@@ -1315,7 +1325,7 @@
endLauncherTransitionController();
updateSysUiFlags(1 /* windowProgress == overview */);
}
- doLogGesture(NEW_TASK, taskToLaunch);
+ doLogGesture(NEW_TASK, taskToLaunch, taskPageIndex);
});
}
@@ -1349,32 +1359,38 @@
}
private void invalidateHandler() {
- if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
- || mGestureState.getEndTarget() != RECENTS) {
- mInputConsumerProxy.destroy();
- mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+ if (!mConsumerIsSwitching) {
+ if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
+ || mGestureState.getEndTarget() != RECENTS) {
+ mInputConsumerProxy.destroy();
+ mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+ }
+ endRunningWindowAnim(false /* cancel */);
+
+ if (mGestureEndCallback != null) {
+ mGestureEndCallback.run();
+ }
}
+
mInputConsumerProxy.unregisterCallback();
- endRunningWindowAnim(false /* cancel */);
-
- if (mGestureEndCallback != null) {
- mGestureEndCallback.run();
- }
-
mActivityInitListener.unregister();
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
mTaskSnapshot = null;
mHandler.post(() -> {
// Defer clearing the activity since invalidation can happen over multiple callbacks
+ // ie. invalidateHandlerWithLauncher()
mActivity = null;
+ mRecentsView = null;
});
}
private void invalidateHandlerWithLauncher() {
- endLauncherTransitionController();
+ if (!mConsumerIsSwitching) {
+ endLauncherTransitionController();
+ mRecentsView.onGestureAnimationEnd();
+ }
mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
- mRecentsView.onGestureAnimationEnd();
resetLauncherListeners();
}
@@ -1407,23 +1423,17 @@
}
protected void switchToScreenshot() {
- final int runningTaskId = mGestureState.getRunningTaskId();
- if (LIVE_TILE.get()) {
- if (mRecentsAnimationController != null) {
- mRecentsAnimationController.getController().setWillFinishToHome(true);
- // Update the screenshot of the task
- if (mTaskSnapshot == null) {
- mTaskSnapshot = mRecentsAnimationController.screenshotTask(runningTaskId);
- }
- mRecentsView.updateThumbnail(runningTaskId, mTaskSnapshot, false /* refreshNow */);
- }
- mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
- } else if (!hasTargets()) {
+ if (!hasTargets()) {
// If there are no targets, then we don't need to capture anything
mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
} else {
+ final int runningTaskId = mGestureState.getRunningTaskId();
+ final boolean refreshView = !LIVE_TILE.get() /* refreshView */;
boolean finishTransitionPosted = false;
if (mRecentsAnimationController != null) {
+ if (LIVE_TILE.get()) {
+ mRecentsAnimationController.getController().setWillFinishToHome(true);
+ }
// Update the screenshot of the task
if (mTaskSnapshot == null) {
UI_HELPER_EXECUTOR.execute(() -> {
@@ -1432,14 +1442,14 @@
mRecentsAnimationController.screenshotTask(runningTaskId);
MAIN_EXECUTOR.execute(() -> {
mTaskSnapshot = taskSnapshot;
- if (!updateThumbnail(runningTaskId)) {
+ if (!updateThumbnail(runningTaskId, refreshView)) {
setScreenshotCapturedState();
}
});
});
return;
}
- finishTransitionPosted = updateThumbnail(runningTaskId);
+ finishTransitionPosted = updateThumbnail(runningTaskId, refreshView);
}
if (!finishTransitionPosted) {
setScreenshotCapturedState();
@@ -1448,17 +1458,17 @@
}
// Returns whether finish transition was posted.
- private boolean updateThumbnail(int runningTaskId) {
+ private boolean updateThumbnail(int runningTaskId, boolean refreshView) {
boolean finishTransitionPosted = false;
final TaskView taskView;
- if (mGestureState.getEndTarget() == HOME) {
- // Capture the screenshot before finishing the transition to home to ensure it's
- // taken in the correct orientation, but no need to update the thumbnail.
+ if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK) {
+ // Capture the screenshot before finishing the transition to home or quickswitching to
+ // ensure it's taken in the correct orientation, but no need to update the thumbnail.
taskView = null;
} else {
- taskView = mRecentsView.updateThumbnail(runningTaskId, mTaskSnapshot);
+ taskView = mRecentsView.updateThumbnail(runningTaskId, mTaskSnapshot, refreshView);
}
- if (taskView != null && !mCanceled) {
+ if (taskView != null && refreshView && !mCanceled) {
// Defer finishing the animation until the next launcher frame with the
// new thumbnail
finishTransitionPosted = ViewUtils.postFrameDrawn(taskView,
@@ -1499,7 +1509,8 @@
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
- doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
+ TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView();
+ doLogGesture(HOME, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
}
/**
@@ -1530,7 +1541,8 @@
}
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
- doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView());
+ TaskView taskToLaunch = mRecentsView.getCurrentPageTaskView();
+ doLogGesture(RECENTS, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
reset();
}
@@ -1689,7 +1701,7 @@
// No need to apply any transform if there is ongoing swipe-pip-to-home animator since
// that animator handles the leash solely.
if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
- if (mRecentsViewScrollLinked) {
+ if (mRecentsViewScrollLinked && mRecentsView != null) {
mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
}
mTaskViewSimulator.apply(mTransformParams);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 9fa65d9..3c81d1b 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -163,7 +163,9 @@
@Override
public boolean isInLiveTileMode() {
- return false;
+ RecentsActivity activity = getCreatedActivity();
+ return activity != null && activity.getStateManager().getState() == DEFAULT &&
+ activity.isStarted();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index dd35d68..46cd8a2 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -30,9 +30,11 @@
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.os.IBinder;
import android.os.UserHandle;
+import android.util.Size;
import android.view.View;
import androidx.annotation.NonNull;
@@ -50,9 +52,11 @@
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.FloatingIconView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
+import com.android.quickstep.views.FloatingWidgetView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.plugins.ResourceProvider;
@@ -77,155 +81,207 @@
@Override
protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
long duration) {
- HomeAnimationFactory homeAnimFactory;
- if (mActivity != null) {
- final View workspaceView = findWorkspaceView(launchCookies,
- mRecentsView.getRunningTaskView());
- boolean canUseWorkspaceView =
- workspaceView != null && workspaceView.isAttachedToWindow();
-
- mActivity.getRootView().setForceHideBackArrow(true);
- mActivity.setHintUserWillBeActive();
-
- if (canUseWorkspaceView) {
- final ResourceProvider rp = DynamicResource.provider(mActivity);
- final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
- float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s));
- final float launcherAlphaMax =
- rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress);
-
- RectF iconLocation = new RectF();
- FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
- true /* hideOriginal */, iconLocation, false /* isOpening */);
-
- // We want the window alpha to be 0 once this threshold is met, so that the
- // FolderIconView can be seen morphing into the icon shape.
- float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
- homeAnimFactory = new LauncherHomeAnimationFactory() {
-
- // There is a delay in loading the icon, so we need to keep the window
- // opaque until it is ready.
- private boolean mIsFloatingIconReady = false;
-
- private @Nullable ValueAnimator mBounceBackAnimator;
-
- @Override
- public RectF getWindowTargetRect() {
- if (PROTOTYPE_APP_CLOSE.get()) {
- // We want the target rect to be at this offset position, so that all
- // launcher content can spring back upwards.
- floatingIconView.setPositionOffsetY(transY);
- }
- return iconLocation;
- }
-
- @Override
- public void setAnimation(RectFSpringAnim anim) {
- anim.addAnimatorListener(floatingIconView);
- floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
- floatingIconView.setFastFinishRunnable(anim::end);
- if (PROTOTYPE_APP_CLOSE.get()) {
- mBounceBackAnimator = bounceBackToRestingPosition();
- // Use a spring to put drag layer translation back to 0.
- anim.addAnimatorListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- floatingIconView.setPositionOffsetY(0);
- mBounceBackAnimator.start();
- }
- });
-
- Workspace workspace = mActivity.getWorkspace();
- workspace.setPivotToScaleWithSelf(mActivity.getHotseat());
- }
- }
-
- private ValueAnimator bounceBackToRestingPosition() {
- DragLayer dl = mActivity.getDragLayer();
- Workspace workspace = mActivity.getWorkspace();
- Hotseat hotseat = mActivity.getHotseat();
-
- final float startValue = transY;
- final float endValue = 0;
- // Ensures the velocity is always aligned with the direction.
- float pixelPerSecond = Math.abs(dpPerSecond)
- * Math.signum(endValue - transY);
-
- ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
- .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
- .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
- .setMinimumVisibleChange(1f)
- .setStartValue(startValue)
- .setEndValue(endValue)
- .setStartVelocity(pixelPerSecond)
- .build(dl, VIEW_TRANSLATE_Y);
- springTransY.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- dl.setTranslationY(0f);
- dl.setAlpha(1f);
- SCALE_PROPERTY.set(workspace, 1f);
- SCALE_PROPERTY.set(hotseat, 1f);
- }
- });
- return springTransY;
- }
-
- @Override
- public boolean keepWindowOpaque() {
- if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
- mIsFloatingIconReady = true;
- return false;
- }
- return true;
- }
-
- @Override
- public void update(@Nullable AppCloseConfig config, RectF currentRect,
- float progress, float radius) {
- int fgAlpha = 255;
- if (config != null && PROTOTYPE_APP_CLOSE.get()) {
- DragLayer dl = mActivity.getDragLayer();
- float translationY = config.getWorkspaceTransY();
- dl.setTranslationY(translationY);
-
- float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR);
- dl.setAlpha(Math.min(alpha, 1f));
-
- float scale = Math.min(1f, config.getWorkspaceScale());
- SCALE_PROPERTY.set(mActivity.getWorkspace(), scale);
- SCALE_PROPERTY.set(mActivity.getHotseat(), scale);
- SCALE_PROPERTY.set(mActivity.getAppsView(), scale);
-
- progress = config.getInterpolatedProgress();
- fgAlpha = config.getFgAlpha();
- }
- floatingIconView.update(1f, fgAlpha, currentRect, progress,
- windowAlphaThreshold, radius, false);
- }
-
- @Override
- public void onCancel() {
- floatingIconView.fastFinish();
- if (mBounceBackAnimator != null) {
- mBounceBackAnimator.cancel();
- }
- }
- };
- } else {
- homeAnimFactory = new LauncherHomeAnimationFactory();
- }
- } else {
- homeAnimFactory = new HomeAnimationFactory() {
+ if (mActivity == null) {
+ mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
+ isPresent -> mRecentsView.startHome());
+ return new HomeAnimationFactory() {
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
return AnimatorPlaybackController.wrap(new AnimatorSet(), duration);
}
};
- mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
- isPresent -> mRecentsView.startHome());
}
- return homeAnimFactory;
+
+ final View workspaceView = findWorkspaceView(launchCookies,
+ mRecentsView.getRunningTaskView());
+ boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
+
+ mActivity.getRootView().setForceHideBackArrow(true);
+ mActivity.setHintUserWillBeActive();
+
+ if (!canUseWorkspaceView) {
+ return new LauncherHomeAnimationFactory();
+ }
+ if (workspaceView instanceof LauncherAppWidgetHostView) {
+ return createWidgetHomeAnimationFactory((LauncherAppWidgetHostView) workspaceView);
+ }
+ return createIconHomeAnimationFactory(workspaceView);
+ }
+
+ private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
+ final ResourceProvider rp = DynamicResource.provider(mActivity);
+ final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+ float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s));
+ final float launcherAlphaMax =
+ rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress);
+
+ RectF iconLocation = new RectF();
+ FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
+ true /* hideOriginal */, iconLocation, false /* isOpening */);
+
+ // We want the window alpha to be 0 once this threshold is met, so that the
+ // FolderIconView can be seen morphing into the icon shape.
+ float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
+ return new LauncherHomeAnimationFactory() {
+
+ // There is a delay in loading the icon, so we need to keep the window
+ // opaque until it is ready.
+ private boolean mIsFloatingIconReady = false;
+
+ private @Nullable ValueAnimator mBounceBackAnimator;
+
+ @Override
+ public RectF getWindowTargetRect() {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ // We want the target rect to be at this offset position, so that all
+ // launcher content can spring back upwards.
+ floatingIconView.setPositionOffsetY(transY);
+ }
+ return iconLocation;
+ }
+
+ @Override
+ public void setAnimation(RectFSpringAnim anim) {
+ anim.addAnimatorListener(floatingIconView);
+ floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ floatingIconView.setFastFinishRunnable(anim::end);
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ mBounceBackAnimator = bounceBackToRestingPosition();
+ // Use a spring to put drag layer translation back to 0.
+ anim.addAnimatorListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ floatingIconView.setPositionOffsetY(0);
+ mBounceBackAnimator.start();
+ }
+ });
+
+ Workspace workspace = mActivity.getWorkspace();
+ workspace.setPivotToScaleWithSelf(mActivity.getHotseat());
+ }
+ }
+
+ private ValueAnimator bounceBackToRestingPosition() {
+ DragLayer dl = mActivity.getDragLayer();
+ Workspace workspace = mActivity.getWorkspace();
+ Hotseat hotseat = mActivity.getHotseat();
+
+ final float startValue = transY;
+ final float endValue = 0;
+ // Ensures the velocity is always aligned with the direction.
+ float pixelPerSecond = Math.abs(dpPerSecond) * Math.signum(endValue - transY);
+
+ ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
+ .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
+ .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
+ .setMinimumVisibleChange(1f)
+ .setStartValue(startValue)
+ .setEndValue(endValue)
+ .setStartVelocity(pixelPerSecond)
+ .build(dl, VIEW_TRANSLATE_Y);
+ springTransY.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ dl.setTranslationY(0f);
+ dl.setAlpha(1f);
+ SCALE_PROPERTY.set(workspace, 1f);
+ SCALE_PROPERTY.set(hotseat, 1f);
+ }
+ });
+ return springTransY;
+ }
+
+ @Override
+ public boolean keepWindowOpaque() {
+ if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
+ mIsFloatingIconReady = true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ int fgAlpha = 255;
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ DragLayer dl = mActivity.getDragLayer();
+ float translationY = config.getWorkspaceTransY();
+ dl.setTranslationY(translationY);
+
+ float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR);
+ dl.setAlpha(Math.min(alpha, 1f));
+
+ float scale = Math.min(1f, config.getWorkspaceScale());
+ SCALE_PROPERTY.set(mActivity.getWorkspace(), scale);
+ SCALE_PROPERTY.set(mActivity.getHotseat(), scale);
+ SCALE_PROPERTY.set(mActivity.getAppsView(), scale);
+
+ progress = config.getInterpolatedProgress();
+ fgAlpha = config.getFgAlpha();
+ }
+ floatingIconView.update(1f, fgAlpha, currentRect, progress,
+ windowAlphaThreshold, radius, false);
+ }
+
+ @Override
+ public void onCancel() {
+ floatingIconView.fastFinish();
+ if (mBounceBackAnimator != null) {
+ mBounceBackAnimator.cancel();
+ }
+ }
+ };
+ }
+
+ private HomeAnimationFactory createWidgetHomeAnimationFactory(
+ LauncherAppWidgetHostView hostView) {
+
+ RectF backgroundLocation = new RectF();
+ Rect crop = new Rect();
+ mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
+ Size windowSize = new Size(crop.width(), crop.height());
+ FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
+ hostView, backgroundLocation, windowSize,
+ mTaskViewSimulator.getCurrentCornerRadius());
+
+ return new LauncherHomeAnimationFactory() {
+
+ @Override
+ public RectF getWindowTargetRect() {
+ return backgroundLocation;
+ }
+
+ @Override
+ public float getEndRadius(RectF cropRectF) {
+ return floatingWidgetView.getInitialCornerRadius();
+ }
+
+ @Override
+ public void setAnimation(RectFSpringAnim anim) {
+ anim.addAnimatorListener(floatingWidgetView);
+ floatingWidgetView.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ floatingWidgetView.setFastFinishRunnable(anim::end);
+ }
+
+ @Override
+ public boolean keepWindowOpaque() {
+ return false;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ floatingWidgetView.update(currentRect, 1 /* floatingWidgetAlpha */,
+ config != null ? config.getFgAlpha() : 1f /* foregroundAlpha */,
+ 0 /* fallbackBackgroundAlpha */, 1 - progress);
+ }
+
+ @Override
+ public void onCancel() {
+ floatingWidgetView.fastFinish();
+ }
+ };
}
/**
@@ -244,8 +300,9 @@
return null;
}
- // Find the associated item info for the launch cookie (if available)
- int launchCookieItemId = -1;
+ // Find the associated item info for the launch cookie (if available), note that predicted
+ // apps actually have an id of -1, so use another default id here
+ int launchCookieItemId = -2;
for (IBinder cookie : launchCookies) {
Integer itemId = ObjectWrapper.unwrap(cookie);
if (itemId != null) {
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index c47300c..62b821c 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -191,7 +191,7 @@
* @see #enableMultipleRegions(boolean, Info)
*/
void createOrAddTouchRegion(Info info) {
- mCurrentDisplay = new CurrentDisplay(info.realSize, info.rotation);
+ mCurrentDisplay = new CurrentDisplay(info.currentSize, info.rotation);
if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED
&& mCurrentDisplay.rotation == mQuickStepStartingRotation) {
@@ -256,7 +256,7 @@
Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplay.rotation);
}
- mCurrentDisplay = new CurrentDisplay(region.realSize, region.rotation);
+ mCurrentDisplay = new CurrentDisplay(region.currentSize, region.rotation);
OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay);
if (DEBUG) {
Log.d(TestProtocol.NO_SWIPE_TO_HOME, "cached region: " + regionToKeep
@@ -289,7 +289,7 @@
+ " with mode: " + mMode + " displayRotation: " + display.rotation);
}
- Point size = display.realSize;
+ Point size = display.currentSize;
int rotation = display.rotation;
int touchHeight = mNavBarGesturalHeight;
OrientationRectF orientationRectF =
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 3b92779..0e9e3ad 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -22,10 +22,13 @@
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
import static com.android.launcher3.Utilities.createHomeIntent;
+import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -35,6 +38,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.view.SurfaceControl.Transaction;
import android.view.View;
import androidx.annotation.Nullable;
@@ -47,6 +51,7 @@
import com.android.launcher3.R;
import com.android.launcher3.WrappedAnimationRunnerImpl;
import com.android.launcher3.WrappedLauncherAnimationRunner;
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -69,6 +74,7 @@
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.views.OverviewActionsView;
+import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.SplitPlaceholderView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityOptionsCompat;
@@ -90,6 +96,8 @@
private Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private static final long HOME_APPEAR_DURATION = 250;
+
private RecentsDragLayer mDragLayer;
private ScrimView mScrimView;
private FallbackRecentsView mFallbackRecentsView;
@@ -112,6 +120,7 @@
mScrimView = findViewById(R.id.scrim_view);
mFallbackRecentsView = findViewById(R.id.overview_panel);
mActionsView = findViewById(R.id.overview_actions_view);
+ SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
splitPlaceholderView.init(
@@ -291,6 +300,16 @@
super.onConfigurationChanged(newConfig);
}
+ @Override
+ public void onStateSetEnd(RecentsState state) {
+ super.onStateSetEnd(state);
+
+ if (state == RecentsState.DEFAULT) {
+ AccessibilityManagerCompat.sendStateEventToTest(getBaseContext(),
+ OVERVIEW_STATE_ORDINAL);
+ }
+ }
+
/**
* Initialize/update the device profile.
*/
@@ -329,7 +348,42 @@
}
public void startHome() {
- startActivity(createHomeIntent());
+ if (LIVE_TILE.get()) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true,
+ this::startHomeInternal));
+ } else {
+ startHomeInternal();
+ }
+ }
+
+ private void startHomeInternal() {
+ WrappedLauncherAnimationRunner runner = new WrappedLauncherAnimationRunner(
+ getMainThreadHandler(), this::onCreateAnimationToHome, true);
+ RemoteAnimationAdapterCompat adapterCompat =
+ new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0);
+ startActivity(createHomeIntent(),
+ ActivityOptionsCompat.makeRemoteAnimation(adapterCompat).toBundle());
+ }
+
+ private void onCreateAnimationToHome(
+ int transit, RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) {
+ AnimatorPlaybackController controller = getStateManager()
+ .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION);
+ controller.dispatchOnStart();
+
+ RemoteAnimationTargets targets = new RemoteAnimationTargets(
+ appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
+ for (RemoteAnimationTargetCompat app : targets.apps) {
+ new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply();
+ }
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(controller.getAnimationPlayer());
+ anim.setDuration(HOME_APPEAR_DURATION);
+ result.setAnimation(anim, this,
+ () -> getStateManager().goToState(RecentsState.HOME, false));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 4560735..78da311 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -25,6 +25,7 @@
import androidx.annotation.UiThread;
import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.RunnableList;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -43,6 +44,8 @@
private boolean mUseLauncherSysBarFlags = false;
private boolean mSplitScreenMinimized = false;
+ private boolean mFinishRequested = false;
+ private RunnableList mPendingFinishCallbacks = new RunnableList();
public RecentsAnimationController(RecentsAnimationControllerCompat controller,
boolean allowMinimizeSplitScreen,
@@ -132,14 +135,22 @@
@UiThread
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
+ if (mFinishRequested) {
+ // If finishing, add to pending finish callbacks, otherwise, if finished, adding to the
+ // destroyed RunnableList will just trigger the callback to be called immediately
+ mPendingFinishCallbacks.add(callback);
+ return;
+ }
+
+ // Finish not yet requested
+ mFinishRequested = true;
mOnFinishedListener.accept(this);
+ mPendingFinishCallbacks.add(callback);
UI_HELPER_EXECUTOR.execute(() -> {
mController.finish(toRecents, sendUserLeaveHint);
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
- if (callback != null) {
- MAIN_EXECUTOR.execute(callback);
- }
+ MAIN_EXECUTOR.execute(mPendingFinishCallbacks::executeAllAndDestroy);
});
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index ef09957..e271203 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -18,7 +18,7 @@
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
@@ -271,15 +271,9 @@
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
- // ignore displays that aren't running launcher and frame refresh rate changes
- return;
+ if ((flags & CHANGE_ROTATION) != 0) {
+ mNavBarPosition = new NavBarPosition(mMode, info);
}
-
- if (!mMode.hasGestures) {
- return;
- }
- mNavBarPosition = new NavBarPosition(mMode, info);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index fd0de42..7629862 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -17,8 +17,9 @@
import static android.view.Surface.ROTATION_0;
+import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
@@ -274,8 +275,7 @@
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if (info.id != mDisplayId|| flags == CHANGE_FRAME_DELAY) {
- // ignore displays that aren't running launcher and frame refresh rate changes
+ if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
return;
}
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 0f34a72..29a00d1 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -145,6 +145,11 @@
targetX + halfIconSize, targetY + halfIconSize);
}
+ /** Returns the corner radius of the window at the end of the animation. */
+ public float getEndRadius(RectF cropRectF) {
+ return cropRectF.width() / 2f;
+ }
+
public abstract @NonNull AnimatorPlaybackController createActivityAnimationToHome();
public void playAtomicAnimation(float velocity) {
@@ -197,8 +202,7 @@
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
Matrix homeToWindowPositionMap = new Matrix();
- final RectF startRect = updateProgressForStartRect(
- homeToWindowPositionMap, startProgress);
+ final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
// Move the startRect to Launcher space as floatingIconView runs in Launcher
@@ -210,7 +214,7 @@
if (PROTOTYPE_APP_CLOSE.get()) {
anim = new RectFSpringAnim2(startRect, targetRect, mContext,
mTaskViewSimulator.getCurrentCornerRadius(),
- cropRectF.width() / 2f);
+ homeAnimationFactory.getEndRadius(cropRectF));
} else {
anim = new RectFSpringAnim(startRect, targetRect, mContext);
}
@@ -269,7 +273,7 @@
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
// rounding at the end of the animation.
mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
- mEndRadius = cropRectF.width() / 2f;
+ mEndRadius = factory.getEndRadius(cropRectF);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 7067dbc..e4d148c 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -20,7 +20,7 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
@@ -98,6 +98,6 @@
state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()) ? 1f : 0f, LINEAR);
setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
- config.getInterpolator(ANIM_WORKSPACE_SCRIM_FADE, LINEAR));
+ config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 4d4b6e1..1bb8e96 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -20,6 +20,7 @@
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
+import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -27,6 +28,9 @@
import android.util.AttributeSet;
import android.util.Log;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.testing.TestProtocol;
@@ -67,7 +71,6 @@
@Override
public void startHome() {
mActivity.startHome();
- mActivity.getStateManager().goToState(RecentsState.HOME);
}
/**
@@ -86,14 +89,17 @@
* to the center.
*/
@Override
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
- super.onGestureEndTargetCalculated(endTarget);
- if (mHomeTaskInfo != null && endTarget == RECENTS) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ super.onPrepareGestureEndAnimation(animatorSet, endTarget);
+ if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
TaskView tv = getTaskView(mHomeTaskInfo.taskId);
if (tv != null) {
PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150);
pa.addEndListener(e -> setCurrentTask(-1));
- runDismissAnimation(pa);
+ AnimatorPlaybackController controller = pa.createPlaybackController();
+ controller.dispatchOnStart();
+ animatorSet.play(controller.getAnimationPlayer());
}
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index b3d6cfa..b6cfdce 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -39,15 +39,18 @@
private static final int FLAG_OVERVIEW_ACTIONS = BaseState.getFlag(3);
private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4);
private static final int FLAG_SCRIM = BaseState.getFlag(5);
+ private static final int FLAG_LIVE_TILE = BaseState.getFlag(6);
public static final RecentsState DEFAULT = new RecentsState(0,
- FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM
+ | FLAG_LIVE_TILE);
public static final RecentsState MODAL_TASK = new ModalState(1,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL
- | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE);
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN);
public static final RecentsState HOME = new RecentsState(3, 0);
+ public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
public final int ordinal;
private final int mFlags;
@@ -108,6 +111,13 @@
}
/**
+ * For this state, whether live tile should be shown.
+ */
+ public boolean hasLiveTile() {
+ return hasFlag(FLAG_LIVE_TILE);
+ }
+
+ /**
* For this state, what color scrim should be drawn behind overview.
*/
public int getScrimColor(RecentsActivity activity) {
@@ -152,4 +162,15 @@
return getOverviewScaleAndOffsetForBackgroundState(activity);
}
}
+
+ private static class LauncherState extends RecentsState {
+ LauncherState(int id, int flags) {
+ super(id, flags);
+ }
+
+ @Override
+ public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
+ return new float[] { NO_SCALE, 1 };
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
index d7458d2..273d1f6 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.fallback;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
+
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.quickstep.RecentsActivity;
@@ -26,7 +28,8 @@
@Override
protected boolean isRecentsInteractive() {
- return mActivity.hasWindowFocus();
+ return mActivity.hasWindowFocus() || (LIVE_TILE.get()
+ && mActivity.getStateManager().getState().hasLiveTile());
}
@Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 9c64794..fcc0217 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -116,7 +116,7 @@
R.dimen.device_locked_y_offset);
// Do not use DeviceProfile as the user data might be locked
- mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
// Init states
mStateCallback = new MultiStateCallback(STATE_NAMES);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
index d82d43d..8d9c524 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
@@ -70,7 +70,7 @@
mDragDistThreshold = context.getResources().getDimensionPixelSize(
R.dimen.gestures_onehanded_drag_threshold);
mSquaredSlop = Utilities.squaredTouchSlop(context);
- mDisplaySize = DisplayController.INSTANCE.get(mContext).getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
mNavBarSize = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE,
mContext.getResources());
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
new file mode 100644
index 0000000..76f43c9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2021 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.quickstep.interaction;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+import java.net.URISyntaxException;
+
+/**
+ * A page shows after SUW flow to hint users to swipe up from the bottom of the screen to go home
+ * for the gestural system navigation.
+ */
+public class AllSetActivity extends Activity {
+
+ private static final String LOG_TAG = "AllSetActivity";
+ private static final String URI_SYSTEM_NAVIGATION_SETTING =
+ "#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end";
+ private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "accent_color_dark_mode";
+ private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "accent_color_light_mode";
+
+ private int mAccentColor;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_allset);
+ setTitle(R.string.allset_title);
+
+ final int mode =
+ getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ mAccentColor = getIntent().getIntExtra(
+ mode == Configuration.UI_MODE_NIGHT_YES
+ ? EXTRA_ACCENT_COLOR_DARK_MODE : EXTRA_ACCENT_COLOR_LIGHT_MODE,
+ /* defValue= */ Color.BLACK);
+
+ ((ImageView) findViewById(R.id.icon)).getDrawable().mutate().setTint(mAccentColor);
+
+ TextView navigationSettings = findViewById(R.id.navigation_settings);
+ navigationSettings.setMovementMethod(LinkMovementMethod.getInstance());
+ AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+ AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION,
+ new AllSetLinkSpan(
+ /* context= */ this,
+ view -> {
+ try {
+ startActivityForResult(
+ Intent.parseUri(URI_SYSTEM_NAVIGATION_SETTING, 0), 0);
+ } catch (URISyntaxException e) {
+ Log.e(LOG_TAG, "Failed to parse system nav settings intent", e);
+ }
+ finish();
+ }));
+ navigationSettings.setText(
+ AnnotationSpan.linkify(getText(R.string.allset_navigation_settings), linkInfo));
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus) {
+ hideSystemUI();
+ }
+ }
+
+ private void hideSystemUI() {
+ getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN);
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
+ }
+
+ private final class AllSetLinkSpan extends AnnotationSpan {
+
+ private final String mFontFamily;
+ private final int mTextSize;
+
+ AllSetLinkSpan(Context context, View.OnClickListener listener) {
+ super(listener);
+ TypedArray typedArray =
+ context.obtainStyledAttributes(R.style.TextAppearance_GestureTutorial_LinkText,
+ R.styleable.AllSetLinkSpan);
+ mFontFamily = typedArray.getString(R.styleable.AllSetLinkSpan_android_fontFamily);
+ mTextSize =
+ typedArray.getDimensionPixelSize(
+ R.styleable.AllSetLinkSpan_android_textSize, /* defValue= */ -1);
+ typedArray.recycle();
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setColor(mAccentColor);
+ ds.setTypeface(Typeface.create(mFontFamily, Typeface.NORMAL));
+ ds.setUnderlineText(false);
+ if (mTextSize != -1) {
+ ds.setTextSize(mTextSize);
+ }
+ }
+ }
+
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
new file mode 100644
index 0000000..fea5078
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.interaction;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.text.Annotation;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.style.URLSpan;
+import android.util.Log;
+import android.view.View;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * This class is used to add {@link View.OnClickListener} for the text been wrapped by
+ * annotation.
+ *
+ * Copied from packages/apps/Settings/src/com/android/settings/utils/AnnotationSpan.java.
+ */
+public class AnnotationSpan extends URLSpan {
+
+ private final View.OnClickListener mClickListener;
+
+ AnnotationSpan(View.OnClickListener lsn) {
+ super((String) null);
+ mClickListener = lsn;
+ }
+
+ @Override
+ public void onClick(View widget) {
+ if (mClickListener != null) {
+ mClickListener.onClick(widget);
+ }
+ }
+
+ public static CharSequence linkify(CharSequence rawText, LinkInfo... linkInfos) {
+ SpannableString msg = new SpannableString(rawText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(msg);
+ for (Annotation annotation : spans) {
+ final String key = annotation.getValue();
+ int start = msg.getSpanStart(annotation);
+ int end = msg.getSpanEnd(annotation);
+ AnnotationSpan link = null;
+ for (LinkInfo linkInfo : linkInfos) {
+ if (linkInfo.mAnnotation.equals(key)) {
+ link = linkInfo.mCustomizedSpan != null ? linkInfo.mCustomizedSpan
+ : new AnnotationSpan(linkInfo.mClickListener);
+ break;
+ }
+ }
+ if (link != null) {
+ builder.setSpan(link, start, end, msg.getSpanFlags(link));
+ }
+ }
+ return builder;
+ }
+
+ /**
+ * get the text part without having text for link part
+ */
+ public static CharSequence textWithoutLink(CharSequence encodedText) {
+ SpannableString msg = new SpannableString(encodedText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ if (spans == null) {
+ return encodedText;
+ }
+ Arrays.sort(spans, Comparator.comparingInt(span -> -msg.getSpanStart(span)));
+ StringBuilder msgWithoutLink = new StringBuilder(msg.toString());
+ for (Annotation span : spans) {
+ msgWithoutLink.delete(msg.getSpanStart(span), msg.getSpanEnd(span));
+ }
+ return msgWithoutLink.toString();
+ }
+
+ /** Data class to store the annotation and the click action. */
+ public static class LinkInfo {
+ public static final String DEFAULT_ANNOTATION = "link";
+ private static final String TAG = "AnnotationSpan.LinkInfo";
+ private final String mAnnotation;
+ private final Boolean mActionable;
+ private final View.OnClickListener mClickListener;
+ private final AnnotationSpan mCustomizedSpan;
+
+ public LinkInfo(String annotation, View.OnClickListener listener) {
+ mAnnotation = annotation;
+ mClickListener = listener;
+ mActionable = true; // assume actionable
+ mCustomizedSpan = null;
+ }
+
+ public LinkInfo(String annotation, AnnotationSpan customizedSpan) {
+ mAnnotation = annotation;
+ mClickListener = null;
+ mActionable = customizedSpan != null;
+ mCustomizedSpan = customizedSpan;
+ }
+
+ public LinkInfo(Context context, String annotation, Intent intent) {
+ mAnnotation = annotation;
+ mCustomizedSpan = null;
+ if (intent != null) {
+ mActionable = context.getPackageManager().resolveActivity(intent, 0) != null;
+ } else {
+ mActionable = false;
+ }
+ if (mActionable) {
+ mClickListener =
+ view -> {
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity was not found for intent, " + intent);
+ }
+ };
+ } else {
+ mClickListener = null;
+ }
+ }
+
+ public boolean isActionable() {
+ return mActionable;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index c396eec..14c3a92 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -20,9 +20,7 @@
import static com.android.quickstep.interaction.TutorialController.TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
import android.graphics.PointF;
-import android.view.View;
-import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import com.android.launcher3.R;
@@ -36,11 +34,6 @@
super(fragment, tutorialType);
}
- @Nullable
- public View getMockLauncherView() {
- return null;
- }
-
@Override
public Integer getIntroductionTitle() {
return mTutorialType == LEFT_EDGE_BACK_NAVIGATION
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 3c59ed3..06610e6 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -16,15 +16,11 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.quickstep.interaction.TutorialController.TutorialType.OVERVIEW_NAVIGATION_COMPLETE;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.graphics.PointF;
import android.os.Build;
-import android.view.View;
-
-import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
@@ -52,12 +48,6 @@
return R.string.overview_gesture_intro_subtitle;
}
- @Nullable
- @Override
- public View getMockLauncherView() {
- return null;
- }
-
@Override
public void onBackGestureAttempted(BackGestureResult result) {
switch (mTutorialType) {
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java b/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
deleted file mode 100644
index 80ffe66..0000000
--- a/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.interaction;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.graphics.LauncherPreviewRenderer;
-
-/** Renders a fake Launcher for use in the Sandbox. */
-class SandboxLauncherRenderer extends LauncherPreviewRenderer {
- SandboxLauncherRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
- super(context, idp, migrated);
- }
-
- @Override
- public boolean shouldShowRealLauncherPreview() {
- return false;
- }
-
- @Override
- public boolean shouldShowQsb() {
- return false;
- }
-
- @Override
- public View.OnLongClickListener getWorkspaceChildOnLongClickListener() {
- return null;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 6f82f85..55972ad 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -37,7 +37,6 @@
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.views.ClipIconView;
@@ -129,13 +128,6 @@
return R.drawable.default_sandbox_app_previous_task_thumbnail;
}
- @Nullable
- public View getMockLauncherView() {
- InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext);
-
- return new SandboxLauncherRenderer(mContext, dp, true).getRenderedView();
- }
-
@DrawableRes
public int getMockAppIconResId() {
return R.drawable.default_sandbox_app_icon;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 66c24c8..3b26108 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -84,6 +84,7 @@
private static final int FOLDER_HIERARCHY_OFFSET = 100;
private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
private static final int EXTENDED_CONTAINERS_HIERARCHY_OFFSET = 300;
+ private static final int ATTRIBUTE_MULTIPLIER = 100;
public static final CopyOnWriteArrayList<StatsLogConsumer> LOGS_CONSUMER =
new CopyOnWriteArrayList<>();
@@ -112,7 +113,8 @@
}
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
LAUNCHER_WORKSPACE_SNAPSHOT.getId() /* event_id */,
- info.getItemCase().getNumber() /* target_id */,
+ info.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
+ + info.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id */,
0 /* uid */,
getPackageName(info) /* package_name */,
@@ -329,7 +331,8 @@
null /* launcher extensions, deprecated */,
false /* quickstep_enabled, deprecated */,
event.getId() /* event_id */,
- atomInfo.getItemCase().getNumber() /* target_id */,
+ atomInfo.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
+ + atomInfo.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id TODO */,
0 /* uid TODO */,
getPackageName(atomInfo) /* package_name */,
diff --git a/quickstep/src/com/android/quickstep/util/AssistContentRequester.java b/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
index 3730284..71c6382 100644
--- a/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
+++ b/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
@@ -28,6 +28,10 @@
import com.android.launcher3.util.Executors;
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
import java.util.concurrent.Executor;
/**
@@ -51,6 +55,10 @@
private final String mPackageName;
private final Executor mCallbackExecutor;
+ // If system loses the callback, our internal cache of original callback will also get cleared.
+ private final Map<Object, Callback> mPendingCallbacks =
+ Collections.synchronizedMap(new WeakHashMap<>());
+
public AssistContentRequester(Context context) {
mActivityTaskManager = ActivityTaskManager.getService();
mPackageName = context.getApplicationContext().getPackageName();
@@ -66,20 +74,28 @@
public void requestAssistContent(int taskId, Callback callback) {
try {
mActivityTaskManager.requestAssistDataForTask(
- new AssistDataReceiver(callback, mCallbackExecutor), taskId, mPackageName);
+ new AssistDataReceiver(callback, this), taskId, mPackageName);
} catch (RemoteException e) {
Log.e(TAG, "Requesting assist content failed for task: " + taskId, e);
}
}
+ private void executeOnMainExecutor(Runnable callback) {
+ mCallbackExecutor.execute(callback);
+ }
+
private static final class AssistDataReceiver extends IAssistDataReceiver.Stub {
- private final Executor mExecutor;
- private final Callback mCallback;
+ // The AssistDataReceiver binder callback object is passed to a system server, that may
+ // keep hold of it for longer than the lifetime of the AssistContentRequester object,
+ // potentially causing a memory leak. In the callback passed to the system server, only
+ // keep a weak reference to the parent object and lookup its callback if it still exists.
+ private final WeakReference<AssistContentRequester> mParentRef;
+ private final Object mCallbackKey = new Object();
- AssistDataReceiver(Callback callback, Executor callbackExecutor) {
- mCallback = callback;
- mExecutor = callbackExecutor;
+ AssistDataReceiver(Callback callback, AssistContentRequester parent) {
+ parent.mPendingCallbacks.put(mCallbackKey, callback);
+ mParentRef = new WeakReference<>(parent);
}
@Override
@@ -94,7 +110,18 @@
return;
}
- mExecutor.execute(() -> mCallback.onAssistContentAvailable(content));
+ AssistContentRequester requester = mParentRef.get();
+ if (requester != null) {
+ Callback callback = requester.mPendingCallbacks.get(mCallbackKey);
+ if (callback != null) {
+ requester.executeOnMainExecutor(
+ () -> callback.onAssistContentAvailable(content));
+ } else {
+ Log.d(TAG, "Callback received after calling UI was disposed of");
+ }
+ } else {
+ Log.d(TAG, "Callback received after Requester was collected");
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
index c527be3..60c7add 100644
--- a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
+++ b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
@@ -20,8 +20,6 @@
import android.content.Context;
-import com.android.quickstep.OverviewComponentObserver;
-import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SysUINavigationMode;
import java.util.function.Predicate;
@@ -37,7 +35,6 @@
private final Supplier<Boolean> mBasePredicate;
private final Predicate<SysUINavigationMode.Mode> mModePredicate;
private boolean mSupported;
- private OverviewComponentObserver mObserver;
private NavigationModeFeatureFlag(Supplier<Boolean> basePredicate,
Predicate<SysUINavigationMode.Mode> modePredicate) {
@@ -46,17 +43,12 @@
}
public boolean get() {
- return mBasePredicate.get() && mSupported && mObserver != null
- && mObserver.isHomeAndOverviewSame();
+ return mBasePredicate.get() && mSupported;
}
public void initialize(Context context) {
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context).getMode());
SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
-
- // Temporary solution to disable live tile for the fallback launcher
- RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(context);
- mObserver = new OverviewComponentObserver(context, rads);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
index 1128dac..42be9bb 100644
--- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
+++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
@@ -20,7 +20,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
@@ -109,7 +109,7 @@
? clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f) : FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, INSTANT);
+ config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR);
if (!isLayoutNaturalToLauncher) {
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL);
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 188efad..d164c8c 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -33,6 +33,7 @@
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.Log;
@@ -49,6 +50,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface;
@@ -561,11 +563,27 @@
*/
public DeviceProfile getLauncherDeviceProfile() {
InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(mContext);
- // TODO also check the natural orientation is landscape or portrait
- return (mRecentsActivityRotation == ROTATION_90
- || mRecentsActivityRotation == ROTATION_270)
- ? idp.landscapeProfile
- : idp.portraitProfile;
+ Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
+
+ int width, height;
+ if ((mRecentsActivityRotation == ROTATION_90 || mRecentsActivityRotation == ROTATION_270)) {
+ width = Math.max(currentSize.x, currentSize.y);
+ height = Math.min(currentSize.x, currentSize.y);
+ } else {
+ width = Math.min(currentSize.x, currentSize.y);
+ height = Math.max(currentSize.x, currentSize.y);
+ }
+
+ DeviceProfile bestMatch = idp.supportedProfiles.get(0);
+ float minDiff = Float.MAX_VALUE;
+ for (DeviceProfile profile : idp.supportedProfiles) {
+ float diff = Math.abs(profile.widthPx - width) + Math.abs(profile.heightPx - height);
+ if (diff < minDiff) {
+ minDiff = diff;
+ bestMatch = profile;
+ }
+ }
+ return bestMatch;
}
private static String nameAndAddress(Object obj) {
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
index 88cc650..483a1c6 100644
--- a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
@@ -20,10 +20,7 @@
import android.annotation.TargetApi;
import android.content.Context;
-import android.graphics.Insets;
-import android.graphics.Rect;
import android.os.Build;
-import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowMetrics;
@@ -73,10 +70,8 @@
*/
private static WindowBounds createDefaultWindowBounds(Context context) {
WindowMetrics wm = context.getSystemService(WindowManager.class).getMaximumWindowMetrics();
- Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
+ WindowBounds bounds = WindowBounds.fromWindowMetrics(wm);
- WindowBounds bounds = new WindowBounds(wm.getBounds(),
- new Rect(insets.left, insets.top, insets.right, insets.bottom));
int rotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
int halfDividerSize = context.getResources()
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index e63f8bb..f578ad1 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -36,6 +36,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
@@ -95,7 +96,9 @@
mContext = context;
mSizeStrategy = sizeStrategy;
- mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
+ // TODO(b/187074722): Don't create this per-TaskViewSimulator
+ mOrientationState = TraceHelper.allowIpcs("",
+ () -> new RecentsOrientedState(context, sizeStrategy, i -> { }));
mOrientationState.setGestureActive(true);
mCurrentFullscreenParams = new FullscreenDrawParams(context);
mOrientationStateId = mOrientationState.getStateId();
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index f74aa55..9ea2369 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -100,8 +100,8 @@
/** Restores the drawables to the source view. */
void finish() {
if (isUninitialized()) return;
- mSourceView.setForeground(mOriginalForeground);
- mSourceView.setBackground(mOriginalBackground);
+ if (mOriginalForeground != null) mSourceView.setForeground(mOriginalForeground);
+ if (mOriginalBackground != null) mSourceView.setBackground(mOriginalBackground);
}
void recycle() {
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index d23884c..ed54f10 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -20,13 +20,14 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Matrix;
-import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
+import android.util.Size;
import android.view.GhostView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
import com.android.launcher3.Launcher;
@@ -39,7 +40,8 @@
/** A view that mimics an App Widget through a launch animation. */
@TargetApi(Build.VERSION_CODES.S)
-public class FloatingWidgetView extends FrameLayout implements AnimatorListener {
+public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
+ OnGlobalLayoutListener {
private static final Matrix sTmpMatrix = new Matrix();
private final Launcher mLauncher;
@@ -54,6 +56,7 @@
private Runnable mEndRunnable;
private Runnable mFastFinishRunnable;
+ private Runnable mOnTargetChangeRunnable;
public FloatingWidgetView(Context context) {
this(context, null);
@@ -93,6 +96,32 @@
public void onAnimationRepeat(Animator animator) {
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnGlobalLayoutListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ if (isUninitialized()) return;
+ positionViews();
+ if (mOnTargetChangeRunnable != null) {
+ mOnTargetChangeRunnable.run();
+ }
+ }
+
+ /** Sets a runnable that is called on global layout change. */
+ public void setOnTargetChangeListener(Runnable onTargetChangeListener) {
+ mOnTargetChangeRunnable = onTargetChangeListener;
+ }
+
/** Sets a runnable that is called after a call to {@link #fastFinish()}. */
public void setFastFinishRunnable(Runnable runnable) {
mFastFinishRunnable = runnable;
@@ -113,7 +142,7 @@
}
private void init(DragLayer dragLayer, LauncherAppWidgetHostView originalView,
- RectF widgetBackgroundPosition, Rect windowTargetBounds, float windowCornerRadius) {
+ RectF widgetBackgroundPosition, Size windowSize, float windowCornerRadius) {
mAppWidgetView = originalView;
mAppWidgetView.beginDeferringUpdates();
mBackgroundPosition = widgetBackgroundPosition;
@@ -128,7 +157,7 @@
getRelativePosition(mAppWidgetBackgroundView, mAppWidgetView, mBackgroundOffset);
mBackgroundView.init(mAppWidgetView, mAppWidgetBackgroundView, windowCornerRadius);
// Layout call before GhostView creation so that the overlaid view isn't clipped
- layout(0, 0, windowTargetBounds.width(), windowTargetBounds.height());
+ layout(0, 0, windowSize.getWidth(), windowSize.getHeight());
mForegroundOverlayView = GhostView.addGhost(mAppWidgetView, this);
positionViews();
@@ -205,6 +234,7 @@
private void recycle() {
mEndRunnable = null;
mFastFinishRunnable = null;
+ mOnTargetChangeRunnable = null;
mBackgroundPosition = null;
mListenerView.setListener(null);
mAppWidgetView = null;
@@ -219,19 +249,19 @@
*
* @param widgetBackgroundPosition a {@link RectF} that will be updated with the widget's
* background bounds
- * @param windowTargetBounds the bounds of the window when launched
+ * @param windowSize the size of the window when launched
* @param windowCornerRadius the corner radius of the window
*/
public static FloatingWidgetView getFloatingWidgetView(Launcher launcher,
LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition,
- Rect windowTargetBounds, float windowCornerRadius) {
+ Size windowSize, float windowCornerRadius) {
final DragLayer dragLayer = launcher.getDragLayer();
ViewGroup parent = (ViewGroup) dragLayer.getParent();
FloatingWidgetView floatingView =
launcher.getViewCache().getView(R.layout.floating_widget_view, launcher, parent);
floatingView.recycle();
- floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowTargetBounds,
+ floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowSize,
windowCornerRadius);
parent.addView(floatingView);
return floatingView;
@@ -240,7 +270,7 @@
private static void getRelativePosition(View descendant, View ancestor, RectF position) {
float[] points = new float[]{0, 0, descendant.getWidth(), descendant.getHeight()};
Utilities.getDescendantCoordRelativeToAncestor(descendant, ancestor, points,
- false /* includeRootScroll */);
+ false /* includeRootScroll */, true /* ignoreTransform */);
position.set(
Math.min(points[0], points[2]),
Math.min(points[1], points[3]),
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e5ce950..9797afd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -699,11 +699,6 @@
return taskView;
}
- /** See {@link #updateThumbnail(int, ThumbnailData, boolean)} */
- public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData) {
- return updateThumbnail(taskId, thumbnailData, true /* refreshNow */);
- }
-
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
@@ -1636,7 +1631,16 @@
/**
* Called when a gesture from an app has finished, and an end target has been determined.
*/
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ if (mSizeStrategy.stateFromGestureEndTarget(endTarget)
+ .displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
+ if (animatorSet == null) {
+ setGridProgress(1);
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
+ }
+ }
mCurrentGestureEndTarget = endTarget;
if (endTarget == GestureState.GestureEndTarget.NEW_TASK
|| endTarget == GestureState.GestureEndTarget.LAST_TASK) {
@@ -2254,7 +2258,8 @@
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
- if (LIVE_TILE.get() && taskView.isRunningTask() && success) {
+ if (LIVE_TILE.get() && mEnableDrawingLiveTile && taskView.isRunningTask()
+ && success) {
finishRecentsAnimation(true /* toHome */, () -> onEnd(success));
} else {
onEnd(success);
@@ -2352,7 +2357,7 @@
return true;
}
- protected void runDismissAnimation(PendingAnimation pendingAnim) {
+ private void runDismissAnimation(PendingAnimation pendingAnim) {
AnimatorPlaybackController controller = pendingAnim.createPlaybackController();
controller.dispatchOnStart();
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index f55cdac..32cd367 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -201,12 +201,13 @@
}
private void addMenuOption(SystemShortcut menuOption) {
- ViewGroup menuOptionView = (ViewGroup) mActivity.getLayoutInflater().inflate(
+ LinearLayout menuOptionView = (LinearLayout) mActivity.getLayoutInflater().inflate(
R.layout.task_view_menu_option, this, false);
menuOption.setIconAndLabelFor(
menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
- mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp);
+ mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp,
+ menuOptionView, mActivity.getDeviceProfile());
menuOptionView.setEnabled(menuOption.isEnabled());
menuOptionView.setAlpha(menuOption.isEnabled() ? 1 : 0.5f);
menuOptionView.setOnClickListener(view -> {
@@ -228,16 +229,15 @@
mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
+ // TODO(b/186583656) Move the entire menu to the center/make smaller than thumbnail width
params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail());
// Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
params.gravity = Gravity.LEFT;
setLayoutParams(params);
setScaleX(taskView.getScaleX());
setScaleY(taskView.getScaleY());
- boolean canActivityRotate = taskView.getRecentsView()
- .mOrientationState.isRecentsActivityRotationAllowed();
- mOptionLayout.setOrientation(orientationHandler
- .getTaskMenuLayoutOrientation(canActivityRotate, mOptionLayout));
+ orientationHandler.setTaskMenuLayoutOrientation(
+ mActivity.getDeviceProfile(), mOptionLayout);
setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 3349b74..99a8049 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -553,6 +553,7 @@
@Override
public void onAnimationEnd(Animator animator) {
+ recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(true);
mIsClickableAsLiveTile = true;
}
});
@@ -777,8 +778,7 @@
float upperClamp = invert ? 1 : iconScalePercentage;
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
.getInterpolation(progress);
- mIconView.setScaleX(scale);
- mIconView.setScaleY(scale);
+ mIconView.setAlpha(scale);
if (mContextualChipWrapper != null && mContextualChipWrapper != null) {
mContextualChipWrapper.setAlpha(scale);
mContextualChipWrapper.setScaleX(Math.min(scale, comp(mModalness)));
@@ -1418,9 +1418,10 @@
}
private void setColorTint(float amount) {
- mSnapshotView.setDimAlpha(amount);
- mIconView.setIconColorTint(mTintingColor, amount);
- mDigitalWellBeingToast.setBannerColorTint(mTintingColor, amount);
+ mTintAmount = amount;
+ mSnapshotView.setDimAlpha(mTintAmount);
+ mIconView.setIconColorTint(mTintingColor, mTintAmount);
+ mDigitalWellBeingToast.setBannerColorTint(mTintingColor, mTintAmount);
}
private float getColorTint() {
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 88f1850..f93d87c 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -61,6 +61,7 @@
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.quickstep.views.RecentsView;
+import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@@ -141,6 +142,12 @@
}
}
+ @After
+ public void verifyLauncherState() {
+ // Limits UI tests affecting tests running after them.
+ AbstractQuickStepTest.checkDetectedLeaks(mLauncher);
+ }
+
// b/143488140
//@NavigationModeSwitch
@Test
diff --git a/res/color/arrow_tip_view_bg.xml b/res/color/arrow_tip_view_bg.xml
new file mode 100644
index 0000000..91eed50
--- /dev/null
+++ b/res/color/arrow_tip_view_bg.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2021, 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.
+*/
+-->
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="?android:attr/colorAccent" />
+</selector>
diff --git a/res/color/arrow_tip_view_content.xml b/res/color/arrow_tip_view_content.xml
new file mode 100644
index 0000000..87c733e
--- /dev/null
+++ b/res/color/arrow_tip_view_content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2021, 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.
+*/
+-->
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/white" />
+</selector>
diff --git a/res/color/cell_layout_bg_color_active.xml b/res/color/cell_layout_bg_color_active.xml
index e826489..d1a3d7c 100644
--- a/res/color/cell_layout_bg_color_active.xml
+++ b/res/color/cell_layout_bg_color_active.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:alpha="0.4"
+ <item android:alpha="0.3"
android:color="?android:attr/colorAccent"/>
</selector>
diff --git a/res/color/cell_layout_bg_color_inactive.xml b/res/color/cell_layout_bg_color_inactive.xml
index d60a27a..0632100 100644
--- a/res/color/cell_layout_bg_color_inactive.xml
+++ b/res/color/cell_layout_bg_color_inactive.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:alpha="0.3"
+ <item android:alpha="0.25"
android:color="?android:attr/colorAccent"/>
</selector>
\ No newline at end of file
diff --git a/res/drawable/arrow_toast_rounded_background.xml b/res/drawable/arrow_toast_rounded_background.xml
index 52cc6fc..f3f2158 100644
--- a/res/drawable/arrow_toast_rounded_background.xml
+++ b/res/drawable/arrow_toast_rounded_background.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
- <solid android:color="?android:attr/colorAccent" />
+ <solid android:color="@color/arrow_tip_view_bg" />
<corners android:radius="8dp" />
</shape>
diff --git a/res/drawable/bg_widgets_searchbox.xml b/res/drawable/bg_widgets_searchbox.xml
index 2a50a51..3230ac8 100644
--- a/res/drawable/bg_widgets_searchbox.xml
+++ b/res/drawable/bg_widgets_searchbox.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
- <solid android:color="?android:attr/textColorPrimaryInverse" />
+ <solid android:color="@color/widgets_picker_surface" />
<corners android:radius="24dp" />
</shape>
\ No newline at end of file
diff --git a/res/drawable/top_round_rect_primary.xml b/res/drawable/drop_target_frame.xml
similarity index 64%
copy from res/drawable/top_round_rect_primary.xml
copy to res/drawable/drop_target_frame.xml
index 1caaa02..fa6dafd 100644
--- a/res/drawable/top_round_rect_primary.xml
+++ b/res/drawable/drop_target_frame.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2018 The Android Open Source Project
+ Copyright (C) 2021 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.
@@ -15,12 +15,8 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorPrimary" />
- <corners
- android:topLeftRadius="@dimen/bg_round_rect_radius"
- android:topRightRadius="@dimen/bg_round_rect_radius"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"
- />
-</shape>
+ android:shape="rectangle">
+ <solid android:color="@android:color/transparent" />
+ <corners android:radius="28dp" />
+ <stroke android:width="2dp" android:color="?android:attr/colorAccent" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/top_round_rect_primary.xml b/res/drawable/drop_target_frame_hover.xml
similarity index 64%
copy from res/drawable/top_round_rect_primary.xml
copy to res/drawable/drop_target_frame_hover.xml
index 1caaa02..7d0e919 100644
--- a/res/drawable/top_round_rect_primary.xml
+++ b/res/drawable/drop_target_frame_hover.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2018 The Android Open Source Project
+ Copyright (C) 2021 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.
@@ -15,12 +15,7 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorPrimary" />
- <corners
- android:topLeftRadius="@dimen/bg_round_rect_radius"
- android:topRightRadius="@dimen/bg_round_rect_radius"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"
- />
-</shape>
+ android:shape="rectangle">
+ <solid android:color="?android:attr/colorAccent" />
+ <corners android:radius="28dp" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_block_no_shadow.xml b/res/drawable/ic_block_no_shadow.xml
index edeb4c6..be9aa07 100644
--- a/res/drawable/ic_block_no_shadow.xml
+++ b/res/drawable/ic_block_no_shadow.xml
@@ -14,10 +14,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportHeight="20.0"
+ android:viewportWidth="20.0"
android:tint="?android:attr/textColorPrimary">
<path
android:fillColor="@android:color/white"
diff --git a/res/drawable/ic_conversations_widget_category.xml b/res/drawable/ic_conversations_widget_category.xml
new file mode 100644
index 0000000..7b13b23
--- /dev/null
+++ b/res/drawable/ic_conversations_widget_category.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:pathData="M24,24m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"
+ android:fillColor="#81C995"/>
+ <path
+ android:pathData="M27,34C23.134,34 20,30.866 20,27C20,23.134 23.134,20 27,20C30.866,20 34,23.134 34,27C34,28.4872 33.5362,29.8662 32.7453,31"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#3C4043"/>
+ <path
+ android:pathData="M35,33l-8,0l-0,2l8,0z"
+ android:fillColor="#3C4043"/>
+ <path
+ android:pathData="M21,21m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0"
+ android:fillColor="#81C995"/>
+ <path
+ android:pathData="M16,25h5v2h-5z"
+ android:fillColor="#81C995"/>
+ <path
+ android:pathData="M21,28C24.866,28 28,24.866 28,21C28,17.134 24.866,14 21,14C17.134,14 14,17.134 14,21C14,22.4872 14.4638,23.8662 15.2547,25"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#ffffff"/>
+ <path
+ android:pathData="M13,27h8v2h-8z"
+ android:fillColor="#ffffff"/>
+</vector>
diff --git a/res/drawable/ic_remove_no_shadow.xml b/res/drawable/ic_remove_no_shadow.xml
index 2c706db..10f1e43 100644
--- a/res/drawable/ic_remove_no_shadow.xml
+++ b/res/drawable/ic_remove_no_shadow.xml
@@ -14,8 +14,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="20dp"
+ android:height="20dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
android:tint="?android:attr/textColorPrimary">
diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml
index 6aff102..14cecac 100644
--- a/res/drawable/ic_uninstall_no_shadow.xml
+++ b/res/drawable/ic_uninstall_no_shadow.xml
@@ -14,10 +14,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="20.0"
+ android:viewportHeight="20.0"
android:tint="?android:attr/textColorPrimary" >
<path
android:fillColor="@android:color/white"
diff --git a/res/drawable/top_round_rect_primary.xml b/res/drawable/widgets_bottom_sheet_background.xml
similarity index 85%
rename from res/drawable/top_round_rect_primary.xml
rename to res/drawable/widgets_bottom_sheet_background.xml
index 1caaa02..faa414c 100644
--- a/res/drawable/top_round_rect_primary.xml
+++ b/res/drawable/widgets_bottom_sheet_background.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2018 The Android Open Source Project
+ Copyright (C) 2021 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.
@@ -15,12 +15,12 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?android:attr/colorPrimary" />
+ android:shape="rectangle">
+ <solid android:color="@color/widgets_picker_surface" />
<corners
android:topLeftRadius="@dimen/bg_round_rect_radius"
android:topRightRadius="@dimen/bg_round_rect_radius"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
/>
-</shape>
+</shape>
\ No newline at end of file
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index d5e7333..7c2f25b 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -36,6 +36,15 @@
android:singleLine="true"
android:maxLines="1" />
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:paddingVertical="8dp"
+ android:text="@string/add_item_request_drag_hint"
+ android:textSize="14sp"
+ android:importantForAccessibility="no"/>
+
<include layout="@layout/widget_cell"
android:id="@+id/widget_cell"
android:layout_width="match_parent"
@@ -53,6 +62,7 @@
style="@style/Widget.DeviceDefault.Button.Rounded.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingHorizontal="16dp"
android:onClick="onCancelClick"
android:text="@android:string/cancel" />
@@ -64,7 +74,8 @@
style="@style/Widget.DeviceDefault.Button.Rounded.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingHorizontal="16dp"
android:onClick="onPlaceAutomaticallyClick"
- android:text="@string/place_automatically" />
+ android:text="@string/add_to_home_screen" />
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/arrow_toast.xml b/res/layout/arrow_toast.xml
index 0ec9981..ae60e1b 100644
--- a/res/layout/arrow_toast.xml
+++ b/res/layout/arrow_toast.xml
@@ -16,6 +16,7 @@
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
@@ -38,7 +39,7 @@
android:paddingBottom="5dp"
android:gravity="center"
android:layout_gravity="center_vertical"
- android:textColor="@android:color/white"
+ android:textColor="@color/arrow_tip_view_content"
android:textSize="16sp"/>
<ImageView
android:id="@+id/dismiss"
@@ -50,7 +51,7 @@
android:layout_marginEnd="2dp"
android:alpha="0.7"
android:src="@drawable/ic_remove_no_shadow"
- android:tint="@android:color/white"
+ android:tint="@color/arrow_tip_view_content"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/accessibility_close"/>
</LinearLayout>
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index 8002d1d..08635c6 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
- android:background="@drawable/top_round_rect_primary"
+ android:background="@drawable/widgets_bottom_sheet_background"
android:elevation="@dimen/deep_shortcuts_elevation"
android:layout_gravity="bottom"
android:theme="?attr/widgetsTheme">
diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml
index c3dd19e..2467156 100644
--- a/res/layout/widgets_search_bar.xml
+++ b/res/layout/widgets_search_bar.xml
@@ -6,6 +6,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="16dp"
+ android:layout_marginBottom="1dp"
android:background="@drawable/bg_widgets_searchbox"
android:elevation="2dp">
@@ -24,8 +25,8 @@
android:layout_weight="1"
android:inputType="text"
android:imeOptions="actionSearch"
- android:textColor="?android:attr/textColorSecondary"
- android:textColorHint="?android:attr/textColorTertiary"/>
+ android:textColor="?android:attr/textColorPrimary"
+ android:textColorHint="?android:attr/textColorSecondary"/>
<ImageButton
android:id="@+id/widgets_search_cancel_button"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 6894e3c..c6d372a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en hou om \'n legstuk te skuif of gebruik gepasmaakte handelinge."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Raak en hou om self te plaas"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Voeg outomaties by"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Raak en hou die legstuk om dit op die Tuisskerm rond te beweeg"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Voeg by Tuisskerm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> legstukke</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> legstuk</item>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 8097ba1..7123a8b 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ምግብርን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ራስዎ ለማስቀመጥ ነክተው ይያዙት"</string>
- <string name="place_automatically" msgid="8064208734425456485">"በራስ-ሰር አክል"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"በመነሻ ገጽ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ወደ መነሻ ገጽ አክል"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ንዑስ ፕሮግራሞች</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ንዑስ ፕሮግራሞች</item>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index b5115e2..c6ab52a 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"العرض %1$d الطول %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"انقر مع الاستمرار لإضافة العنصر يدويًا"</string>
- <string name="place_automatically" msgid="8064208734425456485">"الإضافة تلقائيًا"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"يمكنك النقر على الأداة مع الاستمرار لتحريكها على الشاشة الرئيسية."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"إضافة إلى الشاشة الرئيسية"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="zero"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> أداة</item>
<item quantity="two">أداتان (<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>)</item>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 31ac27f..5e80e65 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"কোনো ৱিজেট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d বহল x %2$d ওখ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"মেনুৱেলভাৱে ৰাখিবলৈ স্পৰ্শ কৰি থাকক"</string>
- <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্ৰিয়ভাবে যোগ কৰক"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ৱিজেটটো গৃহ স্ক্ৰীনৰ আশে-পাশে নিবলৈ সেইটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"গৃহ স্ক্ৰীনত যোগ কৰক"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> টা ৱিজেট</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> টা ৱিজেট</item>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index bc0717d..17f600c 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidceti daşımaq üçün iki dəfə toxunub saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Avtomatik əlavə edin"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Əsas ekranda hərəkət etdirmək üçün vidcetə toxunub saxlayın"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Əsas ekrana əlavə edin"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidcet</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> vidcet</item>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index ed08ca2..dc04fed 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da biste pomerali vidžet ili koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"širina od %1$d i visina od %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite da biste postavili ručno"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Automatski dodaj"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite vidžet da biste ga pomerali po početnom ekranu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžet</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžeta</item>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index c2d9946..9bb2c00 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Шырына: %1$d, вышыня: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Каб размясціць уручную, дакраніцеся і ўтрымлівайце"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Дадаць аўтаматычна"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Утрымліваючы віджэт націснутым, перамяшчайце яго па Галоўным экране"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Дадаць на Галоўны экран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджэт</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджэты</item>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 390a8f8..0d398ee 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d и височина %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Докоснете и задръжте, за да поставите ръчно"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Автоматично добавяне"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Докоснете приспособлението и го задръжте, за да го местите на началния екран"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Добавяне към началния екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> приспособления</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> приспособление</item>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 4c45b29..283ac70 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"নিজে যোগ করতে টাচ করে ধরে রাখুন"</string>
- <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্রিয়ভাবে যোগ করুন"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>টি উইজেট</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>টি উইজেট</item>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index ae46d5b..50aff80 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da pomjerite vidžet ili da koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i držite da postavite ručno"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i držite vidžet da ga pomjerate po Početnom ekranu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžet</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžeta</item>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index c49dce5..9ea5fc7 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Fes doble toc i mantén premut per moure un widget o per utilitzar accions personalitzades."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén-lo premut per afegir-lo manualment"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Afegeix automàticament"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premut el widget per moure\'l per la pantalla d\'inici"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Afegeix a la pantalla d\'inici"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a7f9908..9ae37cc 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chcete-li položku umístit ručně, klepněte na ni a podržte ji"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Přidat automaticky"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pokud widgetem chcete pohybovat po ploše, dotkněte se ho a podržte ho"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Přidat na plochu"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgety</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetu</item>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index c6496fa..3b4e07b 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryk to gange, og hold en widget nede for at flytte den eller bruge tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk og hold for at placere manuelt"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Tilføj automatisk"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Hold widgetten nede for at flytte den rundt på startskærmen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Føj til startskærm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 77ddc86..31b9b20 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Doppeltippen und halten, um ein Widget zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Zum manuellen Hinzufügen gedrückt halten"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Automatisch hinzufügen"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> Widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> Widget</item>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index c81b96a..1d93bfc 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Πλάτος %1$d επί ύψος %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Αγγίξτε παρατεταμένα για μη αυτόματη τοποθέτηση"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Αυτόματη προσθήκη"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Αγγίξτε παρατεταμένα το γραφικό στοιχείο για να το μετακινήσετε στην Αρχική οθόνη"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Προσθήκη στην Αρχική οθόνη"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> γραφικά στοιχεία</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> γραφικό στοιχείο</item>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index f26f284..d6b9296 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch and hold to place manually"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch & hold the widget to move it around the home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index f26f284..d6b9296 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch and hold to place manually"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch & hold the widget to move it around the home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f26f284..d6b9296 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch and hold to place manually"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch & hold the widget to move it around the home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index f26f284..d6b9296 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch and hold to place manually"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch & hold the widget to move it around the home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index b700502..9fff023 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch & hold to place manually"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch & hold the widget to move it around the Home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Add to Home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index acd4a4f..79d33fd 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Presiona dos veces y mantén presionado para mover un widget o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén presionado para ubicarlo manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Agregar automáticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén presionado el widget para moverlo por la pantalla principal"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Agregar a pantalla principal"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 8b9ab0c..1bc4c60 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantenlo pulsado para añadirlo manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Añadir automáticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén pulsado el widget para moverlo por la pantalla de inicio"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Añadir a la pantalla de inicio"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">Widgets: <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Widget: <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 08714ad..916aafc 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Puudutage pikalt, et käsitsi asetada"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Lisa automaatselt"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Vidina avakuval liigutamiseks puudutage vidinat ja hoidke all"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lisa avakuvale"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidinat</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> vidin</item>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index a485a14..901d3cb 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Sakatu birritan eta eduki sakatuta widget bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Eduki sakatuta eskuz gehitzeko"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Gehitu automatikoki"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Eduki sakatuta widgeta hasierako pantailan zehar mugitzeko"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Gehitu hasierako pantailan"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 0b3e7b0..194ea0d 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"برای جابهجا کردن ابزارک یا استفاده از کنشهای سفارشی، دوضربه بزنید و نگه دارید."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d عرض در %2$d طول"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"آن را لمس کنید و بکشید تا بهصورت دستی اضافه شود"</string>
- <string name="place_automatically" msgid="8064208734425456485">"افزودن خودکار"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ابزارک را لمس و کنید و نگه دارید تا آن را در صفحه اصلی حرکت دهید"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"افزودن به صفحه اصلی"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ابزارک</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ابزارک</item>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 34ed9e0..6cffafc 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Kaksoisnapauta ja paina pitkään, niin voit siirtää widgetiä tai käyttää muokattuja toimintoja."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sijoita manuaalisesti koskettamalla pitkään"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Lisää automaattisesti"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Voit siirtää widgetiä aloitusnäytöllä koskettamalla sitä pitkään"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lisää aloitusnäytölle"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetiä</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 34fcb36..3ebd61a 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Touchez 2x un widget et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Maintenez le doigt sur l\'élément pour le placer manuellement"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Maintenez le doigt sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f336031..bb56bac 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Appuyez deux fois et maintenez la pression pour déplacer widget ou utiliser actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement."</string>
- <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Appuyez de manière prolongée sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 382f6ff..d3f3f0b 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dúas veces un widget e manteno premido para movelo ou utiliza accións personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premido o elemento para colocalo manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Engadir automaticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premido o widget para movelo pola pantalla de inicio"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Engadir á pantalla de inicio"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index c7f8042..0882d64 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"વિજેટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ઑટોમૅટિક રીતે ઉમેરો"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> વિજેટ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> વિજેટ</item>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 478d87e..9a3c56c 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"खुद जोड़ने के लिए दबाकर रखें"</string>
- <string name="place_automatically" msgid="8064208734425456485">"अपने-आप जुड़ जाए"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"होम स्क्रीन पर यहां-वहां ले जाने के लिए विजेट को दबाकर रखें"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रीन पर जोड़ें"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 8ebc33f..d1cb5bf 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite pritisak da biste premjestili widget ili upotrijebite prilagođene radnje"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite stavku da biste je postavili ručno"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite widget da biste ga pomicali po početnom zaslonu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni zaslon"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgeta</item>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index d0aea22..9e2c358 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Modul áthelyezéséhez koppintson duplán, tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tartsd lenyomva a manuális hozzáadáshoz"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Automatikus hozzáadás"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tartsa lenyomva a modult a kezdőképernyőn való mozgatáshoz"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Hozzáadás a kezdőképernyőhöz"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> modul</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> modul</item>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index fbbcf1c..ff8b895 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Հպեք և պահեք՝ ձեռքով տեղադրելու համար"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Ավելացնել ավտոմատ կերպով"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> վիջեթ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> վիջեթ</item>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 7bc91c2..d42e4f9 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketuk dua kali & tahan untuk memindahkan widget atau gunakan tindakan khusus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh lama untuk menempatkan secara manual"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Tambahkan otomatis"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh lama widget untuk memindahkannya di sekitar Layar utama"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Tambahkan ke Layar utama"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 104b4ac..30e73b4 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ýttu tvisvar og haltu fingri á græju til að færa hana eða notaðu sérsniðnar aðgerðir."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Haltu inni til að staðsetja handvirkt"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Bæta sjálfkrafa við"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Haltu fingri á græjunni til að hreyfa hana um heimaskjáinn"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Bæta á heimaskjá"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> græja</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> græjur</item>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 9e13576..1d420a9 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tocca due volte e tieni premuto per spostare un widget o per usare le azioni personalizzate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tieni premuto per posizionare l\'elemento manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Aggiungi automaticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 639aa86..7cd53fa 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"רוחב %1$d על גובה %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"יש ללחוץ לחיצה ארוכה כדי להוסיף ידנית"</string>
- <string name="place_automatically" msgid="8064208734425456485">"הוספה אוטומטית"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"יש ללחוץ לחיצה ארוכה על הווידג\'ט כדי להזיז אותו ברחבי מסך הבית"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"הוספה למסך הבית"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="two"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ווידג\'טים</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ווידג\'טים</item>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index dc92748..c1136a4 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"長押しすると、手動で追加できます"</string>
- <string name="place_automatically" msgid="8064208734425456485">"自動的に追加"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ウィジェットを押し続けた状態で、ホーム画面上に移動させます。"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ホーム画面に追加"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 件のウィジェット</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 件のウィジェット</item>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 7a0ec8d..c701795 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ხანგრძლივად შეეხეთ ხელით განსათავსებლად"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ავტომატურად დამატება"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ხანგრძლივად შეეხეთ ვიჯეტს მთავარ ეკრანზე მის გადასაადგილებლად"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"მთავარ ეკრანზე დამატება"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ვიჯეტი</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ვიჯეტი</item>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index dff1311..8f92db0 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Қолмен қою үшін басып тұрыңыз"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Автоматты қосу"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Негізгі экран бойымен қозғалту үшін виджетті басып, ұстап тұрыңыз."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Негізгі экранға қосу"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> виджет</item>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index f460512..8a82bda 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទីធាតុក្រាហ្វិក ឬប្រើសកម្មភាពតាមបំណង។"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ចុចឲ្យជាប់ដើម្បីបញ្ចូលវាដោយផ្ទាល់"</string>
- <string name="place_automatically" msgid="8064208734425456485">"បញ្ចូលដោយស្វ័យប្រវត្តិ"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ចុចធាតុក្រាហ្វិកឱ្យជាប់ ដើម្បីផ្លាស់ទីវាជុំវិញអេក្រង់ដើម"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"បញ្ចូលទៅអេក្រង់ដើម"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">ធាតុក្រាហ្វិក <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">ធាតុក្រាហ្វិក <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index b12c631..73e2255 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ವಿಜೆಟ್ಗಳು</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ವಿಜೆಟ್ಗಳು</item>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 81285ca..b98ee5c 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"너비 %1$d, 높이 %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"길게 터치하여 직접 추가하세요."</string>
- <string name="place_automatically" msgid="8064208734425456485">"자동으로 추가"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"홈 화면에서 위젯을 이동하려면 길게 터치하세요."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"홈 화면에 추가"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">위젯 <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>개</item>
<item quantity="one">위젯 <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g>개</item>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 50c36d5..62fb75c 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетти жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Кол менен кошуу үчүн кое бербей басып туруңуз"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Автоматтык түрдө кошуу"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Башкы экранга жылдыруу үчүн виджетти коё бербей басып туруңуз"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Башкы экранга кошуу"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> виджет</item>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 3ce2c20..a7c2f68 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ ຫຼື ໃຊ້ຄຳສັ່ງກຳນົດເອງ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ກວ້າງ %1$d ຄູນສູງ %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ເພີ່ມໂດຍອັດຕະໂນມັດ"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ແຕະວິດເຈັດຄ້າງໄວ້ເພື່ອຍ້າຍມັນໄປມາຢູ່ໂຮມສະກຣີນ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ເພີ່ມໄປໃສ່ໂຮມສະກຣີນ"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ວິດເຈັດ</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ວິດເຈັດ</item>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index c75afbc..0677e88 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dukart palieskite ir palaikykite, kad perkeltumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Palieskite ir palaikykite, kad padėtumėte patys"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Pridėti automatiškai"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Paliesdami ir palaikydami valdiklį galite judėti pagrindiniame ekrane"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pridėti prie pagrindinio ekrano"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> valdiklis</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> valdikliai</item>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index dc2117f..6310375 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Lai pārvietotu logrīku, uz tā veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pieskarieties un turiet, lai manuāli pievienotu"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Pievienot automātiski"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pieskarieties logrīkam un turiet to, lai to pārvietotu pa sākuma ekrānu."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pievienot sākuma ekrānam"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="zero"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> logrīku</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> logrīks</item>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index ce79bde..c4349e6 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Допрете и задржете за рачно поставување"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Додај автоматски"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџет</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџети</item>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 3ab0b35..c0cb36b 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"വിജറ്റ് നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"നേരിട്ട് സ്ഥാപിക്കുന്നതിന് സ്പർശിച്ചുപിടിക്കുക"</string>
- <string name="place_automatically" msgid="8064208734425456485">"സ്വയമേവ ചേർക്കുക"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> വിജറ്റുകൾ</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> വിജറ്റ്</item>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index b93c535..3e99d67 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Жижиг хэрэгслийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Гараар байршуулахын тулд дараад хүлээнэ үү"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Автоматаар нэмэх"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Жижиг хэрэгслийг Үндсэн нүүрний эргэн тойронд зөөхийн тулд түүнд хүрээд, удаан дарна уу"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Үндсэн нүүрэнд нэмэх"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> жижиг хэрэгсэл</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> жижиг хэрэгсэл</item>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 7fc330e..7bf6c6c 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
- <string name="place_automatically" msgid="8064208734425456485">"आपोआप जोडा"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> विजेट</item>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index e54c6fe..9401040 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketik dua kali & tahan untuk menggerakkan widget atau menggunakan tindakan tersuai."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh & tahan untuk meletakkan widget/ikon secara manual"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Tambahkan secara automatik"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh & tahan widget untuk menggerakkan widget di sekitar Skrin utama"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Tambah pada Skrin utama"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index b429602..4dcd6c1 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"</string>
- <string name="place_automatically" msgid="8064208734425456485">"အလိုအလျောက် ထည့်ရန်"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ပင်မစာမျက်နှာအနီးတွင် ဝိဂျက်ကိုရွှေ့ရန် ၎င်းကို တို့ထိ၍ဖိထားပါ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ပင်မစာမျက်နှာသို့ ထည့်ရန်"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">ဝိဂျက် <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ခု</item>
<item quantity="one">ဝိဂျက် <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ခု</item>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 8245608..ad5affb 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dobbelttrykk og hold inne for å flytte en modul eller bruke tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Trykk og hold for å plassere manuelt"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Legg til automatisk"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Trykk og hold på modulen for å bevege den rundt på startskjermen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Legg til på startskjermen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> moduler</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> modul</item>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 9c348e3..0cdeae0 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -26,47 +26,41 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"सुरक्षित मोडमा डाउनलोड गरेको एप अक्षम गरिएको छ"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"सुरक्षित मोडमा विगेटहरू अक्षम गरियो"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"सर्टकट उपलब्ध छैन"</string>
- <!-- no translation found for home_screen (5629429142036709174) -->
- <skip />
- <!-- no translation found for recent_task_option_split_screen (6690461455618725183) -->
- <skip />
- <!-- no translation found for long_press_widget_to_add (3587712543577675817) -->
- <skip />
- <!-- no translation found for long_accessible_way_to_add (2733588281439571974) -->
- <skip />
+ <string name="home_screen" msgid="5629429142036709174">"होम"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रिन"</string>
+ <string name="long_press_widget_to_add" msgid="3587712543577675817">"कुनै विजेट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
+ <string name="long_accessible_way_to_add" msgid="2733588281439571974">"कुनै विजेट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"थप्न टच एण्ड होल्ड गर्नुहोस्"</string>
- <string name="place_automatically" msgid="8064208734425456485">"स्वतः थप्नुहोस्"</string>
- <!-- no translation found for widgets_count (656794749266073027) -->
- <!-- no translation found for shortcuts_count (8080294865447938455) -->
- <!-- no translation found for widgets_and_shortcuts_count (7209136747878365116) -->
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
<skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
+ <plurals name="widgets_count" formatted="false" msgid="656794749266073027">
+ <item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> वटा विजेट</item>
+ <item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> वटा विजेट</item>
+ </plurals>
+ <plurals name="shortcuts_count" formatted="false" msgid="8080294865447938455">
+ <item quantity="other"><xliff:g id="SHORTCUTS_COUNT_1">%1$d</xliff:g> वटा सर्टकट</item>
+ <item quantity="one"><xliff:g id="SHORTCUTS_COUNT_0">%1$d</xliff:g> वटा सर्टकट</item>
+ </plurals>
+ <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"विजेटहरू"</string>
- <!-- no translation found for widgets_full_sheet_search_bar_hint (8484659090860596457) -->
- <skip />
- <!-- no translation found for widgets_full_sheet_cancel_button_description (5766167035728653605) -->
- <skip />
- <!-- no translation found for no_widgets_available (9140948620298620513) -->
- <skip />
- <!-- no translation found for no_search_results (6518732304311458580) -->
- <skip />
- <!-- no translation found for widgets_full_sheet_personal_tab (2743540105607120182) -->
- <skip />
- <!-- no translation found for widgets_full_sheet_work_tab (3767150027110633765) -->
- <skip />
- <!-- no translation found for widget_category_conversations (8894438636213590446) -->
- <skip />
+ <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"खोज्नुहोस्"</string>
+ <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"खोज बाकसमा भएको पाठ हटाउनुहोस्"</string>
+ <string name="no_widgets_available" msgid="9140948620298620513">"कुनै पनि विजेट उपलब्ध छैन"</string>
+ <string name="no_search_results" msgid="6518732304311458580">"कुनै पनि खोज परिणाम भेटिएन"</string>
+ <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"व्यक्तिगत"</string>
+ <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"कामसम्बन्धी"</string>
+ <string name="widget_category_conversations" msgid="8894438636213590446">"वार्तालापहरू"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी एपहरू"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"एपहरू लोड गर्दै…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै एप भेटिएन"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"थप एपहरू खोज्नुहोस्"</string>
<string name="label_application" msgid="8531721983832654978">"एप"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
- <!-- no translation found for long_press_shortcut_to_add (5405328730817637737) -->
- <skip />
- <!-- no translation found for long_accessible_way_to_add_shortcut (2199537273817090740) -->
- <skip />
+ <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"कुनै सर्टकट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"कुनै सर्टकट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
<string name="out_of_space" msgid="4691004494942118364">"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"मन पर्ने ट्रे अब कुनै ठाँउ छैन"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"एपको सूची"</string>
@@ -124,8 +118,7 @@
<string name="abandoned_search" msgid="891119232568284442">"खोजी गर्नुहोस्"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"यो एप स्थापित छैन"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"यो प्रतिमाका लागि एपलाई स्थापना गरिएको छैन। तपाईं यसलाई हटाउन, वा एप खोजी र स्वयं यो स्थापित गर्न सक्नुहुन्छ।"</string>
- <!-- no translation found for app_installing_title (5864044122733792085) -->
- <skip />
+ <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इन्स्टल गरिँदै छ, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरा भयो"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड गर्दै, <xliff:g id="PROGRESS">%2$s</xliff:g> सम्पन्न"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापना गर्न प्रतीक्षा गर्दै"</string>
<string name="widgets_list" msgid="796804551140113767">"विजेटहरूको सूची"</string>
@@ -165,20 +158,13 @@
<string name="work_profile_edu_next" msgid="8783418929296503629">"अर्को"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"बुझेँ"</string>
<string name="work_apps_paused_title" msgid="2389865654362803723">"कार्यालयको प्रोफाइल अस्थायी रूपमा रोक्का गरिएको छ"</string>
- <!-- no translation found for work_apps_paused_body (4209084728264328628) -->
- <skip />
- <!-- no translation found for work_apps_paused_content_description (4473292417145736203) -->
- <skip />
- <!-- no translation found for work_apps_paused_edu_banner (8872412121608402058) -->
- <skip />
- <!-- no translation found for work_apps_paused_edu_accept (6377476824357318532) -->
- <skip />
- <!-- no translation found for work_apps_pause_btn_text (4669288269140620646) -->
- <skip />
- <!-- no translation found for work_apps_enable_btn_text (82111102541971856) -->
- <skip />
- <!-- no translation found for developer_options_filter_hint (5896817443635989056) -->
- <skip />
+ <string name="work_apps_paused_body" msgid="4209084728264328628">"कामसम्बन्धी एपहरूले तपाईंलाई सूचना पठाउन, तपाईंको डिभाइसको ब्याट्री प्रयोग गर्न वा तपाईंको स्थान हेर्न सक्दैनन्"</string>
+ <string name="work_apps_paused_content_description" msgid="4473292417145736203">"कामसम्बन्धी प्रोफाइल अस्थायी रूपमा रोक्का गरिएको छ। कामसम्बन्धी एपहरूले तपाईंलाई सूचना पठाउन, तपाईंको डिभाइसको ब्याट्री प्रयोग गर्न वा तपाईंको स्थान हेर्न सक्दैनन्"</string>
+ <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"कामसम्बन्धी एपमा ब्याज अङ्कित हुन्छ र तपाईंका IT एड्मिन ती एप हेर्न सक्नुहुन्छ"</string>
+ <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"बुझेँ"</string>
+ <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"कामसम्बन्धी एपहरू अस्थायी रूपमा रोक्का गर्नुहोस्"</string>
+ <string name="work_apps_enable_btn_text" msgid="82111102541971856">"अन गर्नुहोस्"</string>
+ <string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
<string name="work_switch_tip" msgid="808075064383839144">"कामसम्बन्धी एप र सूचनाहरू अस्थायी रूपमा रोक्का गर्नुहोस्"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 5af9252..cc16a89 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en houd vast om een widget te verplaatsen of aangepaste acties te gebruiken."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tik en houd vast om handmatig te plaatsen"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Automatisch toevoegen"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Houd de widget ingedrukt om deze te verplaatsen op het startscherm"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Toevoegen aan startscherm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 8505c8e..7f3495a 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ମାନୁଆଲ୍ ଭାବରେ ରଖିବାକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ସ୍ୱଚାଳିତ ଭାବେ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ମୂଳସ୍କ୍ରିନର ଆଖପାଖରେ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଏହାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>ଟି ୱିଜେଟ୍</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g>ଟି ୱିଜେଟ୍</item>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index f97f255..355e303 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ਵਿਜੇਟ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ਵਿਜੇਟ</item>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 06074e0..ceb8046 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść widżet lub użyć działań niestandardowych."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Kliknij i przytrzymaj, by umieścić ręcznie"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatycznie"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Kliknij i przytrzymaj widżet, by poruszać nim po ekranie głównym."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj do ekranu głównego"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widżety</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widżetów</item>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index fa2a50e..e40accf 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes sem soltar para mover um widget ou utilizar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque sem soltar para colocar manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 165a013..8b18329 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes e mantenha a tela pressionada para mover um widget ou usar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque e mantenha pressionado para mover manualmente"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque no widget e mantenha-o pressionado para movê-lo pela tela inicial"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar à tela inicial"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -51,7 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pessoal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabalho"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps de pesquisa"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 20b3353..a71f999 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atingeți de două ori și țineți apăsat pentru a muta un widget sau folosiți acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Atingeți lung pentru a plasa manual"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Adăugați automat"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Atingeți lung widgetul pentru a-l muta pe ecranul de pornire"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adăugați pe ecranul de pornire"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgeturi</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> de widgeturi</item>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 24aabc5..0c1acbc 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Чтобы использовать специальные действия или перенести виджет, нажмите на него дважды и удерживайте."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Нажмите и удерживайте, чтобы добавить вручную."</string>
- <string name="place_automatically" msgid="8064208734425456485">"Добавить автоматически"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Нажмите на виджет и удерживайте его, чтобы переместить в нужное место на главном экране."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Добавить на главный экран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджета</item>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 22baa2a..6b27168 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ස්වයංක්රියව එක් කරන්න"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"එය මුල් පිටු තිරය වටා ගෙන යාමට විජට් එක ස්පර්ශ කර අල්ලා ගන්න"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"මුල් පිටු තිරය වෙත එක් කරන්න"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one">විජට් <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="other">විජට් <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 1bcf528..7ea59d6 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a pridržaním presuňte miniaplikáciu alebo použite vlastné akcie."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Ak chcete položku umiestniť ručne, pridržte ju"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Pridať automaticky"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Po pridržaní môžete miniaplikáciu môžete posúvať po ploche"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pridať na plochu"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> miniaplikácie</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 9e60efb..f74bdcc 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvakrat se dotaknite pripomočka in ga pridržite, da ga premaknete, ali pa uporabite dejanja po meri."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dotaknite se elementa in ga pridržite, da ga ročno dodate"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Samodejno dodaj"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pridržite pripomoček, če ga želite premikati po začetnem zaslonu."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na začetni zaslon"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> pripomoček</item>
<item quantity="two"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> pripomočka</item>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 1ed8070..9a53936 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Trokit dy herë dhe mbaje shtypur një miniapliikacion për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Shto automatikisht"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Prek dhe mbaj miniaplikacionin për ta lëvizur nëpër \"Ekranin bazë\""</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Shto në \"Ekranin bazë\""</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> miniaplikacione</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> miniaplikacion</item>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 4809087..4f67b23 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двапут додирните и задржите да бисте померали виџет или користите прилагођене радње."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ширина од %1$d и висина од %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Додирните и задржите да бисте поставили ручно"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Аутоматски додај"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Додирните и задржите виџет да бисте га померали по почетном екрану"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Додај на почетни екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџета</item>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index aad4e4e..91b9b88 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryck snabbt två gånger och håll kvar för att flytta en widget eller använda anpassade åtgärder."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Placera manuellt genom att trycka länge"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Lägg till automatiskt"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tryck länge på widgeten om du vill flytta den på startskärmen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lägg till på startskärmen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetar</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 3ff05e1..6227239 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Gusa mara mbili na ushikilie ili usogeze wijeti au utumie vitendo maalum."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Gusa na ushikilie ili uweke mwenyewe"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Ongeza kiotomatiki"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Gusa na ushikilie wijeti ili uisogeze kwenye Skrini ya kwanza"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Weka kwenye Skrini ya kwanza"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">Wijeti <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Wijeti <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml
index d50115b..09bdaaf 100644
--- a/res/values-sw600dp/config.xml
+++ b/res/values-sw600dp/config.xml
@@ -1,6 +1,3 @@
<resources>
<bool name="allow_rotation">true</bool>
-
- <!-- Hotseat -->
- <bool name="hotseat_transpose_layout_with_orientation">false</bool>
</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 9d565aa..cae7e24 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
- <string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"முகப்புத் திரைக்கு விட்ஜெட்டை நகர்த்த அதைத் தொட்டுப் பிடிக்கவும்"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"முகப்புத் திரையில் சேர்"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> விட்ஜெட்டுகள்</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> விட்ஜெட்</item>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 344f455..478bd02 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"విడ్జెట్ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి & హోల్డ్ చేయి."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"మాన్యువల్గా ఉంచడానికి నొక్కి, పట్టుకోండి"</string>
- <string name="place_automatically" msgid="8064208734425456485">"ఆటోమేటిక్గా జోడించు"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> విడ్జెట్లు</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> విడ్జెట్</item>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index ea6a7c2..4f98cd2 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"แตะสองครั้งค้างไว้เพื่อย้ายวิดเจ็ตหรือใช้การดำเนินการที่กำหนดเอง"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"กว้าง %1$d x สูง %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"แตะค้างไว้เพื่อวางด้วยตัวเอง"</string>
- <string name="place_automatically" msgid="8064208734425456485">"เพิ่มโดยอัตโนมัติ"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"แตะวิดเจ็ตค้างไว้เพื่อย้ายไปรอบๆ หน้าจอหลัก"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"เพิ่มลงในหน้าจอหลัก"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">วิดเจ็ต <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> รายการ</item>
<item quantity="one">วิดเจ็ต <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> รายการ</item>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index f112ec9..a3504fe 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"I-double tap at pindutin nang matagal para ilipat ang widget o gumamit ng mga custom na pagkilos."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pindutin nang matagal para manual na ilagay"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Awtomatikong idagdag"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pindutin nang matagal ang widget para ilipat-lipat ito sa Home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Idagdag sa Home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> na widget</item>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 9936538..8029aeb 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Widget\'ı taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manuel olarak yerleştirmek için dokunun ve basılı tutun"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Otomatik olarak ekle"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Ana ekranda taşımak için widget\'a dokunup basılı tutun"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ana ekrana ekle"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 87ae581..5e179aa 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина – %1$d, висота – %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Натисніть і утримуйте, щоб додати вручну"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Додати автоматично"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Натисніть і втримуйте віджет, щоб переміщувати його головним екраном"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Додати на головний екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджети</item>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 2ee66b0..8cc578c 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ویجیٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d چوڑا اور %2$d اونچا"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"دستی طور پر رکھنے کیلئے ٹچ کر کے دبائے رکھیں"</string>
- <string name="place_automatically" msgid="8064208734425456485">"خود کار طور پر شامل کریں"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ویجیٹس</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ویجیٹ</item>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index d31aea9..9c8f7ed 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Joylash uchun bosib turing"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Avtomatik chiqarish"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Bosh ekranda surish uchun vidjet ustiga bosib turing"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Bosh ekranga chiqarish"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ta vidjet</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ta vidjet</item>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 318d453..a026dbc 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Nhấn đúp và giữ để di chuyển một tiện ích hoặc sử dụng các thao tác tùy chỉnh."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chạm và giữ để thêm theo cách thủ công"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Tự động thêm"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Chạm và giữ để di chuyển tiện ích xung quanh Màn hình chính"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Thêm vào Màn hình chính"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> tiện ích</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> tiện ích</item>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index f9628b2..d79f181 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -32,8 +32,10 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"宽 %1$d,高 %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"轻触并按住即可手动放置"</string>
- <string name="place_automatically" msgid="8064208734425456485">"自动添加"</string>
+ <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
+ <skip />
+ <!-- no translation found for add_to_home_screen (8631549138215492708) -->
+ <skip />
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 个微件</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 个微件</item>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 8929aa8..d32611d 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d 闊,%2$d 高"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住即可手動新增"</string>
- <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可將其移至主畫面上任何位置"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"新增至主畫面"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 個小工具</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 個小工具</item>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index c6f933c..58e8f19 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"寬度為 %1$d,高度為 %2$d"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住圖示即可手動新增"</string>
- <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可將小工具移到主畫面的任一位置"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"新增到主畫面"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 項小工具</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 項小工具</item>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 8296853..3892f6b 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -32,8 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Thepha kabili uphinde ubambe ukuze uhambise iwijethi noma usebenzise izindlela ezingokwezifiso."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
- <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Thinta futhi ubambe ukuze ubeke ngokwenza"</string>
- <string name="place_automatically" msgid="8064208734425456485">"Engeza ngokuzenzakalelayo"</string>
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Thinta uphinde ubambe iwijethi ukuyihambisa Kusikrini sasekhaya"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Engeza kusikrini sasekhaya"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one">Amawijethi angu-<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Amawijethi angu-<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 9089a64..a81802d 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -80,7 +80,8 @@
<attr name="ambientShadowBlur" format="dimension" />
<attr name="keyShadowColor" format="color" />
<attr name="keyShadowBlur" format="dimension" />
- <attr name="keyShadowOffset" format="dimension" />
+ <attr name="keyShadowOffsetX" format="dimension" />
+ <attr name="keyShadowOffsetY" format="dimension" />
</declare-styleable>
<!-- PagedView specific attributes. These attributes are used to customize
@@ -126,17 +127,24 @@
<!-- numFolderRows & numFolderColumns defaults to numRows & numColumns, if not specified -->
<attr name="numFolderRows" format="integer" />
<attr name="numFolderColumns" format="integer" />
+ <!-- numAllAppsColumns defaults to numColumns, if not specified -->
+ <attr name="numAllAppsColumns" format="integer" />
+ <!-- Number of columns to use when extending the all-apps size,
+ defaults to 2 * numAllAppsColumns -->
+ <attr name="numExtendedAllAppsColumns" format="integer" />
+
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
+ <!-- Number of icons to use when extending the hotseat size,
+ defaults to 2 * numHotseatIcons -->
+ <attr name="numExtendedHotseatIcons" format="integer" />
+
<attr name="dbFile" format="string" />
<attr name="defaultLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
<attr name="isScalable" format="boolean" />
<attr name="devicePaddingId" format="reference" />
- <!-- whether the grid option is shown to the user -->
- <attr name="visible" format="boolean" />
-
</declare-styleable>
<declare-styleable name="DevicePadding">
@@ -166,8 +174,12 @@
<attr name="iconTextSize" format="float" />
<!-- landscapeIconTextSize defaults to iconTextSize, if not specified -->
<attr name="landscapeIconTextSize" format="float" />
- <!-- If true, this display option is used to determine the default grid -->
- <attr name="canBeDefault" format="boolean" />
+
+ <!-- If set, this display option is used to determine the default grid -->
+ <attr name="canBeDefault" format="boolean|integer" >
+ <!-- The profile can be default on split display devices -->
+ <flag name="split_display" value="0x2" />
+ </attr>
<!-- The following values are only enabled if grid is supported. -->
<!-- allAppsIconSize defaults to iconSize, if not specified -->
@@ -175,11 +187,6 @@
<!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
<attr name="allAppsIconTextSize" format="float" />
- <!-- numAllAppsColumns defaults to GridDisplayOption.numColumns, if not specified -->
- <attr name="numAllAppsColumns" format="integer" />
-
- <!-- numShownHotseatIcons defaults to GridDisplayOption.numHotseatIcons, if not specified -->
- <attr name="numShownHotseatIcons" format="integer" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/res/values/config.xml b/res/values/config.xml
index f8a517d..9ad1224 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -35,7 +35,7 @@
<!-- Workspace -->
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->
- <integer name="config_dragOutlineFadeTime">900</integer>
+ <integer name="config_dragOutlineFadeTime">500</integer>
<!-- The alpha value at which to show the most recent drop visualization outline. -->
<integer name="config_dragOutlineMaxAlpha">255</integer>
@@ -55,9 +55,6 @@
<!-- The duration of the caret animation -->
<integer name="config_caretAnimationDuration">200</integer>
- <!-- Hotseat -->
- <bool name="hotseat_transpose_layout_with_orientation">true</bool>
-
<!-- Various classes overriden by projects/build flavors. -->
<string name="folder_name_provider_class" translatable="false"></string>
<string name="stats_log_manager_class" translatable="false"></string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 600a550..a57ccde 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -158,7 +158,7 @@
<!-- Dragging -->
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">14dp</dimen>
- <dimen name="drop_target_text_size">14sp</dimen>
+ <dimen name="drop_target_text_size">20sp</dimen>
<dimen name="drop_target_shadow_elevation">2dp</dimen>
<!-- the distance an icon must be dragged before button drop targets accept it -->
@@ -293,7 +293,7 @@
<dimen name="overview_task_margin">0dp</dimen>
<!-- Workspace grid visualization parameters -->
- <dimen name="grid_visualization_rounding_radius">28dp</dimen>
+ <dimen name="grid_visualization_rounding_radius">22dp</dimen>
<dimen name="grid_visualization_cell_spacing">6dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0f937fa..eae32b7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -55,10 +55,11 @@
<string name="widget_dims_format">%1$d \u00d7 %2$d</string>
<!-- Accessibility spoken message format for the dimensions of a widget in the drawer -->
<string name="widget_accessible_dims_format">%1$d wide by %2$d high</string>
- <!-- Message to tell the user to press and hold a widget/icon to add it -->
- <string name="add_item_request_drag_hint">Touch & hold to place manually</string>
- <!-- Button label to automatically add icon on home screen [CHAR_LIMIT=50] -->
- <string name="place_automatically">Add automatically</string>
+ <!-- Message to tell the user to press and hold a widget/icon to add it to the home screen.
+ [CHAR LIMIT=NONE] -->
+ <string name="add_item_request_drag_hint">Touch & hold the widget to move it around the Home screen</string>
+ <!-- Button label to automatically add a widget to home screen [CHAR_LIMIT=50] -->
+ <string name="add_to_home_screen">Add to Home screen</string>
<!-- Label for showing the number of widgets an app has in the full widgets picker.
[CHAR_LIMIT=25] -->
<plurals name="widgets_count">
@@ -220,7 +221,7 @@
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
<string name="wallpaper_button_text">Wallpapers</string>
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
- <string name="styles_wallpaper_button_text">Styles & wallpapers</string>
+ <string name="styles_wallpaper_button_text">Wallpaper & style</string>
<!-- Text for settings button [CHAR LIMIT=30]-->
<string name="settings_button_text">Home settings</string>
<!-- Message shown when a feature is disabled by the administrator -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8d46f1c..97a5760 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -42,8 +42,8 @@
<item name="isWorkspaceDarkText">false</item>
<item name="workspaceTextColor">@color/workspace_text_color_light</item>
<item name="workspaceShadowColor">#B0000000</item>
- <item name="workspaceAmbientShadowColor">#33000000</item>
- <item name="workspaceKeyShadowColor">#44000000</item>
+ <item name="workspaceAmbientShadowColor">#00000000</item>
+ <item name="workspaceKeyShadowColor">#89000000</item>
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="folderDotColor">?android:attr/colorPrimary</item>
@@ -243,8 +243,9 @@
<item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
<item name="ambientShadowBlur">2.5dp</item>
<item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
- <item name="keyShadowBlur">1dp</item>
- <item name="keyShadowOffset">.5dp</item>
+ <item name="keyShadowBlur">.5dp</item>
+ <item name="keyShadowOffsetX">.5dp</item>
+ <item name="keyShadowOffsetY">.5dp</item>
</style>
<!-- Theme for the popup container -->
@@ -257,14 +258,11 @@
<item name="android:drawablePadding">7.5dp</item>
<item name="android:paddingLeft">16dp</item>
<item name="android:paddingRight">16dp</item>
- <item name="android:textColor">?attr/workspaceTextColor</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">@dimen/drop_target_text_size</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">end</item>
- <item name="android:shadowColor">?attr/workspaceShadowColor</item>
- <item name="android:shadowDx">0.0</item>
- <item name="android:shadowDy">1.0</item>
- <item name="android:shadowRadius">4.0</item>
+ <item name="android:background">@drawable/drop_target_frame</item>
</style>
<style name="DropTargetButton" parent="DropTargetButtonBase" />
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
index 344f532..b58e4b7 100644
--- a/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
@@ -18,11 +18,15 @@
import android.content.Context;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.uioverrides.DeviceFlag;
import com.android.launcher3.util.LooperExecutor;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
/**
* Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
@@ -30,6 +34,9 @@
@Implements(value = DeviceFlag.class, isInAndroidSdk = false)
public class ShadowDeviceFlag {
+ @RealObject private DeviceFlag mRealObject;
+ @Nullable private Boolean mValue;
+
/**
* Mock change listener as it uses internal system classes not available to robolectric
*/
@@ -40,4 +47,16 @@
protected static boolean getDeviceValue(String key, boolean defaultValue) {
return defaultValue;
}
+
+ @Implementation
+ public boolean get() {
+ if (mValue != null) {
+ return mValue;
+ }
+ return Shadow.directlyOn(mRealObject, DeviceFlag.class, "get");
+ }
+
+ public void setValue(boolean value) {
+ mValue = new Boolean(value);
+ }
}
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
index 4d151f1..ea75548 100644
--- a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
+++ b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
@@ -161,7 +161,7 @@
private static MotionEvent createScrollEvent(int scroll) {
DeviceProfile dp = InvariantDeviceProfile.INSTANCE
- .get(RuntimeEnvironment.application).portraitProfile;
+ .get(RuntimeEnvironment.application).supportedProfiles.get(0);
final PointerProperties[] pointerProperties = new PointerProperties[1];
pointerProperties[0] = new PointerProperties();
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index 92f77f2..d977011 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -17,6 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+
import android.content.Context;
import android.graphics.Point;
@@ -109,10 +112,14 @@
private InvariantDeviceProfile createIDP() {
DeviceProfile profile = Mockito.mock(DeviceProfile.class);
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(CELL_SIZE, CELL_SIZE);
+ return null;
+ }).when(profile).getCellSize(any(Point.class));
Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
InvariantDeviceProfile idp = new InvariantDeviceProfile();
- idp.landscapeProfile = idp.portraitProfile = profile;
+ idp.supportedProfiles.add(profile);
return idp;
}
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 5d41bb5..c1f3ac5 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -1,5 +1,7 @@
package com.android.launcher3;
+import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget;
+
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH;
import static com.android.launcher3.Utilities.ATLEAST_S;
@@ -10,7 +12,9 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
@@ -25,16 +29,14 @@
import android.widget.ImageButton;
import android.widget.ImageView;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
private static final int SNAP_DURATION = 150;
@@ -43,22 +45,6 @@
private static final Rect sTmpRect = new Rect();
- // Represents the cell size on the grid in the two orientations.
- public static final MainThreadInitializedObject<Point[]> CELL_SIZE =
- new MainThreadInitializedObject<>(c -> {
- InvariantDeviceProfile inv = LauncherAppState.getIDP(c);
- return new Point[] {inv.landscapeProfile.getCellSize(),
- inv.portraitProfile.getCellSize()};
- });
-
- // Represents the border spacing size on the grid in the two orientations.
- public static final MainThreadInitializedObject<int[]> BORDER_SPACING_SIZE =
- new MainThreadInitializedObject<>(c -> {
- InvariantDeviceProfile inv = LauncherAppState.getIDP(c);
- return new int[] {inv.landscapeProfile.cellLayoutBorderSpacingPx,
- inv.portraitProfile.cellLayoutBorderSpacingPx};
- });
-
private static final int HANDLE_COUNT = 4;
private static final int INDEX_LEFT = 0;
private static final int INDEX_TOP = 1;
@@ -71,6 +57,22 @@
private final View[] mDragHandles = new View[HANDLE_COUNT];
private final List<Rect> mSystemGestureExclusionRects = new ArrayList<>(HANDLE_COUNT);
+ private final OnAttachStateChangeListener mWidgetViewAttachStateChangeListener =
+ new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ // Do nothing
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // When the app widget view is detached, we should close the resize frame.
+ // An example is when the dragging starts, the widget view is detached from
+ // CellLayout and then reattached to DragLayout.
+ close(false);
+ }
+ };
+
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
@@ -191,7 +193,11 @@
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
DragLayer dragLayer) {
mCellLayout = cellLayout;
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
mWidgetView = widgetView;
+ mWidgetView.addOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo)
widgetView.getAppWidgetInfo();
mResizeMode = info.resizeMode;
@@ -202,7 +208,7 @@
mMaxHSpan = info.maxSpanX;
mMaxVSpan = info.maxSpanY;
- mWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(getContext(),
+ mWidgetPadding = getDefaultPaddingForWidget(getContext(),
widgetView.getAppWidgetInfo().provider, null);
if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) {
@@ -392,81 +398,82 @@
mWidgetView.requestLayout();
}
- public static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher,
- int spanX, int spanY) {
- List<SizeF> sizes = getWidgetSizes(launcher, spanX, spanY);
+ public static void updateWidgetSizeRanges(
+ AppWidgetHostView widgetView, Context context, int spanX, int spanY) {
+ List<SizeF> sizes = getWidgetSizes(context, spanX, spanY);
if (ATLEAST_S) {
widgetView.updateAppWidgetSize(new Bundle(), sizes);
} else {
- Rect bounds = getMinMaxSizes(sizes, null /* outRect */);
+ Rect bounds = getMinMaxSizes(sizes);
widgetView.updateAppWidgetSize(new Bundle(), bounds.left, bounds.top, bounds.right,
bounds.bottom);
}
}
- private static SizeF getWidgetSize(Context context, Point cellSize, int spanX, int spanY,
- int borderSpacing) {
- final float density = context.getResources().getDisplayMetrics().density;
- final float hBorderSpacing = (spanX - 1) * borderSpacing;
- final float vBorderSpacing = (spanY - 1) * borderSpacing;
-
- return new SizeF(((spanX * cellSize.x) + hBorderSpacing) / density,
- ((spanY * cellSize.y) + vBorderSpacing) / density);
- }
-
/** Returns the list of sizes for a widget of given span, in dp. */
public static ArrayList<SizeF> getWidgetSizes(Context context, int spanX, int spanY) {
- final Point[] cellSize = CELL_SIZE.get(context);
- final int[] borderSpacing = BORDER_SPACING_SIZE.get(context);
-
- SizeF landSize = getWidgetSize(context, cellSize[0], spanX, spanY, borderSpacing[0]);
- SizeF portSize = getWidgetSize(context, cellSize[1], spanX, spanY, borderSpacing[1]);
-
ArrayList<SizeF> sizes = new ArrayList<>(2);
- sizes.add(landSize);
- sizes.add(portSize);
+ final float density = context.getResources().getDisplayMetrics().density;
+ Point cellSize = new Point();
+
+ for (DeviceProfile profile : LauncherAppState.getIDP(context).supportedProfiles) {
+ final float hBorderSpacing = (spanX - 1) * profile.cellLayoutBorderSpacingPx;
+ final float vBorderSpacing = (spanY - 1) * profile.cellLayoutBorderSpacingPx;
+ profile.getCellSize(cellSize);
+ sizes.add(new SizeF(
+ ((spanX * cellSize.x) + hBorderSpacing) / density,
+ ((spanY * cellSize.y) + vBorderSpacing) / density));
+ }
return sizes;
}
/**
+ * Returns the bundle to be used as the default options for a widget with provided size
+ */
+ public static Bundle getWidgetSizeOptions(
+ Context context, ComponentName provider, int spanX, int spanY) {
+ ArrayList<SizeF> sizes = getWidgetSizes(context, spanX, spanY);
+ Rect padding = getDefaultPaddingForWidget(context, provider, null);
+ float density = context.getResources().getDisplayMetrics().density;
+ float xPaddingDips = (padding.left + padding.right) / density;
+ float yPaddingDips = (padding.top + padding.bottom) / density;
+
+ ArrayList<SizeF> paddedSizes = sizes.stream()
+ .map(size -> new SizeF(
+ Math.max(0.f, size.getWidth() - xPaddingDips),
+ Math.max(0.f, size.getHeight() - yPaddingDips)))
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ Rect rect = AppWidgetResizeFrame.getMinMaxSizes(paddedSizes);
+ Bundle options = new Bundle();
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, rect.left);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, rect.top);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, rect.right);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, rect.bottom);
+ options.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, paddedSizes);
+ return options;
+ }
+
+ /**
* Returns the min and max widths and heights given a list of sizes, in dp.
*
* @param sizes List of sizes to get the min/max from.
- * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If
- * null, a new rectangle will be allocated.
* @return A rectangle with the left (resp. top) is used for the min width (resp. height) and
* the right (resp. bottom) for the max. The returned rectangle is set with 0s if the list is
* empty.
*/
- public static Rect getMinMaxSizes(List<SizeF> sizes, @Nullable Rect outRect) {
- if (outRect == null) {
- outRect = new Rect();
- }
+ private static Rect getMinMaxSizes(List<SizeF> sizes) {
if (sizes.isEmpty()) {
- outRect.set(0, 0, 0, 0);
+ return new Rect();
} else {
SizeF first = sizes.get(0);
- outRect.set((int) first.getWidth(), (int) first.getHeight(), (int) first.getWidth(),
- (int) first.getHeight());
+ Rect result = new Rect((int) first.getWidth(), (int) first.getHeight(),
+ (int) first.getWidth(), (int) first.getHeight());
for (int i = 1; i < sizes.size(); i++) {
- outRect.union((int) sizes.get(i).getWidth(), (int) sizes.get(i).getHeight());
+ result.union((int) sizes.get(i).getWidth(), (int) sizes.get(i).getHeight());
}
+ return result;
}
- return outRect;
- }
-
- /**
- * Returns the range of sizes a widget may be displayed, given its span.
- *
- * @param context Context in which the View is rendered.
- * @param spanX Width of the widget, in cells.
- * @param spanY Height of the widget, in cells.
- * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If
- * null, a new rectangle will be allocated.
- */
- public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY,
- @Nullable Rect outRect) {
- return getMinMaxSizes(getWidgetSizes(context, spanX, spanY), outRect);
}
@Override
@@ -641,6 +648,9 @@
@Override
protected void handleClose(boolean animate) {
mDragLayer.removeView(this);
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
}
@Override
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 2ace796..3d044d6 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -317,7 +317,8 @@
@UiThread
protected void applyIconAndLabel(ItemInfoWithIcon info) {
- FastBitmapDrawable iconDrawable = info.newIcon(getContext());
+ boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER;
+ FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme);
mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
setIcon(iconDrawable);
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index a26217c..00317f7 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -36,6 +36,8 @@
import android.widget.PopupWindow;
import android.widget.TextView;
+import androidx.appcompat.content.res.AppCompatResources;
+
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
@@ -142,6 +144,11 @@
}
}
+ private void setBackgroundDrawable(int resId) {
+ Drawable bd = AppCompatResources.getDrawable(getContext(), resId);
+ setBackground(bd);
+ }
+
@Override
public final void onDragEnter(DragObject d) {
if (!mAccessibleDrag && !mTextVisible) {
@@ -167,6 +174,7 @@
}
d.dragView.setAlpha(DRAG_VIEW_HOVER_OVER_OPACITY);
+ setBackgroundDrawable(R.drawable.drop_target_frame_hover);
if (d.stateAnnouncer != null) {
d.stateAnnouncer.cancel();
}
@@ -184,6 +192,7 @@
if (!d.dragComplete) {
d.dragView.setAlpha(1f);
+ setBackgroundDrawable(R.drawable.drop_target_frame);
} else {
d.dragView.setAlpha(DRAG_VIEW_HOVER_OVER_OPACITY);
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index c3816cc..1df9df6 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -18,6 +18,7 @@
import static android.animation.ValueAnimator.areAnimatorsEnabled;
+import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import android.animation.Animator;
@@ -193,6 +194,8 @@
private static final int INVALID_DIRECTION = -100;
private final Rect mTempRect = new Rect();
+ private final RectF mTempRectF = new RectF();
+ private final float[] mTmpFloatArray = new float[4];
private static final Paint sPaint = new Paint();
@@ -502,7 +505,7 @@
}
private void updateBgAlpha() {
- mBackground.setAlpha((int) (mSpringLoadedProgress * mScrollProgress * 255));
+ mBackground.setAlpha((int) (mSpringLoadedProgress * 255));
}
/**
@@ -525,9 +528,12 @@
}
protected void visualizeGrid(Canvas canvas) {
- mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding,
- mCellWidth - mGridVisualizationPadding,
- mCellHeight - mGridVisualizationPadding);
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding);
+ int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding);
+ mVisualizeGridRect.set(paddingX, paddingY,
+ mCellWidth - paddingX,
+ mCellHeight - paddingY);
mVisualizeGridPaint.setStrokeWidth(8);
int paintAlpha = (int) (120 * mGridAlpha);
@@ -537,9 +543,9 @@
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
int transX = i * mCellWidth + (i * mBorderSpacing) + getPaddingLeft()
- + mGridVisualizationPadding;
+ + paddingX;
int transY = j * mCellHeight + (j * mBorderSpacing) + getPaddingTop()
- + mGridVisualizationPadding;
+ + paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
mVisualizeGridPaint.setStyle(Paint.Style.FILL);
@@ -560,14 +566,14 @@
int spanX = mDragOutlines[i].cellHSpan;
int spanY = mDragOutlines[i].cellVSpan;
- mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding,
- mCellWidth * spanX - mGridVisualizationPadding,
- mCellHeight * spanY - mGridVisualizationPadding);
+ mVisualizeGridRect.set(paddingX, paddingY,
+ mCellWidth * spanX - paddingX,
+ mCellHeight * spanY - paddingY);
int transX = x * mCellWidth + (x * mBorderSpacing)
- + getPaddingLeft() + mGridVisualizationPadding;
+ + getPaddingLeft() + paddingX;
int transY = y * mCellHeight + (y * mBorderSpacing)
- + getPaddingTop() + mGridVisualizationPadding;
+ + getPaddingTop() + paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
@@ -1067,11 +1073,16 @@
// Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
View view = dragObject.dragView.getContentView();
if (view instanceof LauncherAppWidgetHostView) {
- Workspace workspace =
- Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace();
+ Launcher launcher = Launcher.getLauncher(dragObject.dragView.getContext());
+ Workspace workspace = launcher.getWorkspace();
int screenId = workspace.getIdForScreen(this);
int pageId = workspace.getPageIndexForScreenId(screenId);
cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect);
+
+ // Now get the rect in drag layer coordinates.
+ getBoundsForViewInDragLayer(launcher.getDragLayer(), workspace, mTempRect, false,
+ mTmpFloatArray, mTempRectF);
+ Utilities.setRect(mTempRectF, mTempRect);
((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
}
}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index e46aad2..80ec192 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -53,7 +53,7 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- setDrawable(R.drawable.ic_remove_shadow);
+ setDrawable(R.drawable.ic_remove_no_shadow);
}
@Override
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index fd97936..d5860dc 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -31,7 +31,6 @@
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Surface;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -42,7 +41,6 @@
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.WindowBounds;
@@ -52,9 +50,6 @@
@SuppressLint("NewApi")
public class DeviceProfile {
- private static final float TABLET_MIN_DPS = 600;
- private static final float LARGE_TABLET_MIN_DPS = 720;
-
private static final int DEFAULT_DOT_SIZE = 100;
public final InvariantDeviceProfile inv;
@@ -63,9 +58,9 @@
// Device properties
public final boolean isTablet;
- public final boolean isLargeTablet;
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
+ public final boolean isTwoPanels;
// Device properties in current orientation
public final boolean isLandscape;
@@ -164,6 +159,7 @@
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
+ public final int numShownAllAppsColumns;
public float allAppsIconTextSizePx;
// Overview
@@ -194,42 +190,30 @@
// How much of the bottom inset is due to Taskbar rather than other system elements.
public int nonOverlappingTaskbarInset;
- DeviceProfile(Context context, InvariantDeviceProfile inv, Info info,
- Point minSize, Point maxSize, int width, int height, boolean isLandscape,
+ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
- Point windowPosition) {
+ boolean useTwoPanels) {
this.inv = inv;
- this.isLandscape = isLandscape;
+ this.isLandscape = windowBounds.isLandscape();
this.isMultiWindowMode = isMultiWindowMode;
this.transposeLayoutWithOrientation = transposeLayoutWithOrientation;
- windowX = windowPosition.x;
- windowY = windowPosition.y;
+ windowX = windowBounds.bounds.left;
+ windowY = windowBounds.bounds.top;
isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
// Determine sizes.
- widthPx = width;
- heightPx = height;
- int nonFinalAvailableHeightPx;
- if (isLandscape) {
- availableWidthPx = maxSize.x;
- nonFinalAvailableHeightPx = minSize.y;
- } else {
- availableWidthPx = minSize.x;
- nonFinalAvailableHeightPx = maxSize.y;
- }
+ widthPx = windowBounds.bounds.width();
+ heightPx = windowBounds.bounds.height();
+ availableWidthPx = windowBounds.availableSize.x;
+ int nonFinalAvailableHeightPx = windowBounds.availableSize.y;
mInfo = info;
+ isTablet = info.isTablet(windowBounds);
+ isPhone = !isTablet;
+ isTwoPanels = isTablet && useTwoPanels;
- // Constants from resources
- float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y),
- info.densityDpi);
- boolean allowRotation = context.getResources().getBoolean(R.bool.allow_rotation);
- // Tablet UI is built with assumption that simulated landscape is disabled.
- isTablet = allowRotation && swDPs >= TABLET_MIN_DPS;
- isLargeTablet = isTablet && swDPs >= LARGE_TABLET_MIN_DPS;
- isPhone = !isTablet && !isLargeTablet;
aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx);
boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0;
@@ -284,7 +268,7 @@
? 0
: res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
- if (FeatureFlags.ENABLE_TWO_PANEL_HOME.get() && isTablet) {
+ if (isTwoPanels) {
cellLayoutPaddingLeftRightPx =
res.getDimensionPixelSize(R.dimen.two_panel_home_side_padding);
cellLayoutBottomPaddingPx = 0;
@@ -309,7 +293,10 @@
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
- numShownHotseatIcons = inv.numShownHotseatIcons;
+ numShownHotseatIcons =
+ isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+ numShownAllAppsColumns =
+ isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
hotseatBarBottomPaddingPx = (isTallDevice ? 0
@@ -393,11 +380,12 @@
}
public Builder toBuilder(Context context) {
- Point size = new Point(availableWidthPx, availableHeightPx);
+ WindowBounds bounds =
+ new WindowBounds(widthPx, heightPx, availableWidthPx, availableHeightPx);
+ bounds.bounds.offsetTo(windowX, windowY);
return new Builder(context, inv, mInfo)
- .setSizeRange(size, size)
- .setSize(widthPx, heightPx)
- .setWindowPosition(windowX, windowY)
+ .setWindowBounds(bounds)
+ .setUseTwoPanels(isTwoPanels)
.setMultiWindowMode(isMultiWindowMode);
}
@@ -409,15 +397,8 @@
* TODO: Move this to the builder as part of setMultiWindowMode
*/
public DeviceProfile getMultiWindowProfile(Context context, WindowBounds windowBounds) {
- // We take the minimum sizes of this profile and it's multi-window variant to ensure that
- // the system decor is always excluded.
- Point mwSize = new Point(Math.min(availableWidthPx, windowBounds.availableSize.x),
- Math.min(availableHeightPx, windowBounds.availableSize.y));
-
DeviceProfile profile = toBuilder(context)
- .setSizeRange(mwSize, mwSize)
- .setSize(windowBounds.bounds.width(), windowBounds.bounds.height())
- .setWindowPosition(windowBounds.bounds.left, windowBounds.bounds.top)
+ .setWindowBounds(windowBounds)
.setMultiWindowMode(true)
.build();
@@ -434,14 +415,6 @@
}
/**
- * Inverse of {@link #getMultiWindowProfile(Context, WindowBounds)}
- * @return device profile corresponding to the current orientation in non multi-window mode.
- */
- public DeviceProfile getFullScreenProfile() {
- return isLandscape ? inv.landscapeProfile : inv.portraitProfile;
- }
-
- /**
* Checks if there is enough space for labels on the workspace.
* If there is not, labels on the Workspace are hidden.
* It is important to call this method after the All Apps variables have been set.
@@ -553,7 +526,7 @@
}
// All apps
- if (allAppsHasDifferentNumColumns()) {
+ if (numShownAllAppsColumns != inv.numColumns) {
allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mMetrics);
allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
@@ -667,18 +640,20 @@
}
public Point getCellSize() {
- return getCellSize(inv.numColumns, inv.numRows);
+ return getCellSize(null);
}
- private Point getCellSize(int numColumns, int numRows) {
- Point result = new Point();
+ public Point getCellSize(Point result) {
+ if (result == null) {
+ result = new Point();
+ }
// Since we are only concerned with the overall padding, layout direction does
// not matter.
Point padding = getTotalWorkspacePadding();
result.x = calculateCellWidth(availableWidthPx - padding.x
- - cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, numColumns);
+ - cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, inv.numColumns);
result.y = calculateCellHeight(availableHeightPx - padding.y
- - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, numRows);
+ - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows);
return result;
}
@@ -723,7 +698,7 @@
padding.set(availablePaddingX / 2, edgeMarginPx + availablePaddingY / 2,
availablePaddingX / 2, paddingBottom + availablePaddingY / 2);
- if (FeatureFlags.ENABLE_TWO_PANEL_HOME.get()) {
+ if (isTwoPanels) {
padding.set(0, padding.top, 0, padding.bottom);
}
} else {
@@ -751,7 +726,7 @@
// for this, we pad the left and right of the hotseat with half of the difference of a
// workspace cell vs a hotseat cell.
float workspaceCellWidth = (float) widthPx / inv.numColumns;
- float hotseatCellWidth = (float) widthPx / inv.numShownHotseatIcons;
+ float hotseatCellWidth = (float) widthPx / numShownHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
mHotseatPadding.set(
hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
@@ -802,13 +777,6 @@
}
/**
- * Returns true when the number of workspace columns and all apps columns differs.
- */
- private boolean allAppsHasDifferentNumColumns() {
- return inv.numAllAppsColumns != inv.numColumns;
- }
-
- /**
* Updates orientation information and returns true if it has changed from the previous value.
*/
public boolean updateIsSeascape(Context context) {
@@ -828,7 +796,7 @@
}
public boolean shouldFadeAdjacentWorkspaceScreens() {
- return isVerticalBarLayout() || isLargeTablet;
+ return isVerticalBarLayout();
}
public int getCellHeight(@ContainerType int containerType) {
@@ -854,13 +822,13 @@
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
writer.println(prefix + "\tisTablet:" + isTablet);
- writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
+ transposeLayoutWithOrientation);
writer.println(prefix + "\tisLandscape:" + isLandscape);
writer.println(prefix + "\tisMultiWindowMode:" + isMultiWindowMode);
+ writer.println(prefix + "\tisTwoPanels:" + isTwoPanels);
writer.println(prefix + pxToDpStr("windowX", windowX));
writer.println(prefix + pxToDpStr("windowY", windowY));
@@ -907,6 +875,7 @@
writer.println(prefix + pxToDpStr("allAppsIconDrawablePaddingPx",
allAppsIconDrawablePaddingPx));
writer.println(prefix + pxToDpStr("allAppsCellHeightPx", allAppsCellHeightPx));
+ writer.println(prefix + "\tnumShownAllAppsColumns: " + numShownAllAppsColumns);
writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
@@ -916,6 +885,7 @@
hotseatBarSidePaddingStartPx));
writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
hotseatBarSidePaddingEndPx));
+ writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
@@ -967,41 +937,16 @@
private InvariantDeviceProfile mInv;
private Info mInfo;
- private final Point mWindowPosition = new Point();
- private Point mMinSize, mMaxSize;
- private int mWidth, mHeight;
+ private WindowBounds mWindowBounds;
+ private boolean mUseTwoPanels;
- private boolean mIsLandscape;
private boolean mIsMultiWindowMode = false;
- private boolean mTransposeLayoutWithOrientation;
+ private Boolean mTransposeLayoutWithOrientation;
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
mInv = inv;
mInfo = info;
- mTransposeLayoutWithOrientation = context.getResources()
- .getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "transposeLayout=" + mTransposeLayoutWithOrientation);
- }
- }
-
- public Builder setSizeRange(Point minSize, Point maxSize) {
- mMinSize = minSize;
- mMaxSize = maxSize;
- return this;
- }
-
- public Builder setSize(int width, int height) {
- mWidth = width;
- mHeight = height;
- mIsLandscape = mWidth > mHeight;
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "isLandscape=" + mIsLandscape + " w=" + mWidth + " h=" + mHeight);
- }
- return this;
}
public Builder setMultiWindowMode(boolean isMultiWindowMode) {
@@ -1009,11 +954,14 @@
return this;
}
- /**
- * Sets the window position if not full-screen
- */
- public Builder setWindowPosition(int x, int y) {
- mWindowPosition.set(x, y);
+ public Builder setUseTwoPanels(boolean useTwoPanels) {
+ mUseTwoPanels = useTwoPanels;
+ return this;
+ }
+
+
+ public Builder setWindowBounds(WindowBounds bounds) {
+ mWindowBounds = bounds;
return this;
}
@@ -1023,9 +971,14 @@
}
public DeviceProfile build() {
- return new DeviceProfile(mContext, mInv, mInfo, mMinSize, mMaxSize,
- mWidth, mHeight, mIsLandscape, mIsMultiWindowMode,
- mTransposeLayoutWithOrientation, mWindowPosition);
+ if (mWindowBounds == null) {
+ throw new IllegalArgumentException("Window bounds not set");
+ }
+ if (mTransposeLayoutWithOrientation == null) {
+ mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
+ }
+ return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds,
+ mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels);
}
}
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index c79dabe..4312939 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -99,7 +99,7 @@
}
public void hideKeyboard() {
- UiThreadHelper.hideKeyboardAsync(getContext(), getWindowToken());
+ UiThreadHelper.hideKeyboardAsync(Launcher.getLauncher(getContext()), getWindowToken());
}
private boolean showSoftInput() {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 8496fd5..b2a9e75 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -90,11 +90,11 @@
public void resetLayout(boolean hasVerticalHotseat) {
removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
- InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
+ DeviceProfile dp = mActivity.getDeviceProfile();
if (hasVerticalHotseat) {
- setGridSize(1, idp.numShownHotseatIcons);
+ setGridSize(1, dp.numShownHotseatIcons);
} else {
- setGridSize(idp.numShownHotseatIcons, 1);
+ setGridSize(dp.numShownHotseatIcons, 1);
}
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 1332e14..b263d38 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -16,11 +16,12 @@
package com.android.launcher3;
+import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.Utilities.getPointString;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
-import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
+import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
@@ -55,6 +56,7 @@
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.WindowBounds;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -62,6 +64,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
public class InvariantDeviceProfile {
@@ -73,6 +76,9 @@
public static final String KEY_MIGRATION_SRC_WORKSPACE_SIZE = "migration_src_workspace_size";
public static final String KEY_MIGRATION_SRC_HOTSEAT_COUNT = "migration_src_hotseat_count";
+ private static final int DEFAULT_TRUE = -1;
+ private static final int DEFAULT_SPLIT_DISPLAY = 2;
+
private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
@@ -136,6 +142,7 @@
* Number of columns in the all apps list.
*/
public int numAllAppsColumns;
+ public int numDatabaseAllAppsColumns;
/**
* Do not query directly. see {@link DeviceProfile#isScalableGrid}.
@@ -147,8 +154,7 @@
public int defaultLayoutId;
int demoModeLayoutId;
- public DeviceProfile landscapeProfile;
- public DeviceProfile portraitProfile;
+ public final List<DeviceProfile> supportedProfiles = new ArrayList<>();
@Nullable public DevicePaddings devicePaddings;
@@ -175,6 +181,7 @@
numShownHotseatIcons = p.numShownHotseatIcons;
numDatabaseHotseatIcons = p.numDatabaseHotseatIcons;
numAllAppsColumns = p.numAllAppsColumns;
+ numDatabaseAllAppsColumns = p.numDatabaseAllAppsColumns;
isScalable = p.isScalable;
devicePaddingId = p.devicePaddingId;
minCellHeight = p.minCellHeight;
@@ -204,7 +211,7 @@
DisplayController.INSTANCE.get(context).addChangeListener(
(displayContext, info, flags) -> {
- if ((flags & (CHANGE_SIZE | CHANGE_DENSITY)) != 0) {
+ if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS)) != 0) {
onConfigChanged(displayContext);
}
});
@@ -232,35 +239,29 @@
// Get the display info based on default display and interpolate it to existing display
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
DisplayController.INSTANCE.get(context).getInfo(),
- getPredefinedDeviceProfiles(context, gridName));
+ getPredefinedDeviceProfiles(context, gridName, false), false);
Info myInfo = new Info(context, display);
DisplayOption myDisplayOption = invDistWeightedInterpolate(
- myInfo, getPredefinedDeviceProfiles(context, gridName));
+ myInfo, getPredefinedDeviceProfiles(context, gridName, false), false);
DisplayOption result = new DisplayOption(defaultDisplayOption.grid)
.add(myDisplayOption);
result.iconSize = defaultDisplayOption.iconSize;
result.landscapeIconSize = defaultDisplayOption.landscapeIconSize;
- result.numShownHotseatIcons = myDisplayOption.numShownHotseatIcons;
if (defaultDisplayOption.allAppsIconSize < myDisplayOption.allAppsIconSize) {
result.allAppsIconSize = defaultDisplayOption.allAppsIconSize;
- result.numAllAppsColumns = defaultDisplayOption.numAllAppsColumns;
} else {
result.allAppsIconSize = myDisplayOption.allAppsIconSize;
- result.numAllAppsColumns = myDisplayOption.numAllAppsColumns;
}
result.minCellHeight = defaultDisplayOption.minCellHeight;
result.minCellWidth = defaultDisplayOption.minCellWidth;
result.borderSpacing = defaultDisplayOption.borderSpacing;
- initGrid(context, myInfo, result);
+ initGrid(context, myInfo, result, false);
}
public static String getCurrentGridName(Context context) {
- if (ENABLE_TWO_PANEL_HOME.get()) {
- return ENABLE_TWO_PANEL_HOME.key;
- }
return Utilities.isGridOptionsEnabled(context)
? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null;
}
@@ -278,20 +279,33 @@
private String initGrid(Context context, String gridName) {
Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
- ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
+ // Determine if we have split display
- DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
- initGrid(context, displayInfo, displayOption);
+ boolean isTablet = false, isPhone = false;
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ if (displayInfo.isTablet(bounds)) {
+ isTablet = true;
+ } else {
+ isPhone = true;
+ }
+ }
+ boolean isSplitDisplay = isPhone && isTablet && ENABLE_TWO_PANEL_HOME.get();
+
+ ArrayList<DisplayOption> allOptions =
+ getPredefinedDeviceProfiles(context, gridName, isSplitDisplay);
+ DisplayOption displayOption =
+ invDistWeightedInterpolate(displayInfo, allOptions, isSplitDisplay);
+ initGrid(context, displayInfo, displayOption, isSplitDisplay);
return displayOption.grid.name;
}
private void initGrid(
- Context context, Info displayInfo, DisplayOption displayOption) {
+ Context context, Info displayInfo, DisplayOption displayOption,
+ boolean isSplitDisplay) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
- numDatabaseHotseatIcons = closestProfile.numDatabaseHotseatIcons;
dbFile = closestProfile.dbFile;
defaultLayoutId = closestProfile.defaultLayoutId;
demoModeLayoutId = closestProfile.demoModeLayoutId;
@@ -313,8 +327,14 @@
minCellHeight = displayOption.minCellHeight;
minCellWidth = displayOption.minCellWidth;
borderSpacing = displayOption.borderSpacing;
- numShownHotseatIcons = Math.round(displayOption.numShownHotseatIcons);
- numAllAppsColumns = Math.round(displayOption.numAllAppsColumns);
+
+ numShownHotseatIcons = closestProfile.numHotseatIcons;
+ numDatabaseHotseatIcons = isSplitDisplay
+ ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
+
+ numAllAppsColumns = closestProfile.numAllAppsColumns;
+ numDatabaseAllAppsColumns = isSplitDisplay
+ ? closestProfile.numDatabaseAllAppsColumns : closestProfile.numAllAppsColumns;
if (Utilities.isGridOptionsEnabled(context)) {
allAppsIconSize = displayOption.allAppsIconSize;
@@ -332,31 +352,26 @@
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, metrics);
- Point realSize = new Point(displayInfo.realSize);
- // The real size never changes. smallSide and largeSide will remain the
- // same in any orientation.
- int smallSide = Math.min(realSize.x, realSize.y);
- int largeSide = Math.max(realSize.x, realSize.y);
+ supportedProfiles.clear();
+ defaultWallpaperSize = new Point(displayInfo.currentSize);
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ supportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
+ .setUseTwoPanels(isSplitDisplay)
+ .setWindowBounds(bounds).build());
- DeviceProfile.Builder builder = new DeviceProfile.Builder(context, this, displayInfo)
- .setSizeRange(new Point(displayInfo.smallestSize),
- new Point(displayInfo.largestSize));
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "largeSide=" + largeSide + " smallSide=" + smallSide);
- }
+ // Wallpaper size should be the maximum of the all possible sizes Launcher expects
+ int displayWidth = bounds.bounds.width();
+ int displayHeight = bounds.bounds.height();
+ defaultWallpaperSize.y = Math.max(defaultWallpaperSize.y, displayHeight);
- landscapeProfile = builder.setSize(largeSide, smallSide).build();
- portraitProfile = builder.setSize(smallSide, largeSide).build();
-
- // We need to ensure that there is enough extra space in the wallpaper
- // for the intended parallax effects
- if (context.getResources().getConfiguration().smallestScreenWidthDp >= 720) {
- defaultWallpaperSize = new Point(
- (int) (largeSide * wallpaperTravelToScreenWidthRatio(largeSide, smallSide)),
- largeSide);
- } else {
- defaultWallpaperSize = new Point(Math.max(smallSide * 2, largeSide), largeSide);
+ // We need to ensure that there is enough extra space in the wallpaper
+ // for the intended parallax effects
+ float parallaxFactor =
+ dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.densityDpi) < 720
+ ? 2
+ : wallpaperTravelToScreenWidthRatio(displayWidth, displayHeight);
+ defaultWallpaperSize.x =
+ Math.max(defaultWallpaperSize.x, Math.round(parallaxFactor * displayWidth));
}
ComponentName cn = new ComponentName(context.getPackageName(), getClass().getName());
@@ -385,7 +400,7 @@
} else if (!savedIconMaskPath.equals(getIconShapePath(context))) {
getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
.apply();
- apply(context, CHANGE_FLAG_ICON_PARAMS);
+ apply(CHANGE_FLAG_ICON_PARAMS);
}
}
@@ -423,16 +438,17 @@
IconShape.init(context);
}
- apply(context, changeFlags);
+ apply(changeFlags);
}
- private void apply(Context context, int changeFlags) {
+ private void apply(int changeFlags) {
for (OnIDPChangeListener listener : mChangeListeners) {
listener.onIdpChanged(changeFlags, this);
}
}
- static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
+ private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(
+ Context context, String gridName, boolean isSplitDisplay) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
@@ -449,8 +465,9 @@
&& type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG) && "display-option".equals(
parser.getName())) {
- profiles.add(new DisplayOption(
- gridOption, context, Xml.asAttributeSet(parser)));
+ profiles.add(new DisplayOption(gridOption, context,
+ Xml.asAttributeSet(parser),
+ isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE));
}
}
}
@@ -521,17 +538,29 @@
return (float) Math.hypot(x1 - x0, y1 - y0);
}
- @VisibleForTesting
- static DisplayOption invDistWeightedInterpolate(
- Info displayInfo, ArrayList<DisplayOption> points) {
- Point smallestSize = new Point(displayInfo.smallestSize);
- Point largestSize = new Point(displayInfo.largestSize);
+ private static DisplayOption invDistWeightedInterpolate(
+ Info displayInfo, ArrayList<DisplayOption> points, boolean isSplitDisplay) {
+ int minWidthPx = Integer.MAX_VALUE;
+ int minHeightPx = Integer.MAX_VALUE;
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ boolean isTablet = displayInfo.isTablet(bounds);
+ if (isTablet && isSplitDisplay) {
+ // For split displays, take half width per page
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.x / 2);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
- // This guarantees that width < height
- float width = Utilities.dpiFromPx((float) Math.min(smallestSize.x, smallestSize.y),
- displayInfo.densityDpi);
- float height = Utilities.dpiFromPx((float) Math.min(largestSize.x, largestSize.y),
- displayInfo.densityDpi);
+ } else if (!isTablet && bounds.isLandscape()) {
+ // We will use transposed layout in this case
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.y);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.x);
+ } else {
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.x);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
+ }
+ }
+
+ float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
+ float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
// Sort the profiles based on the closeness to the device size
Collections.sort(points, (a, b) ->
@@ -556,33 +585,30 @@
return out.multiply(1.0f / weights);
}
- @VisibleForTesting
- static DisplayOption invDistWeightedInterpolate(float width, float height,
- ArrayList<DisplayOption> points) {
- float weights = 0;
-
- DisplayOption p = points.get(0);
- if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
- return p;
- }
-
- DisplayOption out = new DisplayOption();
- for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
- p = points.get(i);
- float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
- weights += w;
- out.add(new DisplayOption().add(p).multiply(w));
- }
- return out.multiply(1.0f / weights);
- }
-
public DeviceProfile getDeviceProfile(Context context) {
+ Resources res = context.getResources();
+ Configuration config = context.getResources().getConfiguration();
+
+ float availableWidth = config.screenWidthDp * res.getDisplayMetrics().density;
+ float availableHeight = config.screenHeightDp * res.getDisplayMetrics().density;
+
if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "getDeviceProfile: orientation="
- + context.getResources().getConfiguration().orientation);
+ Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
+ "getDeviceProfile: orientation=" + config.orientation
+ + " size=" + availableWidth + "x" + availableHeight);
}
- return context.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE ? landscapeProfile : portraitProfile;
+ DeviceProfile bestMatch = supportedProfiles.get(0);
+ float minDiff = Float.MAX_VALUE;
+
+ for (DeviceProfile profile : supportedProfiles) {
+ float diff = Math.abs(profile.availableWidthPx - availableWidth)
+ + Math.abs(profile.availableHeightPx - availableHeight);
+ if (diff < minDiff) {
+ minDiff = diff;
+ bestMatch = profile;
+ }
+ }
+ return bestMatch;
}
private static float weight(float x0, float y0, float x1, float y1, float pow) {
@@ -639,6 +665,9 @@
private final int numFolderRows;
private final int numFolderColumns;
+ private final int numAllAppsColumns;
+ private final int numDatabaseAllAppsColumns;
+ private final int numHotseatIcons;
private final int numDatabaseHotseatIcons;
private final String dbFile;
@@ -649,8 +678,6 @@
private final boolean isScalable;
private final int devicePaddingId;
- public final boolean visible;
-
private final SparseArray<TypedValue> extraAttrs;
public GridOption(Context context, AttributeSet attrs) {
@@ -665,8 +692,17 @@
R.styleable.GridDisplayOption_defaultLayoutId, 0);
demoModeLayoutId = a.getResourceId(
R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
- numDatabaseHotseatIcons = a.getInt(
+
+ numAllAppsColumns = a.getInt(
+ R.styleable.GridDisplayOption_numAllAppsColumns, numColumns);
+ numDatabaseAllAppsColumns = a.getInt(
+ R.styleable.GridDisplayOption_numExtendedAllAppsColumns, 2 * numAllAppsColumns);
+
+ numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
+ numDatabaseHotseatIcons = a.getInt(
+ R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
+
numFolderRows = a.getInt(
R.styleable.GridDisplayOption_numFolderRows, numRows);
numFolderColumns = a.getInt(
@@ -677,24 +713,21 @@
devicePaddingId = a.getResourceId(
R.styleable.GridDisplayOption_devicePaddingId, 0);
- visible = a.getBoolean(R.styleable.GridDisplayOption_visible, true);
-
a.recycle();
-
extraAttrs = Themes.createValueMap(context, attrs,
IntArray.wrap(R.styleable.GridDisplayOption));
}
}
- private static final class DisplayOption {
- private final GridOption grid;
+ @VisibleForTesting
+ static final class DisplayOption {
+
+ public final GridOption grid;
private final float minWidthDps;
private final float minHeightDps;
private final boolean canBeDefault;
- private float numShownHotseatIcons;
- private float numAllAppsColumns;
private float minCellHeight;
private float minCellWidth;
private float borderSpacing;
@@ -706,7 +739,7 @@
private float allAppsIconSize;
private float allAppsIconTextSize;
- DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
+ DisplayOption(GridOption grid, Context context, AttributeSet attrs, int defaultFlagValue) {
this.grid = grid;
TypedArray a = context.obtainStyledAttributes(
@@ -714,12 +747,9 @@
minWidthDps = a.getFloat(R.styleable.ProfileDisplayOption_minWidthDps, 0);
minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
- canBeDefault = a.getBoolean(
- R.styleable.ProfileDisplayOption_canBeDefault, false);
- numShownHotseatIcons = a.getInt(R.styleable.ProfileDisplayOption_numShownHotseatIcons,
- grid.numDatabaseHotseatIcons);
- numAllAppsColumns = a.getInt(R.styleable.ProfileDisplayOption_numAllAppsColumns,
- grid.numColumns);
+
+ canBeDefault = a.getInt(R.styleable.ProfileDisplayOption_canBeDefault, 0)
+ == defaultFlagValue;
minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0);
minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0);
@@ -748,16 +778,12 @@
minWidthDps = 0;
minHeightDps = 0;
canBeDefault = false;
- numShownHotseatIcons = 0;
- numAllAppsColumns = 0;
minCellHeight = 0;
minCellWidth = 0;
borderSpacing = 0;
}
private DisplayOption multiply(float w) {
- numShownHotseatIcons *= w;
- numAllAppsColumns *= w;
iconSize *= w;
landscapeIconSize *= w;
allAppsIconSize *= w;
@@ -771,8 +797,6 @@
}
private DisplayOption add(DisplayOption p) {
- numShownHotseatIcons += p.numShownHotseatIcons;
- numAllAppsColumns += p.numAllAppsColumns;
iconSize += p.iconSize;
landscapeIconSize += p.landscapeIconSize;
allAppsIconSize += p.allAppsIconSize;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f640118..09c7b7a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -189,7 +189,6 @@
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetManagerHelper;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
@@ -2332,8 +2331,7 @@
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
- Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this,
- pendingInfo);
+ Bundle options = pendingInfo.getDefaultSizeOptions(this);
boolean isDirectConfig =
item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG);
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index c9cc372..fb21698 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -388,12 +388,19 @@
}
protected void pageEndTransition() {
- if (mIsPageInTransition) {
+ if (mIsPageInTransition && !mIsBeingDragged && mScroller.isFinished()
+ && (!isShown() || (mEdgeGlowLeft.isFinished() && mEdgeGlowRight.isFinished()))) {
mIsPageInTransition = false;
onPageEndTransition();
}
}
+ @Override
+ public void onVisibilityAggregated(boolean isVisible) {
+ pageEndTransition();
+ super.onVisibilityAggregated(isVisible);
+ }
+
protected boolean isPageInTransition() {
return mIsPageInTransition;
}
@@ -1740,6 +1747,7 @@
public void draw(Canvas canvas) {
super.draw(canvas);
drawEdgeEffect(canvas);
+ pageEndTransition();
}
protected void drawEdgeEffect(Canvas canvas) {
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 858b72e..05cef38 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -108,13 +108,13 @@
mCurrentAccessibilityAction = action;
if (action == UNINSTALL) {
- setDrawable(R.drawable.ic_uninstall_shadow);
+ setDrawable(R.drawable.ic_uninstall_no_shadow);
updateText(R.string.uninstall_drop_target_label);
} else if (action == DISMISS_PREDICTION) {
- setDrawable(R.drawable.ic_block_shadow);
+ setDrawable(R.drawable.ic_block_no_shadow);
updateText(R.string.dismiss_prediction_label);
} else if (action == RECONFIGURE) {
- setDrawable(R.drawable.ic_setup_shadow);
+ setDrawable(R.drawable.ic_setting);
updateText(R.string.gadget_setup_text);
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 3312915..972a6e8 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -33,6 +33,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
@@ -65,6 +66,7 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
+import android.widget.LinearLayout;
import androidx.core.graphics.ColorUtils;
import androidx.core.os.BuildCompat;
@@ -73,9 +75,9 @@
import com.android.launcher3.graphics.GridCustomizationsProvider;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
+import com.android.launcher3.icons.ThemedIconDrawable.ThemedAdaptiveIcon;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
@@ -83,6 +85,7 @@
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.PackageManagerHelper;
+import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.lang.reflect.Method;
@@ -103,6 +106,8 @@
private static final Pattern sTrimPattern =
Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$");
+ private static final float[] sTmpFloatArray = new float[4];
+
private static final int[] sLoc0 = new int[2];
private static final int[] sLoc1 = new int[2];
private static final Matrix sMatrix = new Matrix();
@@ -132,6 +137,15 @@
Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") ||
Build.TYPE.toLowerCase(Locale.ROOT).equals("eng");
+ /**
+ * Returns true if theme is dark.
+ */
+ public static boolean isDarkTheme(Context context) {
+ Configuration configuration = context.getResources().getConfiguration();
+ int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ return nightMode == Configuration.UI_MODE_NIGHT_YES;
+ }
+
public static boolean isDevelopersOptionsEnabled(Context context) {
return Settings.Global.getInt(context.getApplicationContext().getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
@@ -218,6 +232,33 @@
}
/**
+ * Returns bounds for a child view of DragLayer, in drag layer coordinates.
+ *
+ * see {@link com.android.launcher3.dragndrop.DragLayer}.
+ *
+ * @param viewBounds Bounds of the view wanted in drag layer coordinates, relative to the view
+ * itself. eg. (0, 0, view.getWidth, view.getHeight)
+ * @param ignoreTransform If true, view transform is ignored
+ * @param outRect The out rect where we return the bounds of {@param view} in drag layer coords.
+ */
+ public static void getBoundsForViewInDragLayer(BaseDragLayer dragLayer, View view,
+ Rect viewBounds, boolean ignoreTransform, float[] recycle, RectF outRect) {
+ float[] points = recycle == null ? new float[4] : recycle;
+ points[0] = viewBounds.left;
+ points[1] = viewBounds.top;
+ points[2] = viewBounds.right;
+ points[3] = viewBounds.bottom;
+
+ Utilities.getDescendantCoordRelativeToAncestor(view, dragLayer, points,
+ false, ignoreTransform);
+ outRect.set(
+ Math.min(points[0], points[2]),
+ Math.min(points[1], points[3]),
+ Math.max(points[0], points[2]),
+ Math.max(points[1], points[3]));
+ }
+
+ /**
* Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}.
*/
public static void mapCoordInSelfToDescendant(View descendant, View root, float[] coord) {
@@ -272,6 +313,16 @@
return new int[] {sLoc1[0] - sLoc0[0], sLoc1[1] - sLoc0[1]};
}
+ /**
+ * Helper method to set rectOut with rectFSrc.
+ */
+ public static void setRect(RectF rectFSrc, Rect rectOut) {
+ rectOut.left = (int) rectFSrc.left;
+ rectOut.top = (int) rectFSrc.top;
+ rectOut.right = (int) rectFSrc.right;
+ rectOut.bottom = (int) rectFSrc.bottom;
+ }
+
public static void scaleRectFAboutCenter(RectF r, float scale) {
if (scale != 1.0f) {
float cx = r.centerX();
@@ -595,13 +646,23 @@
*/
public static Drawable getFullDrawable(Launcher launcher, ItemInfo info, int width, int height,
Object[] outObj) {
+ Drawable icon = loadFullDrawableWithoutTheme(launcher, info, width, height, outObj);
+ if (icon instanceof ThemedAdaptiveIcon) {
+ icon = ((ThemedAdaptiveIcon) icon).getThemedDrawable(launcher);
+ }
+ return icon;
+ }
+
+ private static Drawable loadFullDrawableWithoutTheme(Launcher launcher, ItemInfo info,
+ int width, int height, Object[] outObj) {
LauncherAppState appState = LauncherAppState.getInstance(launcher);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
LauncherActivityInfo activityInfo = launcher.getSystemService(LauncherApps.class)
.resolveActivity(info.getIntent(), info.user);
outObj[0] = activityInfo;
- return activityInfo == null ? null : new IconProvider(launcher).getIcon(
- activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
+ return activityInfo == null ? null : LauncherAppState.getInstance(launcher)
+ .getIconCache().getIconProvider().getIcon(
+ activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
@@ -752,6 +813,16 @@
ColorUtils.blendARGB(0, color, tintAmount));
}
+ /**
+ * Sets start margin on the provided {@param view} to be {@param margin}.
+ * Assumes {@param view} is a child of {@link LinearLayout}
+ */
+ public static void setStartMarginForView(View view, int margin) {
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams();
+ lp.setMarginStart(margin);
+ view.setLayoutParams(lp);
+ }
+
private static class FixedSizeEmptyDrawable extends ColorDrawable {
private final int mSize;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 05d6e04..7c5f99e 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -456,7 +456,7 @@
}
private boolean isTwoPanelEnabled() {
- return mLauncher.mDeviceProfile.isTablet && FeatureFlags.ENABLE_TWO_PANEL_HOME.get();
+ return mLauncher.mDeviceProfile.isTwoPanels;
}
@Override
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index aa99d52..c771e3e 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -34,9 +34,9 @@
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
@@ -166,10 +166,9 @@
propertySetter.setFloat(sysUiScrim, SYSUI_PROGRESS,
state.hasFlag(FLAG_HAS_SYS_UI_SCRIM) ? 1 : 0, LINEAR);
-
propertySetter.setViewBackgroundColor(mLauncher.getScrimView(),
state.getWorkspaceScrimColor(mLauncher),
- config.getInterpolator(ANIM_WORKSPACE_SCRIM_FADE, LINEAR));
+ config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
}
public void applyChildState(LauncherState state, CellLayout cl, int childIndex) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 40f7ab1..b11b63e 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -75,7 +75,7 @@
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
- private static final float FLING_VELOCITY_MULTIPLIER = 1800f;
+ private static final float FLING_VELOCITY_MULTIPLIER = 1000f;
// Starts the springs after at least 25% of the animation has passed.
private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
@@ -157,7 +157,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
for (AdapterHolder holder : mAH) {
- holder.adapter.setAppsPerRow(dp.inv.numAllAppsColumns);
+ holder.adapter.setAppsPerRow(dp.numShownAllAppsColumns);
if (holder.recyclerView != null) {
// Remove all views and clear the pool, while keeping the data same. After this
// call, all the viewHolders will be recreated.
@@ -611,7 +611,7 @@
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (shouldSpring
&& valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
- absorbSwipeUpVelocity(-Math.abs(
+ absorbSwipeUpVelocity(Math.abs(
Math.round(velocity * FLING_VELOCITY_MULTIPLIER)));
shouldSpring = false;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 5b4c4c5..70588ea 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -283,7 +283,7 @@
mOnIconClickListener = launcher.getItemOnClickListener();
mSearchAdapterProvider = searchAdapterProvider;
- setAppsPerRow(mLauncher.getDeviceProfile().inv.numAllAppsColumns);
+ setAppsPerRow(mLauncher.getDeviceProfile().numShownAllAppsColumns);
}
public void setAppsPerRow(int appsPerRow) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index c61c0d6..c4c7891 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -15,13 +15,15 @@
*/
package com.android.launcher3.allapps;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
@@ -154,9 +156,9 @@
return;
}
- Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
- ? config.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
- : FAST_OUT_SLOW_IN;
+ Interpolator interpolator = toState.equals(ALL_APPS)
+ ? (config.userControlled ? ACCEL_2 : ACCEL_0_75) :
+ (config.userControlled ? DEACCEL_2 : DEACCEL);
Animator anim = createSpringAnimation(mProgress, targetProgress);
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 7d5ed60..3b88a0b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -87,6 +87,10 @@
public static final BooleanFlag ENABLE_QUICKSTEP_LIVE_TILE = getDebugFlag(
"ENABLE_QUICKSTEP_LIVE_TILE", true, "Enable live tile in Quickstep overview");
+ public static final BooleanFlag ENABLE_QUICKSTEP_WIDGET_APP_START = getDebugFlag(
+ "ENABLE_QUICKSTEP_WIDGET_APP_START", false,
+ "Enable Quickstep animation when launching activities from an app widget");
+
// Keep as DeviceFlag to allow remote disable in emergency.
public static final BooleanFlag ENABLE_SUGGESTED_ACTIONS_OVERVIEW = new DeviceFlag(
"ENABLE_SUGGESTED_ACTIONS_OVERVIEW", true, "Show chip hints on the overview screen");
@@ -137,8 +141,8 @@
public static final BooleanFlag MULTI_DB_GRID_MIRATION_ALGO = getDebugFlag(
"MULTI_DB_GRID_MIRATION_ALGO", true, "Use the multi-db grid migration algorithm");
- public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag(
- "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker");
+ public static final BooleanFlag ENABLE_THEMED_ICONS = getDebugFlag(
+ "ENABLE_THEMED_ICONS", false, "Enable themed icons on workspace");
// Keep as DeviceFlag for remote disable in emergency.
public static final BooleanFlag ENABLE_OVERVIEW_SELECTIONS = new DeviceFlag(
@@ -151,7 +155,7 @@
"ENABLE_OVERVIEW_SHARE", false, "Show Share button in Overview Actions");
public static final BooleanFlag ENABLE_OVERVIEW_SHARING_TO_PEOPLE = getDebugFlag(
- "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", false,
+ "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", true,
"Show indicators for content on Overview to share with top people. ");
public static final BooleanFlag ENABLE_OVERVIEW_CONTENT_PUSH = getDebugFlag(
@@ -226,6 +230,10 @@
public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = new DeviceFlag(
"ENABLE_ENFORCED_ROUNDED_CORNERS", true, "Enforce rounded corners on all App Widgets");
+ public static final BooleanFlag ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER = new DeviceFlag(
+ "ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER", true,
+ "Enables a local filter for recommended widgets.");
+
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false,
"Sends a notification whenever launcher encounters an uncaught exception.");
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index d5a04a6..5ba36f2 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -64,7 +64,6 @@
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.WidgetCellPreview;
-import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetImageView;
import com.android.launcher3.widget.WidgetManagerHelper;
@@ -234,7 +233,7 @@
PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(widgetInfo);
pendingInfo.spanX = Math.min(mIdp.numColumns, widgetInfo.spanX);
pendingInfo.spanY = Math.min(mIdp.numRows, widgetInfo.spanY);
- mWidgetOptions = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
+ mWidgetOptions = pendingInfo.getDefaultSizeOptions(this);
mWidgetCell.getWidgetView().setTag(pendingInfo);
applyWidgetItemAsync(() -> new WidgetItem(widgetInfo, mIdp, mApp.getIconCache()));
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d7f6cdb..575b8fd 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.Utilities.ATLEAST_Q;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.res.Resources;
import android.graphics.Point;
@@ -307,17 +306,12 @@
mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
}
mIsInPreDrag = false;
+ mDragObject.dragView.onDragStart();
for (DragListener listener : new ArrayList<>(mListeners)) {
listener.onDragStart(mDragObject, mOptions);
}
}
- public void addFirstFrameAnimationHelper(ValueAnimator anim) {
- if (mDragObject != null && mDragObject.dragView != null) {
- mDragObject.dragView.mFirstFrameAnimatorHelper.addTo(anim);
- }
- }
-
public Optional<InstanceId> getLogInstanceId() {
return Optional.ofNullable(mDragObject)
.map(dragObject -> dragObject.logInstanceId);
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 68a8af2..30ee9ec 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -51,7 +51,6 @@
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.FirstFrameAnimatorHelper;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
@@ -62,6 +61,7 @@
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
@@ -85,12 +85,13 @@
private final float mScaleOnDrop;
private final int[] mTempLoc = new int[2];
+ private final RunnableList mOnDragStartCallback = new RunnableList();
+
private Point mDragVisualizeOffset = null;
private Rect mDragRegion = null;
private final Launcher mLauncher;
private final DragLayer mDragLayer;
@Thunk final DragController mDragController;
- final FirstFrameAnimatorHelper mFirstFrameAnimatorHelper;
private boolean mHasDrawn = false;
final ValueAnimator mAnim;
@@ -136,7 +137,6 @@
mLauncher = launcher;
mDragLayer = launcher.getDragLayer();
mDragController = launcher.getDragController();
- mFirstFrameAnimatorHelper = new FirstFrameAnimatorHelper(this);
mContent = content;
mWidth = width;
@@ -276,7 +276,8 @@
}
mFgSpringDrawable.setBounds(bounds);
- new Handler(Looper.getMainLooper()).post(() -> {
+ new Handler(Looper.getMainLooper()).post(() -> mOnDragStartCallback.add(() -> {
+ // TODO: Consider fade-in animation
// Assign the variable on the UI thread to avoid race conditions.
mScaledMaskPath = mask;
// Avoid relayout as we do not care about children affecting layout
@@ -290,11 +291,18 @@
mBadge.setColorFilter(d.getColorFilter());
}
invalidate();
- });
+ }));
}
});
}
+ /**
+ * Called when pre-drag finishes for an icon
+ */
+ public void onDragStart() {
+ mOnDragStartCallback.executeAllAndDestroy();
+ }
+
// TODO(b/183609936): This is only for LauncherAppWidgetHostView that is rendered in a drawable.
// Once LauncherAppWidgetHostView is directly rendered in this view, removes this method.
@Override
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 767fffe..5ddf84f 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -50,6 +50,8 @@
*/
public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
+ private static final boolean DRAW_SHADOW = false;
+
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
private final PorterDuffXfermode mShadowPorterDuffXfermode
@@ -163,13 +165,15 @@
// Stroke width is 1dp
mStrokeWidth = context.getResources().getDisplayMetrics().density;
- float radius = getScaledRadius();
- float shadowRadius = radius + mStrokeWidth;
- int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
- mShadowShader = new RadialGradient(0, 0, 1,
- new int[] {shadowColor, Color.TRANSPARENT},
- new float[] {radius / shadowRadius, 1},
- Shader.TileMode.CLAMP);
+ if (DRAW_SHADOW) {
+ float radius = getScaledRadius();
+ float shadowRadius = radius + mStrokeWidth;
+ int shadowColor = Color.argb(SHADOW_OPACITY, 0, 0, 0);
+ mShadowShader = new RadialGradient(0, 0, 1,
+ new int[]{shadowColor, Color.TRANSPARENT},
+ new float[]{radius / shadowRadius, 1},
+ Shader.TileMode.CLAMP);
+ }
invalidate();
}
@@ -239,6 +243,9 @@
}
public void drawShadow(Canvas canvas) {
+ if (!DRAW_SHADOW) {
+ return;
+ }
if (mShadowShader == null) {
return;
}
@@ -277,6 +284,9 @@
}
public void fadeInBackgroundShadow() {
+ if (!DRAW_SHADOW) {
+ return;
+ }
if (mShadowAnimator != null) {
mShadowAnimator.cancel();
}
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 8244f01..6adef01 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -400,7 +400,7 @@
drawable.setLevel(item.getProgressLevel());
p.drawable = drawable;
} else {
- p.drawable = item.newIcon(mContext);
+ p.drawable = item.newIcon(mContext, true);
}
p.drawable.setBounds(0, 0, mIconSize, mIconSize);
p.item = item;
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index 911f8c3..cb42e7a 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -90,10 +90,7 @@
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption option = new GridOption(getContext(), Xml.asAttributeSet(parser));
- if (option.visible) {
- result.add(option);
- }
+ result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
}
}
} catch (IOException | XmlPullParserException e) {
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 31764c5..f5b6890 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -20,7 +20,6 @@
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
@@ -118,7 +117,7 @@
* 4) Measure and draw the view on a canvas
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherPreviewRenderer extends ContextThemeWrapper
+public class LauncherPreviewRenderer extends ContextWrapper
implements ActivityContext, WorkspaceLayoutManager, LayoutInflater.Factory2 {
private static final String TAG = "LauncherPreviewRenderer";
@@ -220,11 +219,11 @@
private final CellLayout mWorkspace;
public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
- super(context, R.style.AppTheme);
+ super(context);
mUiHandler = new Handler(Looper.getMainLooper());
mContext = context;
mIdp = idp;
- mDp = idp.portraitProfile.copy(context);
+ mDp = idp.getDeviceProfile(context).copy(context);
mMigrated = migrated;
// TODO: get correct insets once display cutout API is available.
@@ -271,14 +270,6 @@
return mRootView;
}
- public boolean shouldShowRealLauncherPreview() {
- return ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get();
- }
-
- public boolean shouldShowQsb() {
- return FeatureFlags.QSB_ON_FIRST_SCREEN;
- }
-
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
if ("TextClock".equals(name)) {
@@ -402,107 +393,88 @@
}
private void populate() {
- if (shouldShowRealLauncherPreview()) {
- WorkspaceFetcher fetcher;
- PreviewContext previewContext = null;
- if (mMigrated) {
- previewContext = new PreviewContext(mContext, mIdp);
- LauncherAppState appForPreview = new LauncherAppState(
- previewContext, null /* iconCacheFileName */);
- fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
- MODEL_EXECUTOR.execute(fetcher);
- } else {
- fetcher = new WorkspaceItemsInfoFetcher();
- LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
- (LauncherModel.ModelUpdateTask) fetcher);
- }
- WorkspaceResult workspaceResult = fetcher.get();
- if (previewContext != null) {
- previewContext.onDestroy();
- }
-
- if (workspaceResult == null) {
- return;
- }
-
- // Separate the items that are on the current screen, and the other remaining items.
- ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
- ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
- ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
- ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
- filterCurrentWorkspaceItems(0 /* currentScreenId */,
- workspaceResult.mWorkspaceItems, currentWorkspaceItems,
- otherWorkspaceItems);
- filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
- currentAppWidgets, otherAppWidgets);
- sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
- for (ItemInfo itemInfo : currentWorkspaceItems) {
- switch (itemInfo.itemType) {
- case Favorites.ITEM_TYPE_APPLICATION:
- case Favorites.ITEM_TYPE_SHORTCUT:
- case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
- break;
- case Favorites.ITEM_TYPE_FOLDER:
- inflateAndAddFolder((FolderInfo) itemInfo);
- break;
- default:
- break;
- }
- }
- for (ItemInfo itemInfo : currentAppWidgets) {
- switch (itemInfo.itemType) {
- case Favorites.ITEM_TYPE_APPWIDGET:
- case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
- if (mMigrated) {
- inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
- workspaceResult.mWidgetProvidersMap);
- } else {
- inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
- workspaceResult.mWidgetsModel);
- }
- break;
- default:
- break;
- }
- }
- IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
- mDp.numShownHotseatIcons);
- List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
- ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
- int count = Math.min(ranks.size(), predictions.size());
- for (int i = 0; i < count; i++) {
- int rank = ranks.get(i);
- WorkspaceItemInfo itemInfo =
- new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
- itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
- itemInfo.rank = rank;
- itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
- itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
- itemInfo.screenId = rank;
- inflateAndAddPredictedIcon(itemInfo);
- }
+ WorkspaceFetcher fetcher;
+ PreviewContext previewContext = null;
+ if (mMigrated) {
+ previewContext = new PreviewContext(mContext, mIdp);
+ LauncherAppState appForPreview = new LauncherAppState(
+ previewContext, null /* iconCacheFileName */);
+ fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
+ MODEL_EXECUTOR.execute(fetcher);
} else {
- // Add hotseat icons
- for (int i = 0; i < mDp.numShownHotseatIcons; i++) {
- WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
- info.container = Favorites.CONTAINER_HOTSEAT;
- info.screenId = i;
- inflateAndAddIcon(info);
+ fetcher = new WorkspaceItemsInfoFetcher();
+ LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
+ (LauncherModel.ModelUpdateTask) fetcher);
+ }
+ WorkspaceResult workspaceResult = fetcher.get();
+ if (previewContext != null) {
+ previewContext.onDestroy();
+ }
+
+ if (workspaceResult == null) {
+ return;
+ }
+
+ // Separate the items that are on the current screen, and the other remaining items.
+ ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
+ ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
+ ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
+ ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
+ filterCurrentWorkspaceItems(0 /* currentScreenId */,
+ workspaceResult.mWorkspaceItems, currentWorkspaceItems,
+ otherWorkspaceItems);
+ filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
+ currentAppWidgets, otherAppWidgets);
+ sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
+ for (ItemInfo itemInfo : currentWorkspaceItems) {
+ switch (itemInfo.itemType) {
+ case Favorites.ITEM_TYPE_APPLICATION:
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
+ break;
+ case Favorites.ITEM_TYPE_FOLDER:
+ inflateAndAddFolder((FolderInfo) itemInfo);
+ break;
+ default:
+ break;
}
- // Add workspace icons
- for (int i = 0; i < mIdp.numColumns; i++) {
- WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
- info.container = Favorites.CONTAINER_DESKTOP;
- info.screenId = 0;
- info.cellX = i;
- info.cellY = mIdp.numRows - 1;
- inflateAndAddIcon(info);
+ }
+ for (ItemInfo itemInfo : currentAppWidgets) {
+ switch (itemInfo.itemType) {
+ case Favorites.ITEM_TYPE_APPWIDGET:
+ case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
+ if (mMigrated) {
+ inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+ workspaceResult.mWidgetProvidersMap);
+ } else {
+ inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+ workspaceResult.mWidgetsModel);
+ }
+ break;
+ default:
+ break;
}
}
+ IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
+ mDp.numShownHotseatIcons);
+ List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
+ ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
+ int count = Math.min(ranks.size(), predictions.size());
+ for (int i = 0; i < count; i++) {
+ int rank = ranks.get(i);
+ WorkspaceItemInfo itemInfo =
+ new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
+ itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
+ itemInfo.rank = rank;
+ itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
+ itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
+ itemInfo.screenId = rank;
+ inflateAndAddPredictedIcon(itemInfo);
+ }
// Add first page QSB
- if (shouldShowQsb()) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
View qsb = mHomeElementInflater.inflate(
R.layout.search_container_workspace, mWorkspace, false);
CellLayout.LayoutParams lp =
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 13ae866..e45b8f7 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -21,7 +21,6 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
@@ -34,6 +33,7 @@
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.GraphicsUtils;
@@ -119,9 +119,7 @@
info,
IconPalette.getPreloadProgressColor(context, info.bitmap.color),
getPreloadColors(context),
- (context.getResources().getConfiguration().uiMode
- & Configuration.UI_MODE_NIGHT_MASK
- & Configuration.UI_MODE_NIGHT_YES) != 0) /* isDarkMode */;
+ Utilities.isDarkTheme(context));
}
public PreloadIconDrawable(
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index fdc3a94..6193570 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import android.app.WallpaperColors;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
@@ -28,18 +29,23 @@
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.R;
import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.model.GridSizeMigrationTaskV2;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.LocalColorExtractor;
import java.util.concurrent.TimeUnit;
/** Render preview using surface view. */
+@SuppressWarnings("NewApi")
public class PreviewSurfaceRenderer implements IBinder.DeathRecipient {
private static final int FADE_IN_ANIMATION_DURATION = 200;
@@ -50,6 +56,7 @@
private static final String KEY_DISPLAY_ID = "display_id";
private static final String KEY_SURFACE_PACKAGE = "surface_package";
private static final String KEY_CALLBACK = "callback";
+ private static final String KEY_COLORS = "wallpaper_colors";
private final Context mContext;
private final InvariantDeviceProfile mIdp;
@@ -57,6 +64,7 @@
private final int mWidth;
private final int mHeight;
private final Display mDisplay;
+ private final WallpaperColors mWallpaperColors;
private SurfaceControlViewHost mSurfaceControlViewHost;
@@ -68,6 +76,8 @@
if (gridName == null) {
gridName = InvariantDeviceProfile.getCurrentGridName(context);
}
+ mWallpaperColors = bundle.getParcelable(KEY_COLORS);
+
mIdp = new InvariantDeviceProfile(context, gridName);
mHostToken = bundle.getBinder(KEY_HOST_TOKEN);
@@ -100,6 +110,19 @@
MODEL_EXECUTOR.post(() -> {
final boolean success = doGridMigrationIfNecessary();
+ final Context inflationContext;
+ if (mWallpaperColors != null) {
+ // Workaround to create a themed context
+ Context context = mContext.createDisplayContext(mDisplay);
+ LocalColorExtractor.newInstance(mContext)
+ .applyColorsOverride(context, mWallpaperColors);
+
+ inflationContext = new ContextThemeWrapper(context,
+ Themes.getActivityThemeRes(context, mWallpaperColors.getColorHints()));
+ } else {
+ inflationContext = new ContextThemeWrapper(mContext, R.style.AppTheme);
+ }
+
MAIN_EXECUTOR.post(() -> {
// If mSurfaceControlViewHost is null due to any reason (e.g. binder died,
// happening when user leaves the preview screen before preview rendering finishes),
@@ -109,7 +132,8 @@
return;
}
- View view = new LauncherPreviewRenderer(mContext, mIdp, success).getRenderedView();
+ View view = new LauncherPreviewRenderer(inflationContext, mIdp, success)
+ .getRenderedView();
// This aspect scales the view to fit in the surface and centers it
final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(),
mHeight / (float) view.getMeasuredHeight());
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index a2c0f5c..bc93a1e 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -52,7 +52,6 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
@@ -94,7 +93,7 @@
mLauncherApps = mContext.getSystemService(LauncherApps.class);
mUserManager = UserCache.INSTANCE.get(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
- mIconProvider = new IconProvider(context);
+ mIconProvider = new IconProvider(context, true /* supportsIconTheme */);
}
@Override
@@ -107,8 +106,12 @@
return mInstantAppResolver.isInstantApp(info);
}
+ public IconProvider getIconProvider() {
+ return mIconProvider;
+ }
+
@Override
- protected BaseIconFactory getIconFactory() {
+ public BaseIconFactory getIconFactory() {
return LauncherIcons.obtain(mContext);
}
@@ -333,15 +336,6 @@
+ ",flags_asi:" + FeatureFlags.APP_SEARCH_IMPROVEMENTS.get();
}
- @Override
- protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
- if (mIconProvider.isClockIcon(cacheKey)) {
- // For clock icon, we always load the dynamic icon
- return false;
- }
- return super.getEntryFromDB(cacheKey, entry, lowRes);
- }
-
/**
* Interface for receiving itemInfo with high-res icon.
*/
diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
index 93de35a..8fc3977 100644
--- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
+++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
@@ -20,6 +20,7 @@
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -56,8 +57,8 @@
@Override
public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) {
try (LauncherIcons li = LauncherIcons.obtain(context)) {
- return li.createBadgedIconBitmap(new IconProvider(context)
- .getIcon(object, li.mFillResIconDpi),
+ return li.createBadgedIconBitmap(LauncherAppState.getInstance(context)
+ .getIconCache().getIconProvider().getIcon(object, li.mFillResIconDpi),
object.getUser(), object.getApplicationInfo().targetSdkVersion);
}
}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 05fd77d..e388965 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -366,7 +366,7 @@
return itemBuilder.build();
}
- LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
+ protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
itemBuilder.setIsWork(user != Process.myUserHandle());
return itemBuilder;
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 76b2ab0..0754c29 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -16,6 +16,8 @@
package com.android.launcher3.model.data;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -223,7 +225,15 @@
* Returns a FastBitmapDrawable with the icon.
*/
public FastBitmapDrawable newIcon(Context context) {
- FastBitmapDrawable drawable = bitmap.newIcon(context);
+ return newIcon(context, false);
+ }
+
+ /**
+ * Returns a FastBitmapDrawable with the icon and context theme applied
+ */
+ public FastBitmapDrawable newIcon(Context context, boolean applyTheme) {
+ FastBitmapDrawable drawable = applyTheme && ENABLE_THEMED_ICONS.get()
+ ? bitmap.newThemedIcon(context) : bitmap.newIcon(context);
drawable.setIsDisabled(isDisabled());
return drawable;
}
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
index b3057d5..0eea92c 100644
--- a/src/com/android/launcher3/model/data/SearchActionItemInfo.java
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -94,6 +94,11 @@
"SearchActionItemInfo can only have either an Intent or a PendingIntent");
}
mIntent = intent;
+ // bandage fix for just one week
+ if (intent != null && "com.android.server.telecom".equals(intent.getPackage())) {
+ intent.setAction(Intent.ACTION_DIAL);
+ intent.setPackage(null);
+ }
}
public PendingIntent getPendingIntent() {
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index c19dfe9..c63d69d 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -16,7 +16,6 @@
package com.android.launcher3.popup;
-import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
@@ -31,6 +30,7 @@
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -41,17 +41,21 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.dragndrop.DragLayer;
@@ -59,9 +63,11 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.LocalColorExtractor;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
/**
* A container for shortcuts to deep links and notifications associated with an app.
@@ -73,6 +79,9 @@
// +1 for system shortcut view
private static final int MAX_NUM_CHILDREN = MAX_SHORTCUTS + 1;
+ // Index used to get background color when using local wallpaper color extraction,
+ private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
+ private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_800;
private final Rect mTempRect = new Rect();
@@ -104,8 +113,14 @@
private Runnable mOnCloseCallback = () -> { };
+ // The rect string of the view that the arrow is attached to, in screen reference frame.
+ private String mArrowColorRectString;
private int mArrowColor;
private final int[] mColors;
+ private final HashMap<String, View> mViewForRect = new HashMap<>();
+
+ private final int mColorExtractionIndex;
+ @Nullable private LocalColorExtractor mColorExtractor;
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@@ -113,7 +128,9 @@
mOutlineRadius = Themes.getDialogCornerRadius(context);
mLauncher = BaseDraggingActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
-
+ mColorExtractionIndex = Utilities.isDarkTheme(context)
+ ? DARK_COLOR_EXTRACTION_INDEX
+ : LIGHT_COLOR_EXTRACTION_INDEX;
setClipToOutline(true);
setOutlineProvider(new ViewOutlineProvider() {
@Override
@@ -158,6 +175,10 @@
mColors[i] =
(int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor);
}
+
+ if (Utilities.ATLEAST_S) {
+ setupColorExtraction();
+ }
}
}
@@ -342,6 +363,15 @@
// so we centered it instead. In that case we don't want to showDefaultOptions the arrow.
mArrow.setVisibility(INVISIBLE);
} else {
+ updateArrowColor();
+ }
+
+ mArrow.setPivotX(mArrowWidth / 2.0f);
+ mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
+ }
+
+ private void updateArrowColor() {
+ if (!Gravity.isVertical(mGravity)) {
mArrow.setBackground(new RoundedArrowDrawable(
mArrowWidth, mArrowHeight, mArrowPointRadius,
mOutlineRadius, getMeasuredWidth(), getMeasuredHeight(),
@@ -350,9 +380,6 @@
mArrowColor));
mArrow.setElevation(getElevation());
}
-
- mArrow.setPivotX(mArrowWidth / 2.0f);
- mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
}
/**
@@ -671,6 +698,12 @@
getPopupContainer().removeView(this);
getPopupContainer().removeView(mArrow);
mOnCloseCallback.run();
+ mArrowColorRectString = null;
+ mViewForRect.clear();
+ if (mColorExtractor != null) {
+ mColorExtractor.removeLocations();
+ mColorExtractor.setListener(null);
+ }
}
/**
@@ -680,6 +713,68 @@
mOnCloseCallback = callback;
}
+ private void setupColorExtraction() {
+ Workspace workspace = mLauncher.findViewById(R.id.workspace);
+ if (workspace == null) {
+ return;
+ }
+
+ mColorExtractor = LocalColorExtractor.newInstance(mLauncher);
+ mColorExtractor.setListener((rect, extractedColors) -> {
+ String rectString = rect.toShortString();
+ View v = mViewForRect.get(rectString);
+ if (v != null) {
+ int newColor = extractedColors.get(mColorExtractionIndex);
+ setChildColor(v, newColor);
+ if (rectString.equals(mArrowColorRectString)) {
+ mArrowColor = newColor;
+ updateArrowColor();
+ }
+ }
+ });
+
+ getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ getViewTreeObserver().removeOnPreDrawListener(this);
+
+ ArrayList<RectF> locations = new ArrayList<>();
+ Rect r = new Rect();
+
+ int count = getChildCount();
+ int numVisibleChild = 0;
+ for (int i = 0; i < count; i++) {
+ View view = getChildAt(i);
+ if (view.getVisibility() == VISIBLE) {
+ RectF rf = new RectF();
+ mColorExtractor.getExtractedRectForView(Launcher.getLauncher(getContext()),
+ workspace.getCurrentPage(), view, rf);
+ if (rf.isEmpty()) {
+ numVisibleChild++;
+ continue;
+ }
+
+ locations.add(rf);
+ String rectString = rf.toShortString();
+ mViewForRect.put(rectString, view);
+
+ // Arrow color matches the first child or the last child.
+ if (!mIsAboveIcon && numVisibleChild == 0) {
+ mArrowColorRectString = rectString;
+ } else if (mIsAboveIcon) {
+ mArrowColorRectString = rectString;
+ }
+
+ numVisibleChild++;
+ }
+ }
+
+ mColorExtractor.addLocation(locations);
+ return false;
+ }
+ });
+ }
+
protected BaseDragLayer getPopupContainer() {
return mLauncher.getDragLayer();
}
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index a191df4..22c3f58 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -20,7 +20,7 @@
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_PROVIDER;
-import static com.android.launcher3.Utilities.ATLEAST_S;
+import static com.android.launcher3.AppWidgetResizeFrame.getWidgetSizeOptions;
import android.app.Activity;
import android.app.Fragment;
@@ -32,11 +32,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.graphics.Rect;
import android.os.Bundle;
import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.SizeF;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -45,7 +43,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
@@ -53,8 +50,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.FragmentWithPreview;
-import java.util.ArrayList;
-
/**
* A frame layout which contains a QSB. This internally uses fragment to bind the view, which
* allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}.
@@ -163,7 +158,7 @@
protected String mKeyWidgetId = "qsb_widget_id";
private QsbWidgetHost mQsbWidgetHost;
- private AppWidgetProviderInfo mWidgetInfo;
+ protected AppWidgetProviderInfo mWidgetInfo;
private QsbWidgetHostView mQsb;
// We need to store the orientation here, due to a bug (b/64916689) that results in widgets
@@ -297,19 +292,7 @@
protected Bundle createBindOptions() {
InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext());
-
- Bundle opts = new Bundle();
- ArrayList<SizeF> sizes = AppWidgetResizeFrame
- .getWidgetSizes(getContext(), idp.numColumns, 1);
- Rect size = AppWidgetResizeFrame.getMinMaxSizes(sizes, null /* outRect */);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom);
- if (ATLEAST_S) {
- opts.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizes);
- }
- return opts;
+ return getWidgetSizeOptions(getContext(), mWidgetInfo.provider, idp.numColumns, 1);
}
protected View getDefaultView(ViewGroup container, boolean showSetupIcon) {
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index f5e74b7..5999091 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -87,8 +87,8 @@
if (mDragLayer != null) {
return;
}
- InvariantDeviceProfile currentDisplayIdp =
- new InvariantDeviceProfile(this, getWindow().getDecorView().getDisplay());
+ InvariantDeviceProfile currentDisplayIdp = new InvariantDeviceProfile(
+ this, getWindow().getDecorView().getDisplay());
// Disable transpose layout and use multi-window mode so that the icons are scaled properly
mDeviceProfile = currentDisplayIdp.getDeviceProfile(this)
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index 40630d3..f78f6dd 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -29,7 +29,6 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.model.data.ItemInfo;
@@ -109,8 +108,6 @@
setMeasuredDimension(width, height);
DeviceProfile grid = mActivity.getDeviceProfile();
- InvariantDeviceProfile idp = grid.inv;
-
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
@@ -118,10 +115,10 @@
int padding = 2 * (grid.desiredWorkspaceLeftRightMarginPx
+ grid.cellLayoutPaddingLeftRightPx);
- int maxWidth = grid.allAppsCellWidthPx * idp.numAllAppsColumns + padding;
+ int maxWidth = grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + padding;
int appsWidth = Math.min(width, maxWidth);
- int maxHeight = grid.allAppsCellHeightPx * idp.numAllAppsColumns + padding;
+ int maxHeight = grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + padding;
int appsHeight = Math.min(height, maxHeight);
mAppsView.measure(
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 2f26b4f..bd6f7d3 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -58,8 +58,7 @@
ANIM_OVERVIEW_TRANSLATE_Y,
ANIM_OVERVIEW_FADE,
ANIM_ALL_APPS_FADE,
- ANIM_WORKSPACE_SCRIM_FADE,
- ANIM_ALL_APPS_HEADER_FADE,
+ ANIM_SCRIM_FADE,
ANIM_OVERVIEW_MODAL,
ANIM_DEPTH,
ANIM_OVERVIEW_ACTIONS_FADE,
@@ -77,13 +76,12 @@
public static final int ANIM_OVERVIEW_TRANSLATE_Y = 8;
public static final int ANIM_OVERVIEW_FADE = 9;
public static final int ANIM_ALL_APPS_FADE = 10;
- public static final int ANIM_WORKSPACE_SCRIM_FADE = 11;
- public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
- public static final int ANIM_OVERVIEW_MODAL = 13;
- public static final int ANIM_DEPTH = 14;
- public static final int ANIM_OVERVIEW_ACTIONS_FADE = 15;
+ public static final int ANIM_SCRIM_FADE = 11;
+ public static final int ANIM_OVERVIEW_MODAL = 12;
+ public static final int ANIM_DEPTH = 13;
+ public static final int ANIM_OVERVIEW_ACTIONS_FADE = 14;
- private static final int ANIM_TYPES_COUNT = 16;
+ private static final int ANIM_TYPES_COUNT = 15;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 2254ab3..2fd5efc 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -254,16 +254,21 @@
}
@Override
- public int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate,
+ public void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile,
LinearLayout taskMenuLayout) {
- return LinearLayout.HORIZONTAL;
+ taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
}
@Override
- public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
+ public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+ LinearLayout viewGroup, DeviceProfile deviceProfile) {
+ // Phone fake landscape
+ viewGroup.setOrientation(LinearLayout.VERTICAL);
lp.width = 0;
lp.height = WRAP_CONTENT;
lp.weight = 1;
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
}
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index c9149ff..6c2f17e 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -101,8 +101,9 @@
float getTaskMenuX(float x, View thumbnailView, int overScroll);
float getTaskMenuY(float y, View thumbnailView, int overScroll);
int getTaskMenuWidth(View view);
- int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate, LinearLayout taskMenuLayout);
- void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp);
+ void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile, LinearLayout taskMenuLayout);
+ void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+ LinearLayout viewGroup, DeviceProfile deviceProfile);
int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect);
List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp);
FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 31586e7..9358c49 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -253,14 +253,34 @@
}
@Override
- public int getTaskMenuLayoutOrientation(boolean canRecentsActivityRotate,
+ public void setTaskMenuLayoutOrientation(DeviceProfile deviceProfile,
LinearLayout taskMenuLayout) {
- return canRecentsActivityRotate ? taskMenuLayout.getOrientation() : LinearLayout.VERTICAL;
+ if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+ // Phone landscape
+ taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
+ } else {
+ // Phone Portrait, LargeScreen Landscape/Portrait
+ taskMenuLayout.setOrientation(LinearLayout.VERTICAL);
+ }
}
@Override
- public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp) {
- // no-op, defaults are fine
+ public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
+ LinearLayout viewGroup, DeviceProfile deviceProfile) {
+ if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+ // Phone landscape
+ viewGroup.setOrientation(LinearLayout.VERTICAL);
+ lp.width = 0;
+ lp.weight = 1;
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
+ } else {
+ // Phone Portrait, LargeScreen Landscape/Portrait
+ viewGroup.setOrientation(LinearLayout.HORIZONTAL);
+ lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
+ }
+
+ lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
}
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 75c089e..b751207 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -18,8 +18,10 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@@ -32,16 +34,22 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
+import android.util.ArraySet;
import android.util.Log;
import android.view.Display;
+import android.view.WindowMetrics;
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.ApiWrapper;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
/**
* Utility class to cache properties of default display to avoid a system RPC on every call.
@@ -54,13 +62,14 @@
public static final MainThreadInitializedObject<DisplayController> INSTANCE =
new MainThreadInitializedObject<>(DisplayController::new);
- public static final int CHANGE_SIZE = 1 << 0;
+ public static final int CHANGE_ACTIVE_SCREEN = 1 << 0;
public static final int CHANGE_ROTATION = 1 << 1;
public static final int CHANGE_FRAME_DELAY = 1 << 2;
public static final int CHANGE_DENSITY = 1 << 3;
+ public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 4;
- public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION
- | CHANGE_FRAME_DELAY | CHANGE_DENSITY;
+ public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
+ | CHANGE_FRAME_DELAY | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
private final Context mContext;
private final DisplayManager mDM;
@@ -87,7 +96,22 @@
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
- mInfo = new Info(getContext(display), display);
+ // Create a single holder for all internal displays. External display holders created
+ // lazily.
+ Set<PortraitSize> extraInternalDisplays = new ArraySet<>();
+ for (Display d : mDM.getDisplays()) {
+ if (ApiWrapper.isInternalDisplay(display) && d.getDisplayId() != DEFAULT_DISPLAY) {
+ Point size = new Point();
+ d.getRealSize(size);
+ extraInternalDisplays.add(new PortraitSize(size.x, size.y));
+ }
+ }
+
+ if (extraInternalDisplays.isEmpty() || !Utilities.ATLEAST_S) {
+ mInfo = new Info(createDisplayInfoContext(display), display, Collections.emptySet());
+ } else {
+ mInfo = new Info(mWindowContext, display, extraInternalDisplays);
+ }
mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
}
@@ -139,7 +163,7 @@
*/
private void onConfigChanged(Intent intent) {
Configuration config = mContext.getResources().getConfiguration();
- if (config.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
+ if (mInfo.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
Log.d(TAG, "Configuration changed, notifying listeners");
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (display != null) {
@@ -157,8 +181,7 @@
|| config.fontScale != mInfo.fontScale
|| display.getRotation() != mInfo.rotation
|| !mInfo.mScreenSizeDp.equals(
- Math.min(config.screenHeightDp, config.screenWidthDp),
- Math.max(config.screenHeightDp, config.screenWidthDp))) {
+ new PortraitSize(config.screenHeightDp, config.screenWidthDp))) {
handleInfoChange(display);
}
}
@@ -178,18 +201,23 @@
return mInfo;
}
- private Context getContext(Display display) {
- return Utilities.ATLEAST_S ? mWindowContext : mContext.createDisplayContext(display);
+ private Context createDisplayInfoContext(Display display) {
+ return Utilities.ATLEAST_S
+ ? mContext.createWindowContext(display, TYPE_APPLICATION, null)
+ : mContext.createDisplayContext(display);
}
@AnyThread
private void handleInfoChange(Display display) {
Info oldInfo = mInfo;
- Context context = getContext(display);
- Info newInfo = new Info(context, display);
+ Set<PortraitSize> extraDisplaysSizes = oldInfo.mAllSizes.size() > 1
+ ? oldInfo.mAllSizes : Collections.emptySet();
+
+ Context displayContext = createDisplayInfoContext(display);
+ Info newInfo = new Info(displayContext, display, extraDisplaysSizes);
int change = 0;
- if (newInfo.hasDifferentSize(oldInfo)) {
- change |= CHANGE_SIZE;
+ if (!newInfo.mScreenSizeDp.equals(oldInfo.mScreenSizeDp)) {
+ change |= CHANGE_ACTIVE_SCREEN;
}
if (newInfo.rotation != oldInfo.rotation) {
change |= CHANGE_ROTATION;
@@ -200,11 +228,14 @@
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
change |= CHANGE_DENSITY;
}
+ if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)) {
+ change |= CHANGE_SUPPORTED_BOUNDS;
+ }
if (change != 0) {
mInfo = newInfo;
final int flags = change;
- MAIN_EXECUTOR.execute(() -> notifyChange(context, flags));
+ MAIN_EXECUTOR.execute(() -> notifyChange(displayContext, flags));
}
}
@@ -224,13 +255,18 @@
public final float fontScale;
public final int densityDpi;
- private final Point mScreenSizeDp;
+ private final PortraitSize mScreenSizeDp;
+ private final Set<PortraitSize> mAllSizes;
- public final Point realSize;
- public final Point smallestSize;
- public final Point largestSize;
+ public final Point currentSize;
+
+ public final Set<WindowBounds> supportedBounds = new ArraySet<>();
public Info(Context context, Display display) {
+ this(context, display, Collections.emptySet());
+ }
+
+ private Info(Context context, Display display, Set<PortraitSize> extraDisplaysSizes) {
id = display.getDisplayId();
rotation = display.getRotation();
@@ -238,35 +274,67 @@
Configuration config = context.getResources().getConfiguration();
fontScale = config.fontScale;
densityDpi = config.densityDpi;
- mScreenSizeDp = new Point(
- Math.min(config.screenHeightDp, config.screenWidthDp),
- Math.max(config.screenHeightDp, config.screenWidthDp));
+ mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
singleFrameMs = getSingleFrameMs(display);
+ currentSize = new Point();
- realSize = new Point();
- smallestSize = new Point();
- largestSize = new Point();
+ display.getRealSize(currentSize);
- display.getRealSize(realSize);
- display.getCurrentSizeRange(smallestSize, largestSize);
+ if (extraDisplaysSizes.isEmpty() || !Utilities.ATLEAST_S) {
+ Point smallestSize = new Point();
+ Point largestSize = new Point();
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ int portraitWidth = Math.min(currentSize.x, currentSize.y);
+ int portraitHeight = Math.max(currentSize.x, currentSize.y);
+
+ supportedBounds.add(new WindowBounds(portraitWidth, portraitHeight,
+ smallestSize.x, largestSize.y));
+ supportedBounds.add(new WindowBounds(portraitHeight, portraitWidth,
+ largestSize.x, smallestSize.y));
+ mAllSizes = Collections.singleton(new PortraitSize(currentSize.x, currentSize.y));
+ } else {
+ mAllSizes = new ArraySet<>(extraDisplaysSizes);
+ mAllSizes.add(new PortraitSize(currentSize.x, currentSize.y));
+ Set<WindowMetrics> metrics = WindowManagerCompat.getDisplayProfiles(
+ context, mAllSizes, densityDpi,
+ ApiWrapper.TASKBAR_DRAWN_IN_PROCESS);
+ metrics.forEach(wm -> supportedBounds.add(WindowBounds.fromWindowMetrics(wm)));
+ }
}
- private boolean hasDifferentSize(Info info) {
- if (!realSize.equals(info.realSize)
- && !realSize.equals(info.realSize.y, info.realSize.x)) {
- Log.d(TAG, String.format("Display size changed from %s to %s",
- info.realSize, realSize));
- return true;
- }
+ /**
+ * Returns 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;
+ }
+ }
- if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) {
- Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
- smallestSize, largestSize, info.smallestSize, info.largestSize));
- return true;
- }
+ /**
+ * Utility class to hold a size information in an orientation independent way
+ */
+ public static class PortraitSize {
+ public final int width, height;
- return false;
+ public PortraitSize(int w, int h) {
+ width = Math.min(w, h);
+ height = Math.max(w, h);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PortraitSize that = (PortraitSize) o;
+ return width == that.width && height == that.height;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(width, height);
}
}
diff --git a/src/com/android/launcher3/util/RunnableList.java b/src/com/android/launcher3/util/RunnableList.java
index 55add14..644537b 100644
--- a/src/com/android/launcher3/util/RunnableList.java
+++ b/src/com/android/launcher3/util/RunnableList.java
@@ -29,6 +29,9 @@
* Ads a runnable to this list
*/
public void add(Runnable runnable) {
+ if (runnable == null) {
+ return;
+ }
if (mDestroyed) {
runnable.run();
return;
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 11b856e..06cac08 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -19,9 +19,9 @@
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT;
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
+import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.ColorMatrix;
@@ -41,23 +41,24 @@
public class Themes {
public static int getActivityThemeRes(Context context) {
- int colorHints = Utilities.ATLEAST_P ? context.getSystemService(WallpaperManager.class)
- .getWallpaperColors(WallpaperManager.FLAG_SYSTEM).getColorHints()
- : 0;
+ final int colorHints;
+ if (Utilities.ATLEAST_P) {
+ WallpaperColors colors = context.getSystemService(WallpaperManager.class)
+ .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+ colorHints = colors == null ? 0 : colors.getColorHints();
+ } else {
+ colorHints = 0;
+ }
return getActivityThemeRes(context, colorHints);
}
public static int getActivityThemeRes(Context context, int wallpaperColorHints) {
- Configuration configuration = context.getResources().getConfiguration();
- int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
- boolean darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES;
-
boolean supportsDarkText = Utilities.ATLEAST_S
&& (wallpaperColorHints & HINT_SUPPORTS_DARK_TEXT) != 0;
boolean isMainColorDark = Utilities.ATLEAST_S
&& (wallpaperColorHints & HINT_SUPPORTS_DARK_THEME) != 0;
- if (darkTheme) {
+ if (Utilities.isDarkTheme(context)) {
return supportsDarkText ? R.style.AppTheme_Dark_DarkText
: isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark;
} else {
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index 0498052..be14e01 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -17,13 +17,18 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.view.WindowInsets;
import android.view.inputmethod.InputMethodManager;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.Utilities;
+
/**
* Utility class for offloading some class from UI thread
*/
@@ -37,8 +42,16 @@
private static final int MSG_SET_ORIENTATION = 2;
private static final int MSG_RUN_COMMAND = 3;
- public static void hideKeyboardAsync(Context context, IBinder token) {
- Message.obtain(HANDLER.get(context), MSG_HIDE_KEYBOARD, token).sendToTarget();
+ @SuppressLint("NewApi")
+ public static void hideKeyboardAsync(Launcher launcher, IBinder token) {
+ if (Utilities.ATLEAST_R) {
+ WindowInsets rootInsets = launcher.getRootView().getRootWindowInsets();
+ boolean isImeShown = rootInsets != null && rootInsets.isVisible(
+ WindowInsets.Type.ime());
+ if (!isImeShown) return;
+ }
+
+ Message.obtain(HANDLER.get(launcher), MSG_HIDE_KEYBOARD, token).sendToTarget();
}
public static void setOrientationAsync(Activity activity, int orientation) {
diff --git a/src/com/android/launcher3/util/WindowBounds.java b/src/com/android/launcher3/util/WindowBounds.java
index 3c2fb62..c92770e 100644
--- a/src/com/android/launcher3/util/WindowBounds.java
+++ b/src/com/android/launcher3/util/WindowBounds.java
@@ -15,11 +15,16 @@
*/
package com.android.launcher3.util;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
+import android.view.WindowInsets.Type;
+import android.view.WindowMetrics;
import androidx.annotation.Nullable;
+import java.util.Objects;
+
/**
* Utility class to hold information about window position and layout
*/
@@ -36,6 +41,18 @@
bounds.height() - insets.top - insets.bottom);
}
+ public WindowBounds(int width, int height, int availableWidth, int availableHeight) {
+ this.bounds = new Rect(0, 0, width, height);
+ this.availableSize = new Point(availableWidth, availableHeight);
+ // We don't care about insets in this case
+ this.insets = new Rect(0, 0, width - availableWidth, height - availableHeight);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(bounds, insets);
+ }
+
@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof WindowBounds)) {
@@ -44,4 +61,30 @@
WindowBounds other = (WindowBounds) obj;
return other.bounds.equals(bounds) && other.insets.equals(insets);
}
+
+ @Override
+ public String toString() {
+ return "WindowBounds{"
+ + "bounds=" + bounds
+ + ", insets=" + insets
+ + ", availableSize=" + availableSize
+ + '}';
+ }
+
+ /**
+ * Returns true if the device is in landscape orientation
+ */
+ public final boolean isLandscape() {
+ return availableSize.x > availableSize.y;
+ }
+
+ /**
+ * Returns the bounds corresponding to the provided WindowMetrics
+ */
+ @SuppressWarnings("NewApi")
+ public static WindowBounds fromWindowMetrics(WindowMetrics wm) {
+ Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
+ return new WindowBounds(wm.getBounds(),
+ new Rect(insets.left, insets.top, insets.right, insets.bottom));
+ }
}
diff --git a/src/com/android/launcher3/util/WindowManagerCompat.java b/src/com/android/launcher3/util/WindowManagerCompat.java
new file mode 100644
index 0000000..38a63de
--- /dev/null
+++ b/src/com/android/launcher3/util/WindowManagerCompat.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 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.util;
+
+import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
+import static com.android.launcher3.Utilities.dpiFromPx;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.util.DisplayController.PortraitSize;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Utility class to simulate window manager APIs until proper APIs are available
+ */
+@TargetApi(Build.VERSION_CODES.S)
+public class WindowManagerCompat {
+
+ public static final int MIN_TABLET_WIDTH = 600;
+
+ /**
+ * Returns a set of supported render sizes for a set of internal displays.
+ * This is a temporary workaround which assumes only nav-bar insets change across displays
+ * @param consumeTaskBar if true, it assumes that task bar is part of the app window
+ * and ignores any insets because of task bar.
+ */
+ public static Set<WindowMetrics> getDisplayProfiles(
+ Context windowContext, Collection<PortraitSize> allDisplaySizes,
+ int densityDpi, boolean consumeTaskBar) {
+ WindowInsets metrics = windowContext.getSystemService(WindowManager.class)
+ .getMaximumWindowMetrics().getWindowInsets();
+ boolean hasNavbar = ResourceUtils.getIntegerByName(
+ "config_navBarInteractionMode",
+ windowContext.getResources(),
+ INVALID_RESOURCE_HANDLE) != 0;
+
+ WindowInsets.Builder insetsBuilder = new WindowInsets.Builder(metrics);
+
+ Set<WindowMetrics> result = new HashSet<>();
+ for (PortraitSize size : allDisplaySizes) {
+ int swDP = (int) dpiFromPx(size.width, densityDpi);
+ boolean isTablet = swDP >= MIN_TABLET_WIDTH;
+
+ final Insets portraitNav, landscapeNav;
+ if (isTablet && !consumeTaskBar) {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, windowContext.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_size));
+ } else if (hasNavbar) {
+ portraitNav = Insets.of(0, 0, 0,
+ getSystemResource(windowContext, "navigation_bar_height", swDP));
+ landscapeNav = isTablet
+ ? Insets.of(0, 0, 0, getSystemResource(windowContext,
+ "navigation_bar_height_landscape", swDP))
+ : Insets.of(0, 0, getSystemResource(windowContext,
+ "navigation_bar_width", swDP), 0);
+ } else {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, 0);
+ }
+
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.width, size.height),
+ insetsBuilder.setInsets(Type.navigationBars(), portraitNav).build()));
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.height, size.width),
+ insetsBuilder.setInsets(Type.navigationBars(), landscapeNav).build()));
+ }
+ return result;
+ }
+
+ private static int getSystemResource(Context context, String key, int swDp) {
+ int resourceId = context.getResources().getIdentifier(key, "dimen", "android");
+ if (resourceId > 0) {
+ Configuration conf = new Configuration();
+ conf.smallestScreenWidthDp = swDp;
+ return context.createConfigurationContext(conf)
+ .getResources().getDimensionPixelSize(resourceId);
+ }
+ return 0;
+ }
+}
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index 89ff821..a6f2b42 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -22,7 +22,6 @@
import android.graphics.drawable.ShapeDrawable;
import android.os.Handler;
import android.util.Log;
-import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -108,10 +107,7 @@
ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
arrowLp.width, arrowLp.height, false));
Paint arrowPaint = arrowDrawable.getPaint();
- TypedValue typedValue = new TypedValue();
- context.getTheme()
- .resolveAttribute(android.R.attr.colorAccent, typedValue, true);
- arrowPaint.setColor(ContextCompat.getColor(getContext(), typedValue.resourceId));
+ arrowPaint.setColor(ContextCompat.getColor(getContext(), R.color.arrow_tip_view_bg));
// The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
arrowPaint.setPathEffect(new CornerPathEffect(
context.getResources().getDimension(R.dimen.arrow_toast_corner_radius)));
@@ -148,6 +144,10 @@
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) findViewById(
R.id.arrow).getLayoutParams();
lp.gravity = gravity;
+
+ if (parent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ arrowMarginStart = parent.getMeasuredWidth() - arrowMarginStart;
+ }
if (gravity == Gravity.END) {
lp.setMarginEnd(parent.getMeasuredWidth() - arrowMarginStart);
} else if (gravity == Gravity.START) {
diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
index d89e7f8..a309e6e 100644
--- a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
+++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
@@ -60,7 +60,7 @@
// We enhance the shadow by drawing the shadow twice
getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
- setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha));
+ getTextShadowColor(mShadowInfo.ambientShadowColor, alpha));
drawWithoutDot(canvas);
canvas.save();
@@ -68,8 +68,11 @@
getScrollX() + getWidth(),
getScrollY() + getHeight());
- getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
- setColorAlphaBound(mShadowInfo.keyShadowColor, alpha));
+ getPaint().setShadowLayer(
+ mShadowInfo.keyShadowBlur,
+ mShadowInfo.keyShadowOffsetX,
+ mShadowInfo.keyShadowOffsetY,
+ getTextShadowColor(mShadowInfo.keyShadowColor, alpha));
drawWithoutDot(canvas);
canvas.restore();
@@ -81,7 +84,8 @@
public final int ambientShadowColor;
public final float keyShadowBlur;
- public final float keyShadowOffset;
+ public final float keyShadowOffsetX;
+ public final float keyShadowOffsetY;
public final int keyShadowColor;
public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
@@ -89,11 +93,13 @@
TypedArray a = c.obtainStyledAttributes(
attrs, R.styleable.ShadowInfo, defStyle, 0);
- ambientShadowBlur = a.getDimension(R.styleable.ShadowInfo_ambientShadowBlur, 0);
+ ambientShadowBlur = a.getDimensionPixelSize(
+ R.styleable.ShadowInfo_ambientShadowBlur, 0);
ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
- keyShadowBlur = a.getDimension(R.styleable.ShadowInfo_keyShadowBlur, 0);
- keyShadowOffset = a.getDimension(R.styleable.ShadowInfo_keyShadowOffset, 0);
+ keyShadowBlur = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowBlur, 0);
+ keyShadowOffsetX = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetX, 0);
+ keyShadowOffsetY = a.getDimensionPixelSize(R.styleable.ShadowInfo_keyShadowOffsetY, 0);
keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
a.recycle();
}
@@ -105,17 +111,26 @@
if (textAlpha == 0 || (keyShadowAlpha == 0 && ambientShadowAlpha == 0)) {
textView.getPaint().clearShadowLayer();
return true;
- } else if (ambientShadowAlpha > 0) {
+ } else if (ambientShadowAlpha > 0 && keyShadowAlpha == 0) {
textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
- setColorAlphaBound(ambientShadowColor, textAlpha));
+ getTextShadowColor(ambientShadowColor, textAlpha));
return true;
- } else if (keyShadowAlpha > 0) {
- textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
- setColorAlphaBound(keyShadowColor, textAlpha));
+ } else if (keyShadowAlpha > 0 && ambientShadowAlpha == 0) {
+ textView.getPaint().setShadowLayer(
+ keyShadowBlur,
+ keyShadowOffsetX,
+ keyShadowOffsetY,
+ getTextShadowColor(keyShadowColor, textAlpha));
return true;
} else {
return false;
}
}
}
+
+ // Multiplies the alpha of shadowColor by textAlpha.
+ private static int getTextShadowColor(int shadowColor, int textAlpha) {
+ return setColorAlphaBound(shadowColor,
+ Math.round(Color.alpha(shadowColor) * textAlpha / 255f));
+ }
}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index d49320b..81581fa 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -233,15 +233,8 @@
outViewBounds.set(0, 0, v.getWidth(), v.getHeight());
}
- float[] points = new float[] {outViewBounds.left, outViewBounds.top, outViewBounds.right,
- outViewBounds.bottom};
- Utilities.getDescendantCoordRelativeToAncestor(v, launcher.getDragLayer(), points,
- false, ignoreTransform);
- outRect.set(
- Math.min(points[0], points[2]),
- Math.min(points[1], points[3]),
- Math.max(points[0], points[2]),
- Math.max(points[1], points[3]));
+ Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, outViewBounds,
+ ignoreTransform, null /** recycle */, outRect);
}
/**
diff --git a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
index 3a24c3d..149ac57 100644
--- a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
@@ -44,7 +44,7 @@
mPaint = new TextPaint();
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
- mLauncher.getDeviceProfile().getFullScreenProfile().iconTextSizePx,
+ mLauncher.getDeviceProfile().iconTextSizePx,
getResources().getDisplayMetrics()));
setBackgroundResource(R.drawable.bg_deferred_app_widget);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 620604a..5deecd4 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -16,6 +16,9 @@
package com.android.launcher3.widget;
+import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer;
+import static com.android.launcher3.Utilities.setRect;
+
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.res.Configuration;
@@ -25,7 +28,6 @@
import android.graphics.RectF;
import android.os.Handler;
import android.os.SystemClock;
-import android.util.Log;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
@@ -95,11 +97,12 @@
private RectF mLastLocationRegistered = null;
@Nullable private AppWidgetHostViewDragListener mDragListener;
- // Used to store the widget size during onLayout.
+ // Used to store the widget sizes in drag layer coordinates.
private final Rect mCurrentWidgetSize = new Rect();
private final Rect mWidgetSizeAtDrag = new Rect();
+
+ private final float[] mTmpFloatArray = new float[4];
private final RectF mTempRectF = new RectF();
- private final boolean mIsRtl;
private final Rect mEnforcedRectangle = new Rect();
private final float mEnforcedCornerRadius;
private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() {
@@ -129,7 +132,6 @@
if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) {
setOnLightBackground(true);
}
- mIsRtl = Utilities.isRtl(context.getResources());
mColorExtractor = LocalColorExtractor.newInstance(getContext());
mColorExtractor.setListener(this);
@@ -319,13 +321,12 @@
mIsScrollable = checkScrollableRecursively(this);
if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
- mCurrentWidgetSize.left = left;
- mCurrentWidgetSize.top = top;
- mCurrentWidgetSize.right = right;
- mCurrentWidgetSize.bottom = bottom;
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
- int pageId = mWorkspace.getPageIndexForScreenId(info.screenId);
- updateColorExtraction(mCurrentWidgetSize, pageId);
+ getBoundsForViewInDragLayer(mLauncher.getDragLayer(), this, mCurrentWidgetSize, true,
+ mTmpFloatArray, mTempRectF);
+ setRect(mTempRectF, mCurrentWidgetSize);
+ updateColorExtraction(mCurrentWidgetSize,
+ mWorkspace.getPageIndexForScreenId(info.screenId));
}
enforceRoundedCorners();
@@ -338,8 +339,8 @@
}
/** Handles a drag event occurred on a workspace page, {@code pageId}. */
- public void handleDrag(Rect rect, int pageId) {
- mWidgetSizeAtDrag.set(rect);
+ public void handleDrag(Rect rectInDragLayer, int pageId) {
+ mWidgetSizeAtDrag.set(rectInDragLayer);
updateColorExtraction(mWidgetSizeAtDrag, pageId);
}
@@ -351,53 +352,14 @@
requestLayout();
}
- private void updateColorExtraction(Rect widgetLocation, int pageId) {
- // If the widget hasn't been measured and laid out, we cannot do this.
- if (widgetLocation.isEmpty()) {
- return;
- }
- int screenWidth = mLauncher.getDeviceProfile().widthPx;
- int screenHeight = mLauncher.getDeviceProfile().heightPx;
- int numScreens = mWorkspace.getNumPagesForWallpaperParallax();
- pageId = mIsRtl ? numScreens - pageId - 1 : pageId;
- float relativeScreenWidth = 1f / numScreens;
- float absoluteTop = widgetLocation.top;
- float absoluteBottom = widgetLocation.bottom;
- View v = this;
- while (v.getParent() instanceof View) {
- v = (View) v.getParent();
- if (v.getId() != R.id.launcher) {
- break;
- }
- absoluteBottom += v.getTop();
- absoluteTop += v.getTop();
- }
- float xOffset = 0;
- View parentView = (View) getParent();
- // The layout depends on the orientation.
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
- int parentViewWidth = parentView == null ? 0 : parentView.getWidth();
- xOffset = screenWidth - mWorkspace.getPaddingRight() - parentViewWidth;
- } else {
- int parentViewPaddingLeft = parentView == null ? 0 : parentView.getPaddingLeft();
- xOffset = mWorkspace.getPaddingLeft() + parentViewPaddingLeft;
- }
- // This is the position of the widget relative to the wallpaper, as expected by the
- // local color extraction of the WallpaperManager.
- // The coordinate system is such that, on the horizontal axis, each screen has a
- // distinct range on the [0,1] segment. So if there are 3 screens, they will have the
- // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be
- // the position of the widget relative to the screen. For the vertical axis, this is
- // simply the location of the widget relative to the screen.
- mTempRectF.left = ((widgetLocation.left + xOffset) / screenWidth + pageId)
- * relativeScreenWidth;
- mTempRectF.right = ((widgetLocation.right + xOffset) / screenWidth + pageId)
- * relativeScreenWidth;
- mTempRectF.top = absoluteTop / screenHeight;
- mTempRectF.bottom = absoluteBottom / screenHeight;
- if (mTempRectF.left < 0 || mTempRectF.right > 1 || mTempRectF.top < 0
- || mTempRectF.bottom > 1) {
- Log.e(LOG_TAG, " Error, invalid relative position");
+ /**
+ * @param rectInDragLayer Rect of widget in drag layer coordinates.
+ * @param pageId The workspace page the widget is on.
+ */
+ private void updateColorExtraction(Rect rectInDragLayer, int pageId) {
+ mColorExtractor.getExtractedRectForViewRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
+
+ if (mTempRectF.isEmpty()) {
return;
}
if (!mTempRectF.equals(mLastLocationRegistered)) {
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index ad61495..de511cd 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -13,6 +13,7 @@
import android.os.Parcel;
import android.os.UserHandle;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
@@ -66,20 +67,25 @@
}
public void initSpans(Context context, InvariantDeviceProfile idp) {
- Point landCellSize = idp.landscapeProfile.getCellSize();
- Point portCellSize = idp.portraitProfile.getCellSize();
-
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations.
- float smallestCellWidth = Math.min(landCellSize.x, portCellSize.x);
- float smallestCellHeight = Math.min(landCellSize.y, portCellSize.y);
+ float smallestCellWidth = Float.MAX_VALUE;
+ float smallestCellHeight = Float.MAX_VALUE;
+
+ Point cellSize = new Point();
+ boolean isWidgetPadded = false;
+ for (DeviceProfile dp : idp.supportedProfiles) {
+ dp.getCellSize(cellSize);
+ smallestCellWidth = Math.min(smallestCellWidth, cellSize.x);
+ smallestCellHeight = Math.min(smallestCellHeight, cellSize.y);
+ isWidgetPadded = isWidgetPadded || !dp.shouldInsetWidgets();
+ }
// We want to account for the extra amount of padding that we are adding to the widget
// to ensure that it gets the full amount of space that it has requested.
// If grids supports insetting widgets, we do not account for widget padding.
Rect widgetPadding = new Rect();
- if (!idp.landscapeProfile.shouldInsetWidgets()
- || !idp.portraitProfile.shouldInsetWidgets()) {
+ if (isWidgetPadded) {
AppWidgetHostView.getDefaultPaddingForWidget(context, provider, widgetPadding);
}
diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java
index 097158b..8ae6b2e 100644
--- a/src/com/android/launcher3/widget/LocalColorExtractor.java
+++ b/src/com/android/launcher3/widget/LocalColorExtractor.java
@@ -16,13 +16,17 @@
package com.android.launcher3.widget;
+import android.app.WallpaperColors;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.util.SparseIntArray;
+import android.view.View;
import androidx.annotation.Nullable;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -43,7 +47,10 @@
void onColorsChanged(RectF rect, SparseIntArray extractedColors);
}
- static LocalColorExtractor newInstance(Context context) {
+ /**
+ * Creates a new instance of LocalColorExtractor
+ */
+ public static LocalColorExtractor newInstance(Context context) {
return Overrides.getObject(LocalColorExtractor.class, context.getApplicationContext(),
R.string.local_colors_extraction_class);
}
@@ -62,4 +69,38 @@
public void removeLocations() {
// no-op
}
+
+ /**
+ * Updates the base context to contain the colors override
+ */
+ public void applyColorsOverride(Context base, WallpaperColors colors) { }
+
+ /**
+ * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
+ *
+ * @param launcher Launcher class class.
+ * @param pageId The page the workspace item is on.
+ * @param v The view.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForView(Launcher launcher, int pageId, View v,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
+
+ /**
+ * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
+ * local color extractor.
+ *
+ * @param launcher Launcher class.
+ * @param pageId The page the workspace item is on.
+ * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForViewRect(Launcher launcher, int pageId, Rect rectInDragLayer,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
}
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index ee0b84e..3377abb 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -15,9 +15,11 @@
*/
package com.android.launcher3.widget;
+import static com.android.launcher3.AppWidgetResizeFrame.getWidgetSizeOptions;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
import android.appwidget.AppWidgetHostView;
+import android.content.Context;
import android.os.Bundle;
import com.android.launcher3.LauncherSettings;
@@ -57,4 +59,8 @@
public WidgetAddFlowHandler getHandler() {
return new WidgetAddFlowHandler(info);
}
+
+ public Bundle getDefaultSizeOptions(Context context) {
+ return getWidgetSizeOptions(context, componentName, spanX, spanY);
+ }
}
diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
index 12e0d43..46141e0 100644
--- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java
+++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
@@ -1,16 +1,12 @@
package com.android.launcher3.widget;
import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
import android.content.Context;
-import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
-import android.util.SizeF;
import android.view.View;
-import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
import com.android.launcher3.dragndrop.DragController;
@@ -18,9 +14,6 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.util.Thunk;
-import java.util.ArrayList;
-import java.util.stream.Collectors;
-
public class WidgetHostViewLoader implements DragController.DragListener {
private static final String TAG = "WidgetHostViewLoader";
private static final boolean LOGD = false;
@@ -90,7 +83,7 @@
if (pInfo.isCustomWidget()) {
return false;
}
- final Bundle options = getDefaultOptionsForWidget(mLauncher, mInfo);
+ final Bundle options = mInfo.getDefaultSizeOptions(mLauncher);
// If there is a configuration activity, do not follow thru bound and inflate.
if (mInfo.getHandler().needsConfigure()) {
@@ -154,29 +147,4 @@
return true;
}
- public static Bundle getDefaultOptionsForWidget(Context context, PendingAddWidgetInfo info) {
- ArrayList<SizeF> sizes = AppWidgetResizeFrame
- .getWidgetSizes(context, info.spanX, info.spanY);
-
- Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context,
- info.componentName, null);
- float density = context.getResources().getDisplayMetrics().density;
- float xPaddingDips = (padding.left + padding.right) / density;
- float yPaddingDips = (padding.top + padding.bottom) / density;
-
- ArrayList<SizeF> paddedSizes = sizes.stream().map(
- size -> new SizeF(Math.max(0.f, size.getWidth() - xPaddingDips),
- Math.max(0.f, size.getHeight() - yPaddingDips))).collect(
- Collectors.toCollection(ArrayList::new));
-
- Rect rect = AppWidgetResizeFrame.getMinMaxSizes(paddedSizes, null /* outRect */);
-
- Bundle options = new Bundle();
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, rect.left);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, rect.top);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, rect.right);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, rect.bottom);
- options.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, paddedSizes);
- return options;
- }
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 8f5d4dc..b4d4856 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -28,7 +28,6 @@
import android.os.Process;
import android.os.UserHandle;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.LayoutInflater;
@@ -473,10 +472,6 @@
WidgetsRecommendationTableLayout table =
mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable;
if (recommendedWidgets.size() > 0) {
- // TODO(b/185508758): Revert the following log after debugging.
- if (getHeaderViewHeight() == 0) {
- Log.d(TAG, "Header view height is 0 when inflating recommended widgets");
- }
float maxTableHeight =
(mLauncher.getDeviceProfile().availableHeightPx - mTabsHeight
- getHeaderViewHeight()) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index ccf3187..41aa437 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -35,7 +35,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
-import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.PlaceHolderIconDrawable;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -174,7 +173,14 @@
}
private void setIcon(PackageItemInfo info) {
- FastBitmapDrawable icon = info.newIcon(getContext());
+ Drawable icon;
+ switch (info.category) {
+ case PackageItemInfo.CONVERSATIONS:
+ icon = getContext().getDrawable(R.drawable.ic_conversations_widget_category);
+ break;
+ default:
+ icon = info.newIcon(getContext());
+ }
applyDrawables(icon);
mIconDrawable = icon;
if (mIconDrawable != null) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 2d3f1a0..62ef4ff 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -93,9 +93,6 @@
mRecommendationTableMaxHeight = recommendationTableMaxHeight;
RecommendationTableData data = fitRecommendedWidgetsToTableSpace(/* previewScale= */ 1f,
recommendedWidgets);
- // TODO(b/185508758): Revert the following logs after debugging.
- Log.d(TAG, "Recommended widgets section max height: " + recommendationTableMaxHeight);
- Log.d(TAG, "Recommended widget down scale: " + data.mPreviewScale);
bindData(data);
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
index 6fd147a..4407fe1 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -18,12 +18,22 @@
import android.app.Person;
import android.content.pm.ShortcutInfo;
+import android.view.Display;
import com.android.launcher3.Utilities;
public class ApiWrapper {
+ public static final boolean TASKBAR_DRAWN_IN_PROCESS = false;
+
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
+
+ /**
+ * Returns true if the display is an internal displays
+ */
+ public static boolean isInternalDisplay(Display display) {
+ return display.getDisplayId() == Display.DEFAULT_DISPLAY;
+ }
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 2c7d30a..883a69e 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -76,6 +76,9 @@
LOCAL_INSTRUMENTATION_FOR := Launcher3
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/src_common/com/android/launcher3/common/WidgetUtils.java b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
index ffad93f..5e17e0a 100644
--- a/tests/src_common/com/android/launcher3/common/WidgetUtils.java
+++ b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
@@ -16,7 +16,6 @@
package com.android.launcher3.common;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
-import static com.android.launcher3.widget.WidgetHostViewLoader.getDefaultOptionsForWidget;
import android.appwidget.AppWidgetHost;
import android.content.ContentResolver;
@@ -62,7 +61,7 @@
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
- Bundle options = getDefaultOptionsForWidget(targetContext, pendingInfo);
+ Bundle options = pendingInfo.getDefaultSizeOptions(targetContext);
AppWidgetHost host = new LauncherAppWidgetHost(targetContext);
int widgetId = host.allocateAppWidgetId();
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index e1fde3b..0582bc9 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -28,7 +28,7 @@
public class AddToHomeScreenPrompt {
private static final Pattern ADD_AUTOMATICALLY =
- Pattern.compile("^Add automatically$", CASE_INSENSITIVE);
+ Pattern.compile("^Add to Home screen$", CASE_INSENSITIVE);
private final LauncherInstrumentation mLauncher;
private final UiObject2 mWidgetCell;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index ebad154..e5b93b1 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -695,6 +695,7 @@
waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
// Swiping up can temporarily bring Nexus Launcher if the current
// Launcher is a Launcher3 one. Wait for the current launcher to reappear.
+ SystemClock.sleep(5000); // b/187080582
waitForLauncherObject(getAnyObjectSelector());
}
}