Merge tag 'android-platform-12.1.0_r8' of https://android.googlesource.com/platform//packages/apps/Launcher3 into arcadia-next
Android Platform 12.1.0 Release 8 (8968309)
Change-Id: Id2406325233d727d26df55b4b9f69e03b2f7da03
# gpg verification failed.
diff --git a/Android.bp b/Android.bp
index bab994a..db8f5b7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -100,6 +100,13 @@
min_sdk_version: min_launcher3_sdk_version,
}
+java_import {
+ name: "libGoogleFeed",
+ jars: [
+ "libs/libGoogleFeed.jar",
+ ],
+}
+
// Library with all the dependencies for building Launcher3
android_library {
name: "Launcher3ResLib",
@@ -117,6 +124,9 @@
"androidx.cardview_cardview",
"com.google.android.material_material",
"iconloader_base",
+ "libGoogleFeed",
+ "colorkt",
+ "themelib",
],
manifest: "AndroidManifest-common.xml",
sdk_version: "current",
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index eee6db5..530b9ca 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -49,13 +49,11 @@
-->
<permission
android:name="${packageName}.permission.READ_SETTINGS"
- android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_read_settings"
android:description="@string/permdesc_read_settings"/>
<permission
android:name="${packageName}.permission.WRITE_SETTINGS"
- android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_write_settings"
android:description="@string/permdesc_write_settings"/>
@@ -135,7 +133,9 @@
<provider
android:name="com.android.launcher3.graphics.GridCustomizationsProvider"
android:authorities="${packageName}.grid_control"
- android:exported="true" />
+ android:exported="true"
+ android:writePermission="${packageName}.permission.WRITE_SETTINGS"
+ android:readPermission="${packageName}.permission.READ_SETTINGS" />
<!--
The settings activity. To extend point settings_fragment_name to appropriate fragment class
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b838a51..63180e8 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -44,7 +44,7 @@
attributes and intent filters the same
-->
<activity
- android:name="com.android.launcher3.Launcher"
+ android:name="com.android.launcher3.CustomLauncher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
@@ -66,6 +66,9 @@
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
+ <meta-data
+ android:name="com.android.launcher3.themedicon.option"
+ android:value="${packageName}.grid_control" />
</activity>
</application>
diff --git a/libs/libGoogleFeed.jar b/libs/libGoogleFeed.jar
new file mode 100644
index 0000000..158b76d
--- /dev/null
+++ b/libs/libGoogleFeed.jar
Binary files differ
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 53910e3..0c0eac7 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -43,7 +43,7 @@
attributes and intent filters the same
-->
<activity
- android:name="com.android.launcher3.uioverrides.QuickstepLauncher"
+ android:name="com.android.launcher3.CustomLauncher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
@@ -65,6 +65,9 @@
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
+ <meta-data
+ android:name="com.android.launcher3.themedicon.option"
+ android:value="${packageName}.grid_control" />
</activity>
</application>
diff --git a/quickstep/res/drawable/task_menu_item_bg.xml b/quickstep/res/drawable/task_menu_item_bg.xml
index 16c13eb..bd863f2 100644
--- a/quickstep/res/drawable/task_menu_item_bg.xml
+++ b/quickstep/res/drawable/task_menu_item_bg.xml
@@ -15,8 +15,13 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/colorSurface" />
- <corners android:radius="@dimen/task_menu_item_corner_radius" />
-</shape>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <item>
+ <shape>
+ <solid android:color="?androidprv:attr/colorSurface" />
+ <corners android:radius="@dimen/task_menu_item_corner_radius" />
+ </shape>
+ </item>
+</ripple>
diff --git a/quickstep/src/com/android/launcher3/CustomLauncher.java b/quickstep/src/com/android/launcher3/CustomLauncher.java
new file mode 100644
index 0000000..1e41f42
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/CustomLauncher.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 Paranoid Android
+ *
+ * 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;
+
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.systemui.plugins.shared.LauncherOverlayManager;
+
+public class CustomLauncher extends QuickstepLauncher {
+
+ @Override
+ protected LauncherOverlayManager getDefaultOverlay() {
+ return new OverlayCallbackImpl(this);
+ }
+
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index bec717d..c4ca2b3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -226,9 +226,10 @@
boolean isTaskBarEnabled =
FeatureFlags.ENABLE_TASKBAR.get() && dp != null && dp.isTaskbarPresent;
+ SystemUiProxy sysui = SystemUiProxy.INSTANCE.get(mContext);
+ sysui.setTaskbarEnabled(isTaskBarEnabled);
if (!isTaskBarEnabled) {
- SystemUiProxy.INSTANCE.get(mContext)
- .notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
+ sysui.notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
return;
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 67e7f88..f301ebc 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -427,6 +427,18 @@
}
@Override
+ public void setTaskbarEnabled(boolean enabled) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSystemUiProxy.setTaskbarEnabled(enabled);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call setTaskbarEnabled with arg: " +
+ enabled, e);
+ }
+ }
+ }
+
+ @Override
public void notifyTaskbarStatus(boolean visible, boolean stashed) {
if (mSystemUiProxy != null) {
try {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7218cd7..053f144 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3268,7 +3268,9 @@
return;
}
mActionsView.setSplitButtonVisible(
- mActivity.getDeviceProfile().overviewShowAsGrid && getTaskViewCount() > 1);
+ mActivity.getDeviceProfile().overviewShowAsGrid &&
+ mActivity.getDeviceProfile().isTablet &&
+ getTaskViewCount() > 1);
}
/**
diff --git a/res/color-night-v31/all_apps_tab_text.xml b/res/color-night-v31/all_apps_tab_text.xml
index 83237b4..eaac621 100644
--- a/res/color-night-v31/all_apps_tab_text.xml
+++ b/res/color-night-v31/all_apps_tab_text.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_50" android:state_selected="true"/>
- <item android:color="@android:color/system_neutral2_700"/>
-</selector>
\ No newline at end of file
+ <item android:color="?android:textColorPrimaryInverse" android:state_selected="true"/>
+ <item android:color="?android:textColorSecondary"/>
+</selector>
diff --git a/res/color-night-v31/all_apps_tabs_background.xml b/res/color-night-v31/all_apps_tabs_background.xml
new file mode 100644
index 0000000..fc8a4d7
--- /dev/null
+++ b/res/color-night-v31/all_apps_tabs_background.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_neutral1_800" />
+</selector>
diff --git a/res/color-v31/all_apps_tab_text.xml b/res/color-v31/all_apps_tab_text.xml
index c3520a7..d133a31 100644
--- a/res/color-v31/all_apps_tab_text.xml
+++ b/res/color-v31/all_apps_tab_text.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_900" android:state_selected="true"/>
- <item android:color="@android:color/system_neutral2_700"/>
-</selector>
\ No newline at end of file
+ <item android:color="?android:textColorPrimary" android:state_selected="true"/>
+ <item android:color="?android:textColorSecondary"/>
+</selector>
diff --git a/res/drawable/all_apps_search_hint.xml b/res/drawable/all_apps_search_hint.xml
index b2ff7a4..c0e6811 100644
--- a/res/drawable/all_apps_search_hint.xml
+++ b/res/drawable/all_apps_search_hint.xml
@@ -16,5 +16,5 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/transparent" android:state_focused="true" />
- <item android:color="?android:attr/colorAccent"/>
-</selector>
\ No newline at end of file
+ <item android:color="?android:attr/textColorSecondary" android:alpha="?android:attr/disabledAlpha" />
+</selector>
diff --git a/res/drawable/bg_all_apps_searchbox.xml b/res/drawable/bg_all_apps_searchbox.xml
index c324927..2d02238 100644
--- a/res/drawable/bg_all_apps_searchbox.xml
+++ b/res/drawable/bg_all_apps_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="?attr/popupColorPrimary" />
- <corners android:radius="2dp" />
-</shape>
\ No newline at end of file
+ <solid android:color="?attr/allappsHeaderProtectionColor" />
+ <corners android:radius="58dp" />
+</shape>
diff --git a/res/layout/search_container_all_apps.xml b/res/layout/search_container_all_apps.xml
index e1646ba..5ebf9c8 100644
--- a/res/layout/search_container_all_apps.xml
+++ b/res/layout/search_container_all_apps.xml
@@ -21,17 +21,17 @@
android:layout_centerHorizontal="true"
android:layout_gravity="top|center_horizontal"
android:background="@drawable/bg_all_apps_searchbox"
- android:elevation="1dp"
+ android:elevation="0dp"
android:focusableInTouchMode="true"
- android:gravity="center"
android:hint="@string/all_apps_search_bar_hint"
android:imeOptions="actionSearch|flagNoExtractUi"
android:inputType="text|textNoSuggestions|textCapWords"
android:maxLines="1"
android:padding="8dp"
+ android:paddingStart="16dp"
android:saveEnabled="false"
android:scrollHorizontally="true"
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textColorHint="@drawable/all_apps_search_hint"
- android:textSize="16sp" />
\ No newline at end of file
+ android:textSize="20sp" />
diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml
index b15a320..131de00 100644
--- a/res/layout/secondary_launcher.xml
+++ b/res/layout/secondary_launcher.xml
@@ -105,9 +105,8 @@
android:layout_centerHorizontal="true"
android:layout_gravity="top|center_horizontal"
android:background="@drawable/bg_all_apps_searchbox"
- android:elevation="1dp"
+ android:elevation="0dp"
android:focusableInTouchMode="true"
- android:gravity="center"
android:hint="@string/all_apps_search_bar_hint"
android:imeOptions="actionSearch|flagNoExtractUi"
android:inputType="text|textNoSuggestions|textCapWords"
@@ -118,8 +117,8 @@
android:singleLine="true"
android:textColor="?android:attr/textColorSecondary"
android:textColorHint="@drawable/all_apps_search_hint"
- android:textSize="16sp" />
+ android:textSize="20sp" />
<include layout="@layout/all_apps_fast_scroller" />
</com.android.launcher3.allapps.AllAppsContainerView>
-</com.android.launcher3.secondarydisplay.SecondaryDragLayer>
\ No newline at end of file
+</com.android.launcher3.secondarydisplay.SecondaryDragLayer>
diff --git a/res/values-ldrtl/custom_strings.xml b/res/values-ldrtl/custom_strings.xml
new file mode 100644
index 0000000..ee4208e
--- /dev/null
+++ b/res/values-ldrtl/custom_strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources>
+
+ <!-- Settings title to show Google Now at -1 screen on launcher. [CHAR LIMIT=50] -->
+ <string name="title_show_google_app">Show Google App</string>
+ <!-- Settings message explaining when the -1 screen is available on an LTR device. [CHAR LIMIT=100] -->
+ <string name="msg_minus_one_on_left">When you swipe left from main Home screen</string>
+ <!-- Settings message explaining when the -1 screen is available on an RTL device. [CHAR LIMIT=100] -->
+ <string name="msg_minus_one_on_right">When you swipe right from main Home screen</string>
+ <string name="pref_show_google_now_summary" translatable="false">@string/msg_minus_one_on_right</string>
+
+</resources>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 7bbdbd1..85a6678 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<color name="popup_color_primary_light">@android:color/system_accent2_50</color>
<color name="popup_color_secondary_light">@android:color/system_neutral2_100</color>
- <color name="popup_color_tertiary_light">@android:color/system_neutral2_300</color>
+ <color name="popup_color_tertiary_light">@android:color/system_neutral2_100</color>
<color name="popup_color_neutral_dark">@android:color/system_neutral1_1000</color>
<color name="popup_color_primary_dark">@android:color/system_neutral2_800</color>
<color name="popup_color_secondary_dark">@android:color/system_neutral1_900</color>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
new file mode 100644
index 0000000..edb1aee
--- /dev/null
+++ b/res/values/custom_strings.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources>
+
+ <!-- Settings title to show Google Now at -1 screen on launcher. [CHAR LIMIT=50] -->
+ <string name="title_show_google_app">Swipe to access Google app</string>
+ <!-- Settings message explaining when the -1 screen is available on an LTR device. [CHAR LIMIT=100] -->
+ <string name="msg_minus_one_on_left">When you swipe left from main Home screen</string>
+ <!-- Settings message explaining when the -1 screen is available on an RTL device. [CHAR LIMIT=100] -->
+ <string name="msg_minus_one_on_right">When you swipe right from main Home screen</string>
+ <string name="pref_show_google_now_summary" translatable="false">@string/msg_minus_one_on_left</string>
+
+ <string name="pref_suggestions_title">Suggestions</string>
+ <string name="pref_suggestions_summary">For all apps and Home screen</string>
+
+ <string name="pref_allow_phone_taskbar">Use taskbar</string>
+ <string name="pref_allow_phone_taskbar_desc">For opening and switching apps anywhere</string>
+
+ <string name="pref_allow_phone_overview_grid">Show grid of recent apps</string>
+ <string name="pref_allow_phone_overview_grid_desc">More recent apps in Overview</string>
+
+</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 818a032..090419b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -99,6 +99,7 @@
<item name="android:colorControlHighlight">#19FFFFFF</item>
<item name="android:colorPrimary">#FF212121</item>
<item name="allAppsScrimColor">?android:attr/colorBackgroundFloating</item>
+ <item name="allappsHeaderProtectionColor">@color/popup_color_tertiary_dark</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
<item name="allAppsTheme">@style/AllAppsTheme.Dark</item>
<item name="popupColorPrimary">@color/popup_color_primary_dark</item>
diff --git a/res/xml/default_workspace_2x2.xml b/res/xml/default_workspace_2x2.xml
new file mode 100644
index 0000000..a4cf881
--- /dev/null
+++ b/res/xml/default_workspace_2x2.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="2"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Messaging, Dialer -->
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+ </resolve>
+
+ <!-- Bottom row -->
+ <resolve
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="1"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/default_workspace_3x3.xml b/res/xml/default_workspace_3x3.xml
index 31376e1..0a22f98 100644
--- a/res/xml/default_workspace_3x3.xml
+++ b/res/xml/default_workspace_3x3.xml
@@ -16,6 +16,16 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="3"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
<!-- Messaging, [All Apps], Dialer -->
diff --git a/res/xml/default_workspace_4x4.xml b/res/xml/default_workspace_4x4.xml
index bf3c62c..dfde7de 100644
--- a/res/xml/default_workspace_4x4.xml
+++ b/res/xml/default_workspace_4x4.xml
@@ -16,6 +16,16 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="4"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
<!-- Dialer, Messaging, Browser, Camera -->
<resolve
diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml
index b4ac8f6..7cba7ac 100644
--- a/res/xml/default_workspace_5x5.xml
+++ b/res/xml/default_workspace_5x5.xml
@@ -16,8 +16,18 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="5"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer, Messaging, [Maps/Music], Browser, Camera -->
+ <!-- Dialer, Messaging, [Maps/Music/Settings], Browser, Camera -->
<resolve
launcher:container="-101"
launcher:screen="0"
@@ -47,6 +57,7 @@
launcher:y="0" >
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+ <favorite launcher:uri="#Intent;action=android.settings.SETTINGS;end" />
</resolve>
<resolve
diff --git a/res/xml/default_workspace_5x6.xml b/res/xml/default_workspace_5x6.xml
new file mode 100644
index 0000000..6a6a556
--- /dev/null
+++ b/res/xml/default_workspace_5x6.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="5"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Dialer, Messaging, [Maps/Music/Settings], Browser, Camera -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="1"
+ launcher:x="1"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+ <favorite launcher:uri="#Intent;action=android.settings.SETTINGS;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+ </resolve>
+
+ <!-- Bottom row -->
+ <resolve
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="1"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="4"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+ <favorite launcher:uri="market://details?id=com.android.launcher" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/default_workspace_5x7.xml b/res/xml/default_workspace_5x7.xml
new file mode 100644
index 0000000..6a6a556
--- /dev/null
+++ b/res/xml/default_workspace_5x7.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="5"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Dialer, Messaging, [Maps/Music/Settings], Browser, Camera -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="1"
+ launcher:x="1"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+ <favorite launcher:uri="#Intent;action=android.settings.SETTINGS;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+ </resolve>
+
+ <!-- Bottom row -->
+ <resolve
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="1"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="4"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+ <favorite launcher:uri="market://details?id=com.android.launcher" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/default_workspace_6x6.xml b/res/xml/default_workspace_6x6.xml
new file mode 100644
index 0000000..0666feb
--- /dev/null
+++ b/res/xml/default_workspace_6x6.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+ <!-- Smartspace Widget -->
+ <appwidget
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0"
+ launcher:spanX="6"
+ launcher:spanY="1"
+ launcher:packageName="com.google.android.googlequicksearchbox"
+ launcher:className="com.google.android.apps.gsa.staticplugins.smartspace.widget.SmartspaceWidgetProvider" />
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Dialer, Messaging, [Maps/Music/Settings], Browser, Camera -->
+ <resolve
+ launcher:container="-101"
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+ <favorite launcher:uri="tel:123" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="1"
+ launcher:x="1"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+ <favorite launcher:uri="sms:" />
+ <favorite launcher:uri="smsto:" />
+ <favorite launcher:uri="mms:" />
+ <favorite launcher:uri="mmsto:" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="2"
+ launcher:x="2"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+ <favorite launcher:uri="#Intent;action=android.settings.SETTINGS;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+ <favorite launcher:uri="http://www.example.com/" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+ <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+ </resolve>
+
+ <!-- Bottom row -->
+ <resolve
+ launcher:screen="0"
+ launcher:x="0"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+ <favorite launcher:uri="mailto:" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="1"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+ <favorite launcher:uri="#Intent;type=images/*;end" />
+ </resolve>
+
+ <resolve
+ launcher:screen="0"
+ launcher:x="4"
+ launcher:y="-1" >
+ <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+ <favorite launcher:uri="market://details?id=com.android.launcher" />
+ </resolve>
+
+</favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 08698e7..91bf271 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -18,6 +18,34 @@
<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >
<grid-option
+ launcher:name="2_by_2"
+ launcher:numRows="2"
+ launcher:numColumns="2"
+ launcher:numFolderRows="2"
+ launcher:numFolderColumns="2"
+ launcher:numHotseatIcons="2"
+ launcher:dbFile="launcher_2_by_2.db"
+ launcher:defaultLayoutId="@xml/default_workspace_2x2" >
+
+ <display-option
+ launcher:name="Super Short Stubby"
+ launcher:minWidthDps="200"
+ launcher:minHeightDps="200"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="12.0"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Shorter Stubby"
+ launcher:minWidthDps="200"
+ launcher:minHeightDps="300"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="12.0"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+ <grid-option
launcher:name="3_by_3"
launcher:numRows="3"
launcher:numColumns="3"
@@ -33,7 +61,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="300"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -41,7 +69,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="400"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
</grid-option>
@@ -62,7 +90,7 @@
launcher:minWidthDps="275"
launcher:minHeightDps="420"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -70,7 +98,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="450"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -78,7 +106,7 @@
launcher:minWidthDps="296"
launcher:minHeightDps="491.33"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -86,7 +114,7 @@
launcher:minWidthDps="359"
launcher:minHeightDps="567"
launcher:iconImageSize="54"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -94,7 +122,7 @@
launcher:minWidthDps="335"
launcher:minHeightDps="567"
launcher:iconImageSize="54"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
</grid-option>
@@ -115,7 +143,7 @@
launcher:minWidthDps="406"
launcher:minHeightDps="694"
launcher:iconImageSize="56"
- launcher:iconTextSize="14.4"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -123,7 +151,7 @@
launcher:minWidthDps="406"
launcher:minHeightDps="694"
launcher:iconImageSize="56"
- launcher:iconTextSize="14.4"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
<display-option
@@ -131,7 +159,49 @@
launcher:minWidthDps="255"
launcher:minHeightDps="400"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+ <grid-option
+ launcher:name="5_by_6"
+ launcher:numRows="6"
+ launcher:numColumns="5"
+ launcher:numFolderRows="5"
+ launcher:numFolderColumns="4"
+ launcher:numHotseatIcons="5"
+ launcher:dbFile="launcher_5_by_6.db"
+ launcher:defaultLayoutId="@xml/default_workspace_5x6"
+ launcher:deviceCategory="phone|multi_display" >
+
+ <display-option
+ launcher:name="Large Phone"
+ launcher:minWidthDps="406"
+ launcher:minHeightDps="694"
+ launcher:iconImageSize="56"
+ launcher:iconTextSize="12.0"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+ <grid-option
+ launcher:name="5_by_7"
+ launcher:numRows="7"
+ launcher:numColumns="5"
+ launcher:numFolderRows="6"
+ launcher:numFolderColumns="4"
+ launcher:numHotseatIcons="5"
+ launcher:dbFile="launcher_5_by_7.db"
+ launcher:defaultLayoutId="@xml/default_workspace_5x7"
+ launcher:deviceCategory="phone|multi_display" >
+
+ <display-option
+ launcher:name="Large Phone"
+ launcher:minWidthDps="406"
+ launcher:minHeightDps="694"
+ launcher:iconImageSize="56"
+ launcher:iconTextSize="12.0"
launcher:canBeDefault="true" />
</grid-option>
@@ -164,4 +234,25 @@
</grid-option>
-</profiles>
\ No newline at end of file
+ <grid-option
+ launcher:name="6_by_6"
+ launcher:numRows="6"
+ launcher:numColumns="6"
+ launcher:numFolderRows="5"
+ launcher:numFolderColumns="5"
+ launcher:numHotseatIcons="6"
+ launcher:dbFile="launcher_6_by_6.db"
+ launcher:defaultLayoutId="@xml/default_workspace_6x6"
+ launcher:deviceCategory="phone|multi_display" >
+
+ <display-option
+ launcher:name="Large Phone"
+ launcher:minWidthDps="406"
+ launcher:minHeightDps="694"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="12.0"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+</profiles>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 90de498..5d3c9b0 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -50,6 +50,32 @@
launcher:logIdOn="615"
launcher:logIdOff="616" />
+ <SwitchPreference
+ android:key="pref_allow_phone_taskbar"
+ android:title="@string/pref_allow_phone_taskbar"
+ android:summary="@string/pref_allow_phone_taskbar_desc" />
+
+ <SwitchPreference
+ android:key="pref_allow_phone_overview_grid"
+ android:title="@string/pref_allow_phone_overview_grid"
+ android:summary="@string/pref_allow_phone_overview_grid_desc" />
+
+ <SwitchPreference
+ android:defaultValue="true"
+ android:key="pref_enable_minus_one"
+ android:summary="@string/pref_show_google_now_summary"
+ android:title="@string/title_show_google_app"/>
+
+ <androidx.preference.PreferenceScreen
+ android:key="pref_suggestions"
+ android:persistent="false"
+ android:title="@string/pref_suggestions_title"
+ android:summary="@string/pref_suggestions_summary">
+
+ <intent android:action="android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS" />
+
+ </androidx.preference.PreferenceScreen>
+
<androidx.preference.PreferenceScreen
android:key="pref_developer_options"
android:persistent="false"
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index d2b9dfe..4f020c9 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -23,6 +23,7 @@
import android.annotation.SuppressLint;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Path;
@@ -48,6 +49,9 @@
@SuppressLint("NewApi")
public class DeviceProfile {
+ public static final String KEY_PHONE_TASKBAR = "pref_allow_phone_taskbar";
+ public static final String KEY_PHONE_OVERVIEW_GRID = "pref_allow_phone_overview_grid";
+
private static final int DEFAULT_DOT_SIZE = 100;
// Ratio of empty space, qsb should take up to appear visually centered.
private static final float QSB_CENTER_FACTOR = .325f;
@@ -270,7 +274,9 @@
}
hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
- isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ boolean allowPhoneTaskbar = prefs.getBoolean(KEY_PHONE_TASKBAR, false);
+ isTaskbarPresent = (isTablet || allowPhoneTaskbar) && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS
&& FeatureFlags.ENABLE_TASKBAR.get();
if (isTaskbarPresent) {
taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
@@ -355,7 +361,9 @@
? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin)
: 0;
- overviewShowAsGrid = isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
+ boolean allowPhoneOverviewGrid = prefs.getBoolean(KEY_PHONE_OVERVIEW_GRID, false);
+ overviewShowAsGrid = (isTablet || allowPhoneOverviewGrid) &&
+ FeatureFlags.ENABLE_OVERVIEW_GRID.get();
overviewTaskMarginPx = overviewShowAsGrid
? res.getDimensionPixelSize(R.dimen.overview_task_margin_focused)
: res.getDimensionPixelSize(R.dimen.overview_task_margin);
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index ff7a90c..49d697d 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -26,6 +26,7 @@
import android.appwidget.AppWidgetHostView;
import android.content.ComponentName;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -55,6 +56,7 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.WindowBounds;
+import com.android.quickstep.SystemUiProxy;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -66,7 +68,7 @@
import java.util.Collections;
import java.util.List;
-public class InvariantDeviceProfile {
+public class InvariantDeviceProfile implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String TAG = "IDP";
// We do not need any synchronization for this variable as its only written on UI thread.
@@ -167,6 +169,7 @@
public Rect defaultWidgetPadding;
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
+ private Context mContext;
@VisibleForTesting
public InvariantDeviceProfile() {
@@ -187,6 +190,23 @@
onConfigChanged(displayContext);
}
});
+
+ mContext = context;
+ Utilities.getPrefs(context).registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (DeviceProfile.KEY_PHONE_TASKBAR.equals(key)) {
+ // Create the illusion of this taking effect immediately
+ // Also needed because TaskbarManager inits before SystemUiProxy on start
+ boolean enabled = Utilities.getPrefs(mContext).getBoolean(DeviceProfile.KEY_PHONE_TASKBAR, false);
+ SystemUiProxy.INSTANCE.get(mContext).setTaskbarEnabled(enabled);
+
+ onConfigChanged(mContext, true);
+ } else if (DeviceProfile.KEY_PHONE_OVERVIEW_GRID.equals(key)) {
+ onConfigChanged(mContext, false);
+ }
}
/**
@@ -398,6 +418,10 @@
}
private void onConfigChanged(Context context) {
+ onConfigChanged(context, false);
+ }
+
+ private void onConfigChanged(Context context, boolean taskbarChanged) {
Object[] oldState = toModelState();
// Re-init grid
@@ -406,7 +430,7 @@
boolean modelPropsChanged = !Arrays.equals(oldState, toModelState());
for (OnIDPChangeListener listener : mChangeListeners) {
- listener.onIdpChanged(modelPropsChanged);
+ listener.onIdpChanged(modelPropsChanged, taskbarChanged);
}
}
@@ -654,7 +678,7 @@
/**
* Called when the device provide changes
*/
- void onIdpChanged(boolean modelPropertiesChanged);
+ void onIdpChanged(boolean modelPropertiesChanged, boolean taskbarChanged);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 87eb222..777c5a7 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -380,6 +380,8 @@
protected InstanceId mAllAppsSessionLogId;
private LauncherState mPrevLauncherState;
+ private boolean mPendingRestart;
+
@Override
@TargetApi(Build.VERSION_CODES.S)
protected void onCreate(Bundle savedInstanceState) {
@@ -591,7 +593,7 @@
public void onConfigurationChanged(Configuration newConfig) {
int diff = newConfig.diff(mOldConfig);
if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
- onIdpChanged(false);
+ onIdpChanged(false, false);
}
mOldConfig.setTo(newConfig);
@@ -599,7 +601,11 @@
}
@Override
- public void onIdpChanged(boolean modelPropertiesChanged) {
+ public void onIdpChanged(boolean modelPropertiesChanged, boolean taskbarChanged) {
+ if (taskbarChanged) {
+ mPendingRestart = true;
+ }
+
initDeviceProfile(mDeviceProfile.inv);
dispatchDeviceProfileChanged();
reapplyUi();
@@ -1145,6 +1151,10 @@
}
TraceHelper.INSTANCE.endSection(traceToken);
+
+ if (mPendingRestart) {
+ System.exit(0);
+ }
}
@Override
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 10023b4..adbb36b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -83,7 +83,7 @@
Log.v(Launcher.TAG, "LauncherAppState initiated");
Preconditions.assertUIThread();
- mInvariantDeviceProfile.addOnChangeListener(modelPropertiesChanged -> {
+ mInvariantDeviceProfile.addOnChangeListener((modelPropertiesChanged, taskbarChanged) -> {
if (modelPropertiesChanged) {
refreshAndReloadLauncher();
}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index e59eac8..9845d88 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -16,7 +16,10 @@
private static final String XML = ".xml";
public static final String LAUNCHER_DB = "launcher.db";
+ public static final String LAUNCHER_6_BY_6_DB = "launcher_6_by_6.db";
public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db";
+ public static final String LAUNCHER_5_BY_7_DB = "launcher_5_by_7.db";
+ public static final String LAUNCHER_5_BY_6_DB = "launcher_5_by_6.db";
public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
public static final String LAUNCHER_4_BY_4_DB = "launcher_4_by_4.db";
public static final String LAUNCHER_3_BY_3_DB = "launcher_3_by_3.db";
@@ -33,7 +36,10 @@
public static final List<String> GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList(
LAUNCHER_DB,
+ LAUNCHER_6_BY_6_DB,
LAUNCHER_6_BY_5_DB,
+ LAUNCHER_5_BY_7_DB,
+ LAUNCHER_5_BY_6_DB,
LAUNCHER_4_BY_5_DB,
LAUNCHER_4_BY_4_DB,
LAUNCHER_3_BY_3_DB,
diff --git a/src/com/android/launcher3/OverlayCallbackImpl.java b/src/com/android/launcher3/OverlayCallbackImpl.java
new file mode 100644
index 0000000..8d8609b
--- /dev/null
+++ b/src/com/android/launcher3/OverlayCallbackImpl.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.Utilities;
+import com.android.systemui.plugins.shared.LauncherOverlayManager;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
+
+import com.google.android.libraries.gsa.launcherclient.LauncherClient;
+import com.google.android.libraries.gsa.launcherclient.LauncherClientCallbacks;
+
+import java.io.PrintWriter;
+
+/**
+ * Implements {@link LauncherOverlay} and passes all the corresponding events to {@link
+ * LauncherClient}. {@see setClient}
+ *
+ * <p>Implements {@link LauncherClientCallbacks} and sends all the corresponding callbacks to {@link
+ * Launcher}.
+ */
+public class OverlayCallbackImpl
+ implements LauncherOverlay, LauncherClientCallbacks, LauncherOverlayManager,
+ OnSharedPreferenceChangeListener {
+
+ public static final String KEY_ENABLE_MINUS_ONE = "pref_enable_minus_one";
+
+ private final Launcher mLauncher;
+ private final LauncherClient mClient;
+
+ private LauncherOverlayCallbacks mLauncherOverlayCallbacks;
+ private boolean mWasOverlayAttached = false;
+
+ public OverlayCallbackImpl(Launcher launcher) {
+ SharedPreferences prefs = Utilities.getPrefs(launcher);
+
+ mLauncher = launcher;
+ mClient = new LauncherClient(mLauncher, this, getClientOptions(prefs));
+ prefs.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onDeviceProvideChanged() {
+ mClient.reattachOverlay();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ mClient.onAttachedToWindow();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ mClient.onDetachedFromWindow();
+ }
+
+ @Override
+ public void dump(String prefix, PrintWriter w) {
+ mClient.dump(prefix, w);
+ }
+
+ @Override
+ public void openOverlay() {
+ mClient.showOverlay(true);
+ }
+
+ @Override
+ public void hideOverlay(boolean animate) {
+ mClient.hideOverlay(animate);
+ }
+
+ @Override
+ public void hideOverlay(int duration) {
+ mClient.hideOverlay(duration);
+ }
+
+ @Override
+ public boolean startSearch(byte[] config, Bundle extras) {
+ return false;
+ }
+
+ @Override
+ public void onActivityCreated(Activity activity, Bundle bundle) {
+ // Not called
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ mClient.onStart();
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ mClient.onResume();
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ mClient.onPause();
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ mClient.onStop();
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ mClient.onDestroy();
+ mLauncher.getSharedPrefs().unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (KEY_ENABLE_MINUS_ONE.equals(key)) {
+ mClient.setClientOptions(getClientOptions(prefs));
+ }
+ }
+
+ @Override
+ public void onServiceStateChanged(boolean overlayAttached, boolean hotwordActive) {
+ if (overlayAttached != mWasOverlayAttached) {
+ mWasOverlayAttached = overlayAttached;
+ mLauncher.setLauncherOverlay(overlayAttached ? this : null);
+ }
+ }
+
+ @Override
+ public void onOverlayScrollChanged(float progress) {
+ if (mLauncherOverlayCallbacks != null) {
+ mLauncherOverlayCallbacks.onScrollChanged(progress);
+ }
+ }
+
+ @Override
+ public void onScrollInteractionBegin() {
+ mClient.startMove();
+ }
+
+ @Override
+ public void onScrollInteractionEnd() {
+ mClient.endMove();
+ }
+
+ @Override
+ public void onScrollChange(float progress, boolean rtl) {
+ mClient.updateMove(progress);
+ }
+
+ @Override
+ public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks) {
+ mLauncherOverlayCallbacks = callbacks;
+ }
+
+
+ private LauncherClient.ClientOptions getClientOptions(SharedPreferences prefs) {
+ return new LauncherClient.ClientOptions(
+ prefs.getBoolean(KEY_ENABLE_MINUS_ONE, true),
+ true, /* enableHotword */
+ true /* enablePrewarming */
+ );
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 3ba6ea4..a796d13 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -760,6 +760,7 @@
if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) {
mHeaderColor = headerColor;
mTabsProtectionAlpha = tabsAlpha;
+ getSearchView().setBackgroundResource(R.drawable.bg_all_apps_searchbox);
invalidateHeader();
}
if (mSearchUiManager.getEditText() != null) {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 85ee636..44ec71c 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -314,7 +314,7 @@
mTabLayout.setTranslationY(mTranslationY);
- int clipHeight = mHeaderTopPadding - getPaddingBottom();
+ int clipHeight = mHeaderTopPadding - getPaddingBottom() * 2;
mRVClip.top = mTabsHidden ? clipHeight : 0;
mHeaderClip.top = clipHeight;
// clipping on a draw might cause additional redraw
@@ -441,7 +441,7 @@
if (mTabsHidden || !mHeaderCollapsed) {
return 0;
}
- return Math.max(getHeight() - getPaddingTop() + mTranslationY, 0);
+ return Math.max(getHeight() - getPaddingTop() + mTranslationY + getPaddingBottom(), 0);
}
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 4c5a9e6..77ed796 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -79,7 +79,6 @@
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
- setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
mContentOverlap =
getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 2d31aa4..186e36c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -40,7 +40,7 @@
private FeatureFlags() { }
public static boolean showFlagTogglerUi(Context context) {
- return Utilities.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context);
+ return Utilities.isDevelopersOptionsEnabled(context);
}
/**
@@ -52,7 +52,7 @@
* Enable moving the QSB on the 0th screen of the workspace. This is not a configuration feature
* and should be modified at a project level.
*/
- public static final boolean QSB_ON_FIRST_SCREEN = true;
+ public static final boolean QSB_ON_FIRST_SCREEN = false;
/**
* Feature flag to handle define config changes dynamically instead of killing the process.
@@ -74,7 +74,7 @@
// TODO: b/206508141: Long pressing on some icons on home screen cause launcher to crash.
public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
- "ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
+ "ENABLE_LOCAL_COLOR_POPUPS", true, "Enable local color extraction for popups.");
public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag(
"KEYGUARD_ANIMATION", false, "Enable animation for keyguard going away on wallpaper");
@@ -209,7 +209,7 @@
"Uses two panel on home screen. Only applicable on large screen devices.");
public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(
- "ENABLE_SCRIM_FOR_APP_LAUNCH", false,
+ "ENABLE_SCRIM_FOR_APP_LAUNCH", true,
"Enables scrim during app launch animation.");
public static final BooleanFlag ENABLE_SPLIT_SELECT = getDebugFlag(
@@ -334,8 +334,6 @@
}
private static BooleanFlag getDebugFlag(String key, boolean defaultValue, String description) {
- return Utilities.IS_DEBUG_DEVICE
- ? new DebugFlag(key, defaultValue, description)
- : new BooleanFlag(key, defaultValue);
+ return new DebugFlag(key, defaultValue, description);
}
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 0c39632..1305479 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -20,8 +20,12 @@
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
+import static com.android.launcher3.OverlayCallbackImpl.KEY_ENABLE_MINUS_ONE;
+
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MenuItem;
@@ -63,9 +67,8 @@
SharedPreferences.OnSharedPreferenceChangeListener{
/** List of fragments that can be hosted by this activity. */
- private static final List<String> VALID_PREFERENCE_FRAGMENTS =
- !Utilities.IS_DEBUG_DEVICE ? Collections.emptyList()
- : Collections.singletonList(DeveloperOptionsFragment.class.getName());
+ private static final List<String> VALID_PREFERENCE_FRAGMENTS = Collections.singletonList(
+ DeveloperOptionsFragment.class.getName());
private static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
private static final String FLAGS_PREFERENCE_KEY = "flag_toggler";
@@ -189,6 +192,10 @@
private boolean mPreferenceHighlighted = false;
private Preference mDeveloperOptionPref;
+ protected static final String GSA_PACKAGE = "com.google.android.googlequicksearchbox";
+
+ private Preference mShowGoogleAppPref;
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final Bundle args = getArguments();
@@ -270,6 +277,11 @@
case DEVELOPER_OPTIONS_KEY:
mDeveloperOptionPref = preference;
return updateDeveloperOption();
+
+ case KEY_ENABLE_MINUS_ONE:
+ mShowGoogleAppPref = preference;
+ updateIsGoogleAppEnabled();
+ return true;
}
return true;
@@ -293,6 +305,20 @@
return showPreference;
}
+ public static boolean isGSAEnabled(Context context) {
+ try {
+ return context.getPackageManager().getApplicationInfo(GSA_PACKAGE, 0).enabled;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ private void updateIsGoogleAppEnabled() {
+ if (mShowGoogleAppPref != null) {
+ mShowGoogleAppPref.setEnabled(isGSAEnabled(getContext()));
+ }
+ }
+
@Override
public void onResume() {
super.onResume();
@@ -308,6 +334,7 @@
requestAccessibilityFocus(getListView());
}
}
+ updateIsGoogleAppEnabled();
}
private PreferenceHighlighter createHighlighter() {
diff --git a/src/org/protonaosp/launcher3/ThemedLocalColorExtractor.java b/src/org/protonaosp/launcher3/ThemedLocalColorExtractor.java
new file mode 100644
index 0000000..955a72e
--- /dev/null
+++ b/src/org/protonaosp/launcher3/ThemedLocalColorExtractor.java
@@ -0,0 +1,280 @@
+/*
+ * 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 org.protonaosp.launcher3;
+
+import android.app.WallpaperColors;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.provider.Settings;
+import android.util.SparseIntArray;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.widget.LocalColorExtractor;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import dev.kdrag0n.colorkt.Color;
+import dev.kdrag0n.colorkt.cam.Zcam;
+import dev.kdrag0n.colorkt.data.Illuminants;
+import dev.kdrag0n.colorkt.rgb.Srgb;
+import dev.kdrag0n.colorkt.tristimulus.CieXyzAbs;
+import dev.kdrag0n.colorkt.ucs.lab.CieLab;
+import dev.kdrag0n.monet.theme.ColorScheme;
+import dev.kdrag0n.monet.theme.DynamicColorScheme;
+import dev.kdrag0n.monet.theme.MaterialYouTargets;
+
+import java.util.Collections;
+import java.util.Map;
+
+public class ThemedLocalColorExtractor extends LocalColorExtractor implements
+ WallpaperManager.LocalWallpaperColorConsumer {
+ private static final String KEY_COLOR_SOURCE = "android.theme.customization.color_source";
+
+ // Shade number -> color resource ID maps
+ private static final SparseIntArray ACCENT1_RES = new SparseIntArray(13);
+ private static final SparseIntArray ACCENT2_RES = new SparseIntArray(13);
+ private static final SparseIntArray ACCENT3_RES = new SparseIntArray(13);
+ private static final SparseIntArray NEUTRAL1_RES = new SparseIntArray(13);
+ private static final SparseIntArray NEUTRAL2_RES = new SparseIntArray(13);
+
+ // Viewing conditions and targets for theme generation
+ private final Zcam.ViewingConditions cond = new Zcam.ViewingConditions(
+ /* surroundFactor */ Zcam.ViewingConditions.SURROUND_AVERAGE,
+ /* adaptingLuminance */ 0.4 * CieXyzAbs.DEFAULT_SDR_WHITE_LUMINANCE,
+ /* backgroundLuminance */ new CieLab(50.0, 0.0, 0.0, Illuminants.D65)
+ .toXyz().getY() * CieXyzAbs.DEFAULT_SDR_WHITE_LUMINANCE,
+ /* referenceWhite */ CieXyzAbs.fromRel(Illuminants.D65,
+ CieXyzAbs.DEFAULT_SDR_WHITE_LUMINANCE)
+ );
+ private final ColorScheme targets = new MaterialYouTargets(1.0, false, cond);
+
+ private final WallpaperManager wallpaperManager;
+ private Listener listener;
+
+ private boolean applyOverlay = true;
+
+ // For calculating and returning bounds
+ private final float[] tempFloatArray = new float[4];
+ private final Rect tempRect = new Rect();
+ private final RectF tempRectF = new RectF();
+
+ static {
+ ACCENT1_RES.put( 0, android.R.color.system_accent1_0);
+ ACCENT1_RES.put( 10, android.R.color.system_accent1_10);
+ ACCENT1_RES.put( 50, android.R.color.system_accent1_50);
+ ACCENT1_RES.put( 100, android.R.color.system_accent1_100);
+ ACCENT1_RES.put( 200, android.R.color.system_accent1_200);
+ ACCENT1_RES.put( 300, android.R.color.system_accent1_300);
+ ACCENT1_RES.put( 400, android.R.color.system_accent1_400);
+ ACCENT1_RES.put( 500, android.R.color.system_accent1_500);
+ ACCENT1_RES.put( 600, android.R.color.system_accent1_600);
+ ACCENT1_RES.put( 700, android.R.color.system_accent1_700);
+ ACCENT1_RES.put( 800, android.R.color.system_accent1_800);
+ ACCENT1_RES.put( 900, android.R.color.system_accent1_900);
+ ACCENT1_RES.put(1000, android.R.color.system_accent1_1000);
+
+ ACCENT2_RES.put( 0, android.R.color.system_accent2_0);
+ ACCENT2_RES.put( 10, android.R.color.system_accent2_10);
+ ACCENT2_RES.put( 50, android.R.color.system_accent2_50);
+ ACCENT2_RES.put( 100, android.R.color.system_accent2_100);
+ ACCENT2_RES.put( 200, android.R.color.system_accent2_200);
+ ACCENT2_RES.put( 300, android.R.color.system_accent2_300);
+ ACCENT2_RES.put( 400, android.R.color.system_accent2_400);
+ ACCENT2_RES.put( 500, android.R.color.system_accent2_500);
+ ACCENT2_RES.put( 600, android.R.color.system_accent2_600);
+ ACCENT2_RES.put( 700, android.R.color.system_accent2_700);
+ ACCENT2_RES.put( 800, android.R.color.system_accent2_800);
+ ACCENT2_RES.put( 900, android.R.color.system_accent2_900);
+ ACCENT2_RES.put(1000, android.R.color.system_accent2_1000);
+
+ ACCENT3_RES.put( 0, android.R.color.system_accent3_0);
+ ACCENT3_RES.put( 10, android.R.color.system_accent3_10);
+ ACCENT3_RES.put( 50, android.R.color.system_accent3_50);
+ ACCENT3_RES.put( 100, android.R.color.system_accent3_100);
+ ACCENT3_RES.put( 200, android.R.color.system_accent3_200);
+ ACCENT3_RES.put( 300, android.R.color.system_accent3_300);
+ ACCENT3_RES.put( 400, android.R.color.system_accent3_400);
+ ACCENT3_RES.put( 500, android.R.color.system_accent3_500);
+ ACCENT3_RES.put( 600, android.R.color.system_accent3_600);
+ ACCENT3_RES.put( 700, android.R.color.system_accent3_700);
+ ACCENT3_RES.put( 800, android.R.color.system_accent3_800);
+ ACCENT3_RES.put( 900, android.R.color.system_accent3_900);
+ ACCENT3_RES.put(1000, android.R.color.system_accent3_1000);
+
+ NEUTRAL1_RES.put( 0, android.R.color.system_neutral1_0);
+ NEUTRAL1_RES.put( 10, android.R.color.system_neutral1_10);
+ NEUTRAL1_RES.put( 50, android.R.color.system_neutral1_50);
+ NEUTRAL1_RES.put( 100, android.R.color.system_neutral1_100);
+ NEUTRAL1_RES.put( 200, android.R.color.system_neutral1_200);
+ NEUTRAL1_RES.put( 300, android.R.color.system_neutral1_300);
+ NEUTRAL1_RES.put( 400, android.R.color.system_neutral1_400);
+ NEUTRAL1_RES.put( 500, android.R.color.system_neutral1_500);
+ NEUTRAL1_RES.put( 600, android.R.color.system_neutral1_600);
+ NEUTRAL1_RES.put( 700, android.R.color.system_neutral1_700);
+ NEUTRAL1_RES.put( 800, android.R.color.system_neutral1_800);
+ NEUTRAL1_RES.put( 900, android.R.color.system_neutral1_900);
+ NEUTRAL1_RES.put(1000, android.R.color.system_neutral1_1000);
+
+ NEUTRAL2_RES.put( 0, android.R.color.system_neutral2_0);
+ NEUTRAL2_RES.put( 10, android.R.color.system_neutral2_10);
+ NEUTRAL2_RES.put( 50, android.R.color.system_neutral2_50);
+ NEUTRAL2_RES.put( 100, android.R.color.system_neutral2_100);
+ NEUTRAL2_RES.put( 200, android.R.color.system_neutral2_200);
+ NEUTRAL2_RES.put( 300, android.R.color.system_neutral2_300);
+ NEUTRAL2_RES.put( 400, android.R.color.system_neutral2_400);
+ NEUTRAL2_RES.put( 500, android.R.color.system_neutral2_500);
+ NEUTRAL2_RES.put( 600, android.R.color.system_neutral2_600);
+ NEUTRAL2_RES.put( 700, android.R.color.system_neutral2_700);
+ NEUTRAL2_RES.put( 800, android.R.color.system_neutral2_800);
+ NEUTRAL2_RES.put( 900, android.R.color.system_neutral2_900);
+ NEUTRAL2_RES.put(1000, android.R.color.system_neutral2_1000);
+ }
+
+ public ThemedLocalColorExtractor(Context context) {
+ wallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
+
+ try {
+ String json = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES);
+ if (json != null && !json.isEmpty()) {
+ JSONObject packages = new JSONObject(json);
+ applyOverlay = !"preset".equals(packages.getString(KEY_COLOR_SOURCE));
+ }
+ } catch (JSONException e) {
+ // Ignore: enabled by default
+ }
+ }
+
+ private static void addColorsToArray(Map<Integer, Color> swatch,
+ SparseIntArray resMap, SparseIntArray array) {
+ for (Map.Entry<Integer, Color> entry : swatch.entrySet()) {
+ int shade = entry.getKey();
+ int resId = resMap.get(shade, -1);
+ if (resId != -1) {
+ Srgb color = (Srgb) entry.getValue();
+ array.put(resId, 0xff000000 | color.toRgb8());
+ }
+ }
+ }
+
+ @Override
+ public void setListener(Listener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void setWorkspaceLocation(Rect pos, View child, int screenId) {
+ Launcher launcher = ActivityContext.lookupContext(child.getContext());
+ getExtractedRectForViewRect(launcher, screenId, pos, tempRectF);
+
+ // Refresh listener
+ wallpaperManager.removeOnColorsChangedListener(this);
+ wallpaperManager.addOnColorsChangedListener(this, Collections.singletonList(tempRectF));
+ }
+
+ @Override
+ public SparseIntArray generateColorsOverride(WallpaperColors colors) {
+ if (!applyOverlay) {
+ return null;
+ }
+
+ SparseIntArray colorRes = new SparseIntArray(5 * 13);
+ Color color = new Srgb(colors.getPrimaryColor().toArgb());
+ ColorScheme colorScheme = new DynamicColorScheme(targets, color, 1.0, cond, true);
+
+ addColorsToArray(colorScheme.getAccent1(), ACCENT1_RES, colorRes);
+ addColorsToArray(colorScheme.getAccent2(), ACCENT2_RES, colorRes);
+ addColorsToArray(colorScheme.getAccent3(), ACCENT3_RES, colorRes);
+ addColorsToArray(colorScheme.getNeutral1(), NEUTRAL1_RES, colorRes);
+ addColorsToArray(colorScheme.getNeutral2(), NEUTRAL2_RES, colorRes);
+
+ return colorRes;
+ }
+
+ @Override
+ public void applyColorsOverride(Context base, WallpaperColors colors) {
+ if (!applyOverlay) {
+ return;
+ }
+
+ RemoteViews.ColorResources res = RemoteViews.ColorResources.create(base, generateColorsOverride(colors));
+ if (res != null) {
+ res.apply(base);
+ }
+ }
+
+ private void getExtractedRectForViewRect(Launcher launcher, int pageId, Rect rectInDragLayer,
+ RectF colorExtractionRectOut) {
+ // If the view hasn't been measured and laid out, we cannot do this.
+ if (rectInDragLayer.isEmpty()) {
+ colorExtractionRectOut.setEmpty();
+ return;
+ }
+
+ Resources res = launcher.getResources();
+ DeviceProfile dp = launcher.getDeviceProfile().inv.getDeviceProfile(launcher);
+ float screenWidth = dp.widthPx;
+ float screenHeight = dp.heightPx;
+ int numScreens = launcher.getWorkspace().getNumPagesForWallpaperParallax();
+ pageId = Utilities.isRtl(res) ? numScreens - pageId - 1 : pageId;
+ float relativeScreenWidth = 1f / numScreens;
+
+ int[] dragLayerBounds = new int[2];
+ launcher.getDragLayer().getLocationOnScreen(dragLayerBounds);
+ // Translate from drag layer coordinates to screen coordinates.
+ int screenLeft = rectInDragLayer.left + dragLayerBounds[0];
+ int screenTop = rectInDragLayer.top + dragLayerBounds[1];
+ int screenRight = rectInDragLayer.right + dragLayerBounds[0];
+ int screenBottom = rectInDragLayer.bottom + dragLayerBounds[1];
+
+ // This is the position of the view 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 view relative to the screen. For the vertical axis, this is
+ // simply the location of the view relative to the screen.
+ // Translate from drag layer coordinates to screen coordinates
+ colorExtractionRectOut.left = (screenLeft / screenWidth + pageId) * relativeScreenWidth;
+ colorExtractionRectOut.right = (screenRight / screenWidth + pageId) * relativeScreenWidth;
+ colorExtractionRectOut.top = screenTop / screenHeight;
+ colorExtractionRectOut.bottom = screenBottom / screenHeight;
+
+ if (colorExtractionRectOut.left < 0
+ || colorExtractionRectOut.right > 1
+ || colorExtractionRectOut.top < 0
+ || colorExtractionRectOut.bottom > 1) {
+ colorExtractionRectOut.setEmpty();
+ }
+ }
+
+ @Override
+ public void onColorsChanged(RectF area, WallpaperColors colors) {
+ if (listener != null) {
+ listener.onColorsChanged(generateColorsOverride(colors));
+ }
+ }
+}