Merge tag 'android-15.0.0_r32' of https://android.googlesource.com/platform/packages/apps/Launcher3 into HEAD
Android 15.0.0 Release 32 (BP1A.250505.005)
Change-Id: I6986c8f9627036a5c4d883fbf64e0bd4c6e41e11
diff --git a/Android.bp b/Android.bp
index 73d0fce..10ed01f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -397,6 +397,7 @@
"kotlinx_coroutines",
"com_android_launcher3_flags_lib",
"com_android_wm_shell_flags_lib",
+ "OmniPreferenceTheme",
"dagger2",
"jsr330",
"com_android_systemui_shared_flags_lib",
@@ -518,12 +519,13 @@
// Library with all the source code and dependencies for building Quickstep
android_library {
- name: "Launcher3QuickStepLib",
+ name: "Launcher3QuickStepLibGoogle",
defaults: [
"launcher_compose_defaults",
"quickstep_compose_defaults",
],
srcs: [
+ "src_overlay/google/com/android/launcher3/overlay/OverlayCallbackImpl.java",
":launcher-src",
":launcher-quickstep-src",
":launcher-quickstep-dagger",
@@ -538,6 +540,43 @@
// in QuickstepResLib to take precendece, so it should be the final
// dependency. See b/208647810 for how this can go wrong.
static_libs: [
+ "OmniLib",
+ "//vendor/omni:libGoogleFeed",
+ "SystemUI-statsd",
+ "QuickstepResLib",
+ ],
+ manifest: "quickstep/AndroidManifest.xml",
+ platform_apis: true,
+ plugins: ["dagger2-compiler"],
+ min_sdk_version: "current",
+ // TODO(b/319712088): re-enable use_resource_processor
+ use_resource_processor: false,
+}
+
+android_library {
+ name: "Launcher3QuickStepLibMock",
+ defaults: [
+ "launcher_compose_defaults",
+ "quickstep_compose_defaults",
+ ],
+ srcs: [
+ "src_overlay/mock/com/android/launcher3/overlay/OverlayCallbackImpl.java",
+ "src_overlay/mock/com/google/android/libraries/gsa/launcherclient/LauncherClientCallbacks.java",
+ ":launcher-src",
+ ":launcher-quickstep-src",
+ ":launcher-quickstep-dagger",
+ ":launcher-build-config",
+ ],
+ resource_dirs: [],
+ libs: [
+ "framework-statsd.stubs.module_lib",
+ ],
+ // Note the ordering here is important when it comes to resource
+ // overriding. We want the most specific resource overrides defined
+ // in QuickstepResLib to take precendece, so it should be the final
+ // dependency. See b/208647810 for how this can go wrong.
+ static_libs: [
+ "OmniLib",
"SystemUI-statsd",
"QuickstepResLib",
],
@@ -552,7 +591,7 @@
// Build rule for Quickstep app.
android_app {
name: "Launcher3QuickStep",
- static_libs: ["Launcher3QuickStepLib"],
+ defaults: ["omni_launcher3_defaults"],
optimize: {
proguard_flags_files: [":launcher-proguard-rules"],
enabled: true,
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 517bd6d..89291c1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -67,6 +67,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/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml
index 2223036..c7562f1 100644
--- a/go/AndroidManifest-launcher.xml
+++ b/go/AndroidManifest-launcher.xml
@@ -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/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 80d8154..813ef75 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -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/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index fcd2e54..f16b7de 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -36,6 +36,21 @@
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Button
+ style="@style/OverviewActionButton"
+ android:id="@+id/action_clear_all"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/recents_clear_all"
+ android:theme="@style/ThemeControlHighlightWorkspaceColor"
+ android:drawableStart="@drawable/ic_close_all" />
+
+ <Space
+ android:id="@+id/action_split_space"
+ android:layout_width="@dimen/overview_actions_button_spacing"
+ android:layout_height="1dp"
+ android:visibility="gone" />
+
+ <Button
android:id="@+id/action_split"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
diff --git a/quickstep/res/values/custom_strings.xml b/quickstep/res/values/custom_strings.xml
new file mode 100644
index 0000000..f8993a6
--- /dev/null
+++ b/quickstep/res/values/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2017 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recents_clear">Clear</string>
+</resources>
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index b51409c..622826d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -197,7 +197,7 @@
}
// TODO: Disable touch events on QSB otherwise it can crash.
- mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+ mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat_taskbar, this, false);
mNumStaticViews = taskbarRecentsLayoutTransition() && !mActivityContext.isPhoneMode()
? addStaticViews() : 0;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 999b13e..6db202c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -131,6 +131,7 @@
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.overlay.OverlayCallbackImpl;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.statehandlers.DepthController;
@@ -192,6 +193,7 @@
import com.android.quickstep.views.RecentsViewContainer;
import com.android.quickstep.views.TaskView;
import com.android.systemui.animation.back.FlingOnBackAnimationCallback;
+import com.android.systemui.plugins.shared.LauncherOverlayManager;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.unfold.RemoteUnfoldSharedComponent;
@@ -271,6 +273,11 @@
}
@Override
+ protected LauncherOverlayManager getDefaultOverlay() {
+ return new OverlayCallbackImpl(this);
+ }
+
+ @Override
protected void setupViews() {
super.setupViews();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index 932d241..eeb6223 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -45,7 +45,7 @@
@Override
public int getVisibleElements(Launcher launcher) {
- return OVERVIEW_ACTIONS | CLEAR_ALL_BUTTON;
+ return OVERVIEW_ACTIONS;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index c48ba4f..19c8399 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -110,7 +110,7 @@
@Override
public int getVisibleElements(Launcher launcher) {
- int elements = CLEAR_ALL_BUTTON | OVERVIEW_ACTIONS;
+ int elements = OVERVIEW_ACTIONS;
DeviceProfile dp = launcher.getDeviceProfile();
boolean showFloatingSearch;
if (dp.isPhone) {
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index ff9c9f6..e623ed0 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -120,7 +120,9 @@
TaskShortcutFactory.WELLBEING,
TaskShortcutFactory.SAVE_APP_PAIR,
TaskShortcutFactory.SCREENSHOT,
- TaskShortcutFactory.MODAL
+ TaskShortcutFactory.MODAL,
+ TaskShortcutFactory.CLEAR_TASK,
+ TaskShortcutFactory.CLEAR_ALL_TASK
};
/**
@@ -229,6 +231,12 @@
}
}
+ private void clearAllTasks() {
+ RecentsView recentsView =
+ mTaskContainer.getThumbnailViewDeprecated().getTaskView().getRecentsView();
+ recentsView.dismissAllTasks(null);
+ }
+
protected void enterSplitSelect() {
RecentsView overviewPanel = mTaskContainer.getTaskView().getRecentsView();
// Task has already been dismissed
@@ -395,6 +403,10 @@
public void onSaveAppPair() {
endLiveTileMode(TaskOverlay.this::saveAppPair);
}
+
+ public void onClearAllTasks() {
+ endLiveTileMode(TaskOverlay.this::clearAllTasks);
+ }
}
}
@@ -411,5 +423,7 @@
/** User wants to save an app pair with current group of apps. */
void onSaveAppPair();
+
+ void onClearAllTasks();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 785666f..f8012d1 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -508,4 +508,59 @@
return createSingletonShortcutList(modalStateSystemShortcut);
}
};
+
+ TaskShortcutFactory CLEAR_TASK = new TaskShortcutFactory() {
+ @Override
+ public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
+ TaskContainer taskContainer) {
+ return Collections.singletonList(new ClearTaskSystemShortcut(container, taskContainer));
+ }
+ };
+
+ class ClearTaskSystemShortcut extends SystemShortcut<ActivityContext> {
+
+ private static final String TAG = "ClearTaskSystemShortcut";
+
+ private final TaskView mTaskView;
+
+ public ClearTaskSystemShortcut(ActivityContext target, TaskContainer taskContainer) {
+ super(R.drawable.ic_close, R.string.recents_clear, target, taskContainer.getItemInfo(),
+ taskContainer.getTaskView());
+ mTaskView = taskContainer.getTaskView();
+ }
+
+ @Override
+ public void onClick(View view) {
+ dismissTaskMenuView();
+ mTaskView.getRecentsView().dismissTask(mTaskView, true /*animateTaskView*/,
+ true /*removeTask*/);
+ }
+ }
+
+ TaskShortcutFactory CLEAR_ALL_TASK = new TaskShortcutFactory() {
+ @Override
+ public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
+ TaskContainer taskContainer) {
+ return Collections.singletonList(new ClearAllTaskSystemShortcut(container, taskContainer));
+ }
+ };
+
+ class ClearAllTaskSystemShortcut extends SystemShortcut<ActivityContext> {
+
+ private static final String TAG = "ClearAllTaskSystemShortcut";
+
+ private final TaskView mTaskView;
+
+ public ClearAllTaskSystemShortcut(ActivityContext target, TaskContainer taskContainer) {
+ super(R.drawable.ic_close_all, R.string.recents_clear_all, target, taskContainer.getItemInfo(),
+ taskContainer.getTaskView());
+ mTaskView = taskContainer.getTaskView();
+ }
+
+ @Override
+ public void onClick(View view) {
+ dismissTaskMenuView();
+ mTaskView.getRecentsView().dismissAllTasks(null);
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index c2e7536..b2cb7b1 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -117,7 +117,7 @@
* For this state, whether clear all button should be shown.
*/
public boolean hasClearAllButton() {
- return hasFlag(FLAG_CLEAR_ALL_BUTTON);
+ return false;
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 4a2be2a..160a511 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -181,6 +181,8 @@
mSplitButton = findViewById(R.id.action_split);
mSplitButton.setOnClickListener(this);
mSaveAppPairButton.setOnClickListener(this);
+ View clearallButton = findViewById(R.id.action_clear_all);
+ clearallButton.setOnClickListener(this);
}
/**
@@ -204,6 +206,8 @@
mCallbacks.onSplit();
} else if (id == R.id.action_save_app_pair) {
mCallbacks.onSaveAppPair();
+ } else if (id == R.id.action_clear_all) {
+ mCallbacks.onClearAllTasks();
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 6752775..4760654 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -4527,7 +4527,7 @@
}
@SuppressWarnings("unused")
- private void dismissAllTasks(View view) {
+ public void dismissAllTasks(View view) {
runDismissAnimation(createAllTasksDismissAnimation(DISMISS_TASK_DURATION));
mContainer.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
}
diff --git a/res/drawable/ic_close.xml b/res/drawable/ic_close.xml
new file mode 100644
index 0000000..70565f2
--- /dev/null
+++ b/res/drawable/ic_close.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M18.3,5.71a0.996,0.996 0,0 0,-1.41 0L12,10.59 7.11,5.7A0.996,0.996 0,1 0,5.7 7.11L10.59,12 5.7,16.89a0.996,0.996 0,1 0,1.41 1.41L12,13.41l4.89,4.89a0.996,0.996 0,1 0,1.41 -1.41L13.41,12l4.89,-4.89c0.38,-0.38 0.38,-1.02 0,-1.4z"
+ android:fillColor="#FF000000"/>
+</vector>
diff --git a/res/drawable/ic_close_all.xml b/res/drawable/ic_close_all.xml
new file mode 100644
index 0000000..edccc22
--- /dev/null
+++ b/res/drawable/ic_close_all.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M5,13H19V11H5M3,17H17V15H3M7,7V9H21V7"
+ android:fillColor="#FF000000"/>
+</vector>
diff --git a/res/layout/search_container_hotseat.xml b/res/layout/search_container_hotseat.xml
index 8f12ca0..3cbd402 100644
--- a/res/layout/search_container_hotseat.xml
+++ b/res/layout/search_container_hotseat.xml
@@ -14,7 +14,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<View
+<!--<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="0dp" />
\ No newline at end of file
+ android:layout_height="0dp" />-->
+
+<com.android.launcher3.qsb.QsbContainerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:id="@id/search_container_hotseat"
+ android:padding="0dp" >
+
+ <fragment
+ android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
+ android:layout_width="match_parent"
+ android:tag="qsb_view_hotseat"
+ android:layout_height="match_parent"/>
+</com.android.launcher3.qsb.QsbContainerView>
\ No newline at end of file
diff --git a/res/layout/search_container_hotseat_empty.xml b/res/layout/search_container_hotseat_empty.xml
new file mode 100644
index 0000000..8f12ca0
--- /dev/null
+++ b/res/layout/search_container_hotseat_empty.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<View
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="0dp" />
\ No newline at end of file
diff --git a/res/layout/search_container_hotseat_taskbar.xml b/res/layout/search_container_hotseat_taskbar.xml
new file mode 100644
index 0000000..8f12ca0
--- /dev/null
+++ b/res/layout/search_container_hotseat_taskbar.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<View
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="0dp" />
\ No newline at end of file
diff --git a/res/layout/search_container_workspace.xml b/res/layout/search_container_workspace.xml
index 1c617b1..3cf4f74 100644
--- a/res/layout/search_container_workspace.xml
+++ b/res/layout/search_container_workspace.xml
@@ -25,6 +25,6 @@
<fragment
android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
android:layout_width="match_parent"
- android:tag="qsb_view"
+ android:tag="qsb_view_workspace"
android:layout_height="match_parent"/>
</com.android.launcher3.qsb.QsbContainerView>
\ No newline at end of file
diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml
index 932ce38..0069426 100644
--- a/res/values-v31/styles.xml
+++ b/res/values-v31/styles.xml
@@ -25,10 +25,20 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:switchStyle">@style/SwitchStyle</item>
- <item name="android:textAppearanceListItem">@style/HomeSettings.PreferenceTitle</item>
+ <item name="android:textAppearanceListItem">@style/Omni.PreferenceTitle</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
- <item name="preferenceTheme">@style/HomeSettings.PreferenceTheme</item>
+ <item name="preferenceTheme">@style/Omni.PreferenceTheme</item>
+ <item name="alertDialogTheme">@style/AlertDialogTheme</item>
+ </style>
+
+ <style name="AlertDialogTheme" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
+ <item name="colorAccent">@color/home_settings_header_accent</item>
+ <item name="android:colorBackground">@color/home_settings_header_expanded</item>
+ <item name="android:windowSoftInputMode">adjustResize</item>
+ <item name="android:clipToPadding">true</item>
+ <item name="android:clipChildren">true</item>
+ <item name="dialogCornerRadius">8dp</item>
</style>
<style name="HomeSettings.PreferenceTheme" parent="@style/PreferenceThemeOverlay">
diff --git a/res/values/custom_arrays.xml b/res/values/custom_arrays.xml
new file mode 100644
index 0000000..37a0a19
--- /dev/null
+++ b/res/values/custom_arrays.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The OmniROM Project
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array name="prefs_qsb_location_entries">
+ <item>@string/pref_qsb_location_hotseat</item>
+ <item>@string/pref_qsb_location_workspace</item>
+ </string-array>
+ <string-array name="prefs_qsb_location_values">
+ <item>"0"</item>
+ <item>"1"</item>
+ </string-array>
+</resources>
diff --git a/res/values/custom_config.xml b/res/values/custom_config.xml
new file mode 100644
index 0000000..d771248
--- /dev/null
+++ b/res/values/custom_config.xml
@@ -0,0 +1,4 @@
+<resources>
+ <!-- Miscellaneous -->
+ <bool name="qsb_show_default">true</bool>
+</resources>
diff --git a/res/values/custom_dimens.xml b/res/values/custom_dimens.xml
new file mode 100644
index 0000000..ddf8791
--- /dev/null
+++ b/res/values/custom_dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The OmniROM Project
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <dimen name="hotseat_qsb_margin_top">8dp</dimen>
+
+</resources>
diff --git a/res/values/custom_strings.xml b/res/values/custom_strings.xml
new file mode 100644
index 0000000..a063d2f
--- /dev/null
+++ b/res/values/custom_strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The OmniROM Project
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <string name="state_loading">Applying\u2026</string>
+ <string name="pref_qsb_show_summary"></string>
+ <string name="pref_qsb_show_title">Show search widget</string>
+ <string name="pref_qsb_location_title">Search widget location</string>
+ <string name="pref_qsb_location_hotseat">Hotseat</string>
+ <string name="pref_qsb_location_hotseat_value" translatable="false">0</string>
+ <string name="pref_qsb_location_workspace">Workspace</string>
+ <string name="pref_qsb_location_workspace_value" translatable="false">1</string>
+ <string name="pref_grid_title">Grid size</string>
+ <string name="left_tab_label">Google feed tab</string>
+ <string name="left_tab_description">Toggle Google feed intergration</string>
+
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 21aabfa..b2f7353 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -115,7 +115,7 @@
<dimen name="all_apps_header_pill_corner_radius">12dp</dimen>
<dimen name="all_apps_header_tab_height">48dp</dimen>
<dimen name="all_apps_tabs_indicator_height">2dp</dimen>
- <dimen name="all_apps_header_top_margin">33dp</dimen>
+ <dimen name="all_apps_header_top_margin">50dp</dimen>
<dimen name="all_apps_header_top_padding">36dp</dimen>
<!-- Additional top padding to add when Floating Searchbar is enabled. -->
<dimen name="all_apps_additional_top_padding_floating_search">16dp</dimen>
@@ -431,7 +431,7 @@
@*android:dimen/rounded_corner_content_padding
</dimen>
<dimen name="taskbar_stashed_size">0dp</dimen>
- <dimen name="qsb_widget_height">0dp</dimen>
+ <dimen name="qsb_widget_height">72dp</dimen>
<dimen name="qsb_shadow_height">0dp</dimen>
<dimen name="min_hotseat_icon_space">18dp</dimen>
<dimen name="max_hotseat_icon_space">50dp</dimen>
diff --git a/res/xml/default_workspace_3x3.xml b/res/xml/default_workspace_3x3.xml
index 31376e1..5d4e8b9 100644
--- a/res/xml/default_workspace_3x3.xml
+++ b/res/xml/default_workspace_3x3.xml
@@ -17,7 +17,7 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Messaging, [All Apps], Dialer -->
+ <!-- Dialer, Messaging, Settings -->
<resolve
launcher:container="-101"
@@ -48,24 +48,7 @@
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="2"
- 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" />
+ <favorite launcher:uri="#Intent;action=org.omnirom.control.intents.LAUNCH;category=android.intent.category.DEFAULT;end" />
</resolve>
</favorites>
diff --git a/res/xml/default_workspace_4x4.xml b/res/xml/default_workspace_4x4.xml
index bf3c62c..84b2828 100644
--- a/res/xml/default_workspace_4x4.xml
+++ b/res/xml/default_workspace_4x4.xml
@@ -17,7 +17,7 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer, Messaging, Browser, Camera -->
+ <!-- Dialer, Messaging, Settings, Camera -->
<resolve
launcher:container="-101"
launcher:screen="0"
@@ -59,29 +59,12 @@
<favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
</resolve>
- <!-- Bottom row -->
+ <!-- Bottom row OmniControl -->
<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="3"
- 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" />
+ <favorite launcher:uri="#Intent;action=org.omnirom.control.intents.LAUNCH;category=android.intent.category.DEFAULT;end" />
</resolve>
</favorites>
diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml
index b4ac8f6..e74d7f1 100644
--- a/res/xml/default_workspace_5x5.xml
+++ b/res/xml/default_workspace_5x5.xml
@@ -17,7 +17,7 @@
<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Dialer, Messaging, [Maps/Music], Browser, Camera -->
+ <!-- Dialer, Messaging, Settings, OmniControl, Camera -->
<resolve
launcher:container="-101"
launcher:screen="0"
@@ -45,8 +45,7 @@
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
@@ -54,9 +53,7 @@
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/" />
+ <favorite launcher:uri="#Intent;action=org.omnirom.control.intents.LAUNCH;category=android.intent.category.DEFAULT;end" />
</resolve>
<resolve
@@ -68,31 +65,4 @@
<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..63a64fc
--- /dev/null
+++ b/res/xml/default_workspace_6x6.xml
@@ -0,0 +1,68 @@
+<?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">
+
+ <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+ <!-- Dialer, Messaging, nothing, Settings, OmniControl, 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="3"
+ launcher:x="3"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=android.settings.SETTINGS;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="4"
+ launcher:x="4"
+ launcher:y="0" >
+ <favorite launcher:uri="#Intent;action=org.omnirom.control.intents.LAUNCH;category=android.intent.category.DEFAULT;end" />
+ </resolve>
+
+ <resolve
+ launcher:container="-101"
+ launcher:screen="5"
+ launcher:x="5"
+ 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>
+
+</favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 1d0dbff..8366aea 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -161,6 +161,50 @@
</grid-option>
<grid-option
+ launcher:name="6_by_6"
+ launcher:numRows="6"
+ launcher:numColumns="6"
+ launcher:numFolderRows="4"
+ launcher:numFolderColumns="4"
+ launcher:numHotseatIcons="6"
+ launcher:dbFile="launcher.db"
+ launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_split"
+ 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="56"
+ launcher:iconTextSize="14.4"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Large Phone Split Display"
+ launcher:minWidthDps="406"
+ launcher:minHeightDps="694"
+ launcher:iconImageSize="56"
+ launcher:iconTextSize="14.4"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Shorter Stubby"
+ launcher:minWidthDps="255"
+ launcher:minHeightDps="400"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="13.0"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+ <grid-option
launcher:name="6_by_5"
launcher:numRows="5"
launcher:numColumns="6"
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 284ab9e..6c161fe 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -50,4 +50,31 @@
launcher:logIdOn="615"
launcher:logIdOff="616" />
+ <SwitchPreference
+ android:defaultValue="@bool/qsb_show_default"
+ android:key="pref_qsb_show"
+ android:persistent="true"
+ android:summary="@string/pref_qsb_show_summary"
+ android:title="@string/pref_qsb_show_title"/>
+
+ <ListPreference
+ android:key="pref_qsb_location"
+ android:title="@string/pref_qsb_location_title"
+ android:persistent="true"
+ android:dependency="pref_qsb_show"
+ android:entries="@array/prefs_qsb_location_entries"
+ android:entryValues="@array/prefs_qsb_location_values"
+ android:defaultValue="@string/pref_qsb_location_workspace_value"/>
+
+ <SwitchPreference
+ android:key="pref_left_tab"
+ android:title="@string/left_tab_label"
+ android:summary="@string/left_tab_description"
+ android:persistent="true" />
+
+ <ListPreference
+ android:key="pref_grid"
+ android:title="@string/pref_grid_title"
+ android:persistent="false"/>
+
</androidx.preference.PreferenceScreen>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index f1274dc..f8b21f0 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -73,6 +73,7 @@
import com.android.launcher3.util.ResourceHelper;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.WindowManagerProxy;
+import com.android.launcher3.Utilities;
import java.io.PrintWriter;
import java.util.Locale;
@@ -235,6 +236,7 @@
public final int hotseatQsbHeight;
public final int hotseatQsbVisualHeight;
private final int hotseatQsbShadowHeight;
+ private final int hotseatQsbMarginTop;
public int hotseatBorderSpace;
private final int mMinHotseatIconSpacePx;
private final int mMinHotseatQsbWidthPx;
@@ -366,6 +368,7 @@
hotseatQsbHeight = 0;
hotseatQsbVisualHeight = 0;
hotseatQsbShadowHeight = 0;
+ hotseatQsbMarginTop = 0;
hotseatBorderSpace = 0;
mMinHotseatIconSpacePx = 0;
mMinHotseatQsbWidthPx = 0;
@@ -610,9 +613,10 @@
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
- hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
+ hotseatQsbHeight = Utilities.showHotseatQsbWidget(context) ? res.getDimensionPixelSize(R.dimen.qsb_widget_height) : 0;
hotseatQsbShadowHeight = res.getDimensionPixelSize(R.dimen.qsb_shadow_height);
hotseatQsbVisualHeight = hotseatQsbHeight - 2 * hotseatQsbShadowHeight;
+ hotseatQsbMarginTop = res.getDimensionPixelSize(R.dimen.hotseat_qsb_margin_top);
// Whether QSB might be inline in appropriate orientation (e.g. landscape).
boolean canQsbInline = (isTwoPanels ? inv.inlineQsb[INDEX_TWO_PANEL_PORTRAIT]
@@ -970,6 +974,13 @@
}
/**
+ * used in Hotseat only for !isQsbInline
+ */
+ public int getHostseatQsbWidth() {
+ return calculateQsbWidth(0);
+ }
+
+ /**
* Calculates the width of the hotseat, changing spaces between the icons and removing icons if
* necessary.
*/
@@ -2053,7 +2064,7 @@
} else if (isTaskbarPresent) { // QSB on top
return hotseatBarSizePx - hotseatQsbHeight + hotseatQsbShadowHeight;
} else {
- return hotseatBarBottomSpacePx - hotseatQsbShadowHeight;
+ return hotseatBarBottomSpacePx - hotseatQsbShadowHeight - hotseatQsbMarginTop;
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index b20d8a5..a83db06 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -33,6 +33,8 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.launcher3.Utilities;
+
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@@ -99,7 +101,12 @@
public Hotseat(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+
+ if (Utilities.showHotseatQsbWidget(context)) {
+ mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+ } else {
+ mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat_empty, this, false);
+ }
addView(mQsb);
mIconsAlphaChannels = new MultiValueAlpha(getShortcutsAndWidgets(),
ALPHA_CHANNEL_CHANNELS_COUNT);
@@ -299,7 +306,8 @@
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
DeviceProfile dp = mActivity.getDeviceProfile();
- mQsb.measure(MeasureSpec.makeMeasureSpec(dp.hotseatQsbWidth, MeasureSpec.EXACTLY),
+ int hotseatQsbWidth = dp.isQsbInline ? dp.hotseatQsbWidth : dp.getHostseatQsbWidth();
+ mQsb.measure(MeasureSpec.makeMeasureSpec(hotseatQsbWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dp.hotseatQsbHeight, MeasureSpec.EXACTLY));
}
diff --git a/src/com/android/launcher3/ModelCallbacks.kt b/src/com/android/launcher3/ModelCallbacks.kt
index 5d32525..008d229 100644
--- a/src/com/android/launcher3/ModelCallbacks.kt
+++ b/src/com/android/launcher3/ModelCallbacks.kt
@@ -40,7 +40,7 @@
var pagesToBindSynchronously = LIntSet()
private var isFirstPagePinnedItemEnabled =
- (BuildConfig.QSB_ON_FIRST_SCREEN && !enableSmartspaceRemovalToggle())
+ (FeatureFlags.QSB_ON_FIRST_SCREEN && !enableSmartspaceRemovalToggle())
var stringCache: StringCache? = null
@@ -332,13 +332,13 @@
)
val firstScreenPosition = 0
if (
- (isFirstPagePinnedItemEnabled && !SHOULD_SHOW_FIRST_PAGE_WIDGET) &&
+ (getQsbOnFirstScreen() && isFirstPagePinnedItemEnabled && !SHOULD_SHOW_FIRST_PAGE_WIDGET) &&
orderedScreenIds.indexOf(FIRST_SCREEN_ID) != firstScreenPosition
) {
orderedScreenIds.removeValue(FIRST_SCREEN_ID)
orderedScreenIds.add(firstScreenPosition, FIRST_SCREEN_ID)
} else if (
- (!isFirstPagePinnedItemEnabled || SHOULD_SHOW_FIRST_PAGE_WIDGET) &&
+ (!getQsbOnFirstScreen() && !isFirstPagePinnedItemEnabled || SHOULD_SHOW_FIRST_PAGE_WIDGET) &&
orderedScreenIds.isEmpty
) {
// If there are no screens, we need to have an empty screen
@@ -395,6 +395,7 @@
}
orderedScreenIds
.filterNot { screenId ->
+ getQsbOnFirstScreen() &&
isFirstPagePinnedItemEnabled &&
!SHOULD_SHOW_FIRST_PAGE_WIDGET &&
screenId == WorkspaceLayoutManager.FIRST_SCREEN_ID
@@ -432,6 +433,8 @@
launcher.appsView.updateWorkUI()
}
+ fun getQsbOnFirstScreen(): Boolean = Utilities.showWorkspaceQsbWidget(launcher)
+
fun getIsFirstPagePinnedItemEnabled(): Boolean = isFirstPagePinnedItemEnabled
override fun getItemInflater() = launcher.itemInflater
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index ebcb5da..aa4ad12 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -22,11 +22,13 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
+import static com.android.launcher3.settings.SettingsActivity.QSB_LOCATION_PREFERENCE_KEY;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Person;
+import android.app.ProgressDialog;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.pm.LauncherActivityInfo;
@@ -87,6 +89,7 @@
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.Executors;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -167,6 +170,9 @@
sIsRunningInTestHarness = true;
}
+ public static final String QSB_SHOW = "pref_qsb_show";
+ public static final long WAIT_BEFORE_RESTART = 250;
+
/** Disables running test in test harness mode */
public static void disableRunningInTestHarnessForTests() {
sIsRunningInTestHarness = false;
@@ -176,6 +182,24 @@
return Log.isLoggable(propertyName, Log.VERBOSE);
}
+ public static boolean showQsbWidget(Context context) {
+ return LauncherPrefs.getPrefs(context).getBoolean(QSB_SHOW,
+ context.getResources().getBoolean(R.bool.qsb_show_default));
+ }
+
+ public static String qsbWidgtLocation(Context context) {
+ return LauncherPrefs.getPrefs(context).getString(QSB_LOCATION_PREFERENCE_KEY,
+ context.getResources().getString(R.string.pref_qsb_location_workspace_value));
+ }
+
+ public static boolean showHotseatQsbWidget(Context context) {
+ return showQsbWidget(context) && qsbWidgtLocation(context).equals(context.getResources().getString(R.string.pref_qsb_location_hotseat_value));
+ }
+
+ public static boolean showWorkspaceQsbWidget(Context context) {
+ return showQsbWidget(context) && qsbWidgtLocation(context).equals(context.getResources().getString(R.string.pref_qsb_location_workspace_value));
+ }
+
/**
* Given a coordinate relative to the descendant, find the coordinate in a parent view's
* coordinates.
@@ -938,4 +962,15 @@
}
return null;
}
+
+ public static void restart(final Context context) {
+ ProgressDialog.show(context, null, context.getString(R.string.state_loading), true, false);
+ Executors.MODEL_EXECUTOR.execute(() -> {
+ try {
+ Thread.sleep(WAIT_BEFORE_RESTART);
+ } catch (Exception ignored) {
+ }
+ android.os.Process.killProcess(android.os.Process.myPid());
+ });
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 69a5a83..4f7ee07 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -606,7 +606,7 @@
* Initializes and binds the first page
*/
public void bindAndInitFirstWorkspaceScreen() {
- if ((!FeatureFlags.QSB_ON_FIRST_SCREEN
+ if ((!Utilities.showWorkspaceQsbWidget(mContext)
|| !mLauncher.getIsFirstPagePinnedItemEnabled())
|| SHOULD_SHOW_FIRST_PAGE_WIDGET) {
mFirstPagePinnedItem = null;
@@ -1047,7 +1047,7 @@
int id = mWorkspaceScreens.keyAt(i);
CellLayout cl = mWorkspaceScreens.valueAt(i);
// FIRST_SCREEN_ID can never be removed.
- if (((!FeatureFlags.QSB_ON_FIRST_SCREEN
+ if (((!Utilities.showWorkspaceQsbWidget(getContext())
|| SHOULD_SHOW_FIRST_PAGE_WIDGET)
|| id > FIRST_SCREEN_ID)
&& cl.getShortcutsAndWidgets().getChildCount() == 0) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 9e38824..a27b2ac 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -50,6 +50,7 @@
* @deprecated Use {@link BuildConfig#QSB_ON_FIRST_SCREEN} directly
*/
@Deprecated
+ // NOTE: replaced by resource qsb_show_default
public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN;
/**
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index f0e4fc4..0aa4cf2 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -69,6 +69,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.WorkspaceLayoutManager;
import com.android.launcher3.apppairs.AppPairIcon;
@@ -522,7 +523,7 @@
}
// Add first page QSB
- if (FeatureFlags.QSB_ON_FIRST_SCREEN && dataModel.isFirstPagePinnedItemEnabled
+ if (Utilities.showWorkspaceQsbWidget(mContext) && dataModel.isFirstPagePinnedItemEnabled
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET) {
CellLayout firstScreen = mWorkspaceScreens.get(FIRST_SCREEN_ID);
View qsb = mHomeElementInflater.inflate(R.layout.qsb_preview, firstScreen, false);
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index b9b1e98..fc1355d 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -162,9 +162,7 @@
screenSet.add(item.screenId);
}
}
- if ((FeatureFlags.QSB_ON_FIRST_SCREEN
- && !SHOULD_SHOW_FIRST_PAGE_WIDGET)
- || screenSet.isEmpty()) {
+ if (screenSet.isEmpty()) {
screenSet.add(Workspace.FIRST_SCREEN_ID);
}
return screenSet.getArray();
diff --git a/src/com/android/launcher3/model/DatabaseHelper.java b/src/com/android/launcher3/model/DatabaseHelper.java
index ed4f492..9e9f918 100644
--- a/src/com/android/launcher3/model/DatabaseHelper.java
+++ b/src/com/android/launcher3/model/DatabaseHelper.java
@@ -257,7 +257,7 @@
Favorites.SCREEN, IntArray.wrap(-777, -778)), null);
}
case 30: {
- if (FeatureFlags.QSB_ON_FIRST_SCREEN
+ if (Utilities.showWorkspaceQsbWidget(mContext)
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET) {
// Clean up first row in screen 0 as it might contain junk data.
Log.d(TAG, "Cleaning up first row");
diff --git a/src/com/android/launcher3/model/GridSizeMigrationDBController.java b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
index bfa00bd..80ac0cb 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationDBController.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationDBController.java
@@ -360,7 +360,7 @@
final GridOccupancy occupied = new GridOccupancy(trgX, trgY);
final Point trg = new Point(trgX, trgY);
final Point next = new Point(0, screenId == 0
- && (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && (Utilities.showWorkspaceQsbWidget(destReader.mContext)
&& (!enableSmartspaceRemovalToggle() || LauncherPrefs.getPrefs(destReader.mContext)
.getBoolean(SMARTSPACE_ON_HOME_SCREEN, true))
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET)
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index c01b1b6..742fc31 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -553,7 +553,7 @@
if (!mOccupied.containsKey(item.screenId)) {
GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);
- if (item.screenId == Workspace.FIRST_SCREEN_ID && (FeatureFlags.QSB_ON_FIRST_SCREEN
+ if (item.screenId == Workspace.FIRST_SCREEN_ID && (Utilities.showWorkspaceQsbWidget(mContext)
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET
&& isFirstPagePinnedItemEnabled)) {
// Mark the first X columns (X is width of the search container) in the first row as
@@ -561,7 +561,7 @@
// container.
int spanX = mIDP.numSearchContainerColumns;
int spanY = 1;
- screen.markCells(0, 0, spanX, spanY, true);
+ screen.markCells(0, 0, spanX, spanY, Utilities.showWorkspaceQsbWidget(mContext));
}
mOccupied.put(item.screenId, screen);
}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index f96e959..c70c2db 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -417,7 +417,7 @@
}
logASplit("loadWorkspace finished");
- mBgDataModel.isFirstPagePinnedItemEnabled = FeatureFlags.QSB_ON_FIRST_SCREEN
+ mBgDataModel.isFirstPagePinnedItemEnabled = Utilities.showQsbWidget(mApp.getContext())
&& (!enableSmartspaceRemovalToggle() || LauncherPrefs.getPrefs(
mApp.getContext()).getBoolean(SMARTSPACE_ON_HOME_SCREEN, true));
}
diff --git a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
index 1a6d178..7e025ac 100644
--- a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
+++ b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
@@ -25,6 +25,7 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
@@ -67,7 +68,7 @@
int screenCount = workspaceScreens.size();
// First check the preferred screen.
IntSet screensToExclude = new IntSet();
- if (FeatureFlags.QSB_ON_FIRST_SCREEN
+ if (Utilities.showWorkspaceQsbWidget(app.getContext())
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET) {
screensToExclude.add(FIRST_SCREEN_ID);
}
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index d6b41b0..ac20d13 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -47,6 +47,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherPrefs;
+import com.android.launcher3.Utilities;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.FragmentWithPreview;
@@ -280,19 +281,14 @@
}
private void rebindFragment() {
- // Exit if the embedded qsb is disabled
- if (!isQsbEnabled()) {
- return;
- }
-
- if (mWrapper != null && getContext() != null) {
+ if (mWrapper != null && getContext() != null && isQsbEnabled()) {
mWrapper.removeAllViews();
mWrapper.addView(createQsb(mWrapper));
}
}
- public boolean isQsbEnabled() {
- return FeatureFlags.QSB_ON_FIRST_SCREEN
+ private boolean isQsbEnabled() {
+ return Utilities.showQsbWidget(getContext())
&& !SHOULD_SHOW_FIRST_PAGE_WIDGET;
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 6008287..6a0527c 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -30,9 +30,13 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
+import android.content.res.XmlResourceParser;
import android.os.Bundle;
+import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.Log;
+import android.util.Xml;
import android.view.MenuItem;
import android.view.View;
@@ -43,6 +47,7 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
+import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback;
@@ -55,17 +60,29 @@
import com.android.launcher3.BuildConfig;
import com.android.launcher3.Flags;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile.GridOption;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R;
import com.android.launcher3.states.RotationHelper;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
+import org.omnirom.omnilib.utils.PackageUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
*/
public class SettingsActivity extends FragmentActivity
implements OnPreferenceStartFragmentCallback, OnPreferenceStartScreenCallback {
+ private static final String TAG = "SettingsActivity";
@VisibleForTesting
static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
@@ -73,6 +90,8 @@
public static final String FIXED_LANDSCAPE_MODE = "pref_fixed_landscape_mode";
private static final String NOTIFICATION_DOTS_PREFERENCE_KEY = "pref_icon_badging";
+ private static final String GRID_SIZE_PREFERENCE_KEY = "pref_grid";
+ public static final String QSB_LOCATION_PREFERENCE_KEY = "pref_qsb_location";
public static final String EXTRA_FRAGMENT_ARGS = ":settings:fragment_args";
@@ -84,6 +103,9 @@
private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
public static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
+ private static final String SEARCH_PACKAGE = "com.google.android.googlequicksearchbox";
+ private static final String SHOW_LEFT_TAB_PREFERENCE_KEY = "pref_left_tab";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -227,6 +249,77 @@
if (getActivity() != null && !TextUtils.isEmpty(getPreferenceScreen().getTitle())) {
getActivity().setTitle(getPreferenceScreen().getTitle());
}
+
+ Preference showQsbWidget = findPreference(Utilities.QSB_SHOW);
+ showQsbWidget.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ new Handler().postDelayed(() -> Utilities.restart(getActivity()), Utilities.WAIT_BEFORE_RESTART);
+ return true;
+ }
+ });
+
+ Preference leftTabPage = findPreference(SHOW_LEFT_TAB_PREFERENCE_KEY);
+ if (!isSearchInstalled()) {
+ getPreferenceScreen().removePreference(leftTabPage);
+ }
+ leftTabPage.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ new Handler().postDelayed(() -> Utilities.restart(getActivity()), Utilities.WAIT_BEFORE_RESTART);
+ return true;
+ }
+ });
+
+ final ListPreference grid = (ListPreference) findPreference(GRID_SIZE_PREFERENCE_KEY);
+ InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
+ ArrayList<String> entries = new ArrayList<>();
+ ArrayList<String> values = new ArrayList<>();
+ for (GridOption gridOption : parseAllGridOptions(idp.deviceType)) {
+ values.add(gridOption.name);
+ entries.add(gridOption.numColumns + " x " + gridOption.numRows);
+ }
+
+ grid.setEntries(entries.toArray(new String[entries.size()]));
+ grid.setEntryValues(values.toArray(new String[values.size()]));
+
+ String currentGrid = idp.getCurrentGridName(getContext());
+ int valueIndex = grid.findIndexOfValue(currentGrid);
+ grid.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
+ grid.setSummary(grid.getEntry());
+
+ grid.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ // Verify that this is a valid grid option
+ String gridName = (String) newValue;
+ GridOption match = null;
+ for (GridOption option : parseAllGridOptions(idp.deviceType)) {
+ if (option.name.equals(gridName)) {
+ match = option;
+ break;
+ }
+ }
+ if (match == null) {
+ return false;
+ }
+
+ InvariantDeviceProfile.INSTANCE.get(getContext())
+ .setCurrentGrid(getContext(), gridName);
+
+ int valueIndex = grid.findIndexOfValue(gridName);
+ grid.setValueIndex(valueIndex >= 0 ? valueIndex : 0);
+ grid.setSummary(grid.getEntries()[valueIndex]);
+ return true;
+ }
+ });
+
+ final ListPreference qsbLocation = (ListPreference) findPreference(QSB_LOCATION_PREFERENCE_KEY);
+ valueIndex = qsbLocation.findIndexOfValue(qsbLocation.getValue());
+ qsbLocation.setSummary(qsbLocation.getEntries()[valueIndex]);
+ qsbLocation.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ new Handler().postDelayed(() -> Utilities.restart(getActivity()), Utilities.WAIT_BEFORE_RESTART);
+ return true;
+ }
+ });
}
private boolean isKeyInPreferenceGroup(String targetKey, PreferenceGroup parent) {
@@ -405,5 +498,31 @@
list, position, screen.findPreference(mHighLightKey))
: null;
}
+
+ private List<GridOption> parseAllGridOptions(int deviceType) {
+ List<GridOption> result = new ArrayList<>();
+ try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) {
+ final int depth = parser.getDepth();
+ int type;
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+ if ((type == XmlPullParser.START_TAG)
+ && GridOption.TAG_NAME.equals(parser.getName())) {
+ GridOption gridOption = new GridOption(getContext(), Xml.asAttributeSet(parser));
+ if (gridOption.isEnabled(deviceType)) {
+ result.add(gridOption);
+ }
+ }
+ }
+ } catch (IOException | XmlPullParserException e) {
+ Log.e(TAG, "Error parsing device profile", e);
+ return Collections.emptyList();
+ }
+ return result;
+ }
+
+ private boolean isSearchInstalled() {
+ return PackageUtils.isAvailableApp(SEARCH_PACKAGE, getActivity());
+ }
}
}
diff --git a/src_overlay/google/com/android/launcher3/overlay/OverlayCallbackImpl.java b/src_overlay/google/com/android/launcher3/overlay/OverlayCallbackImpl.java
new file mode 100644
index 0000000..d068cf5
--- /dev/null
+++ b/src_overlay/google/com/android/launcher3/overlay/OverlayCallbackImpl.java
@@ -0,0 +1,171 @@
+/*
+ * 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.overlay;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherPrefs;
+import com.android.systemui.plugins.shared.LauncherOverlayManager;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks;
+
+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,
+ SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private static final String SHOW_LEFT_TAB_PREFERENCE_KEY = "pref_left_tab";
+
+ private final Launcher mLauncher;
+ private final LauncherClient mClient;
+
+ private LauncherOverlayCallbacks mLauncherOverlayCallbacks;
+ private boolean mWasOverlayAttached = false;
+
+ public OverlayCallbackImpl(Launcher launcher) {
+ SharedPreferences prefs = LauncherPrefs.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 void onActivityStarted() {
+ mClient.onStart();
+ }
+
+ @Override
+ public void onActivityResumed() {
+ mClient.onResume();
+ }
+
+ @Override
+ public void onActivityPaused() {
+ mClient.onPause();
+ }
+
+ @Override
+ public void onActivityStopped() {
+ mClient.onStop();
+ }
+
+ @Override
+ public void onActivityDestroyed() {
+ mClient.onDestroy();
+ mLauncher.getSharedPrefs().unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ if (SHOW_LEFT_TAB_PREFERENCE_KEY.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.onOverlayScrollChanged(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(SHOW_LEFT_TAB_PREFERENCE_KEY, false),
+ true, /* enableHotword */
+ true /* enablePrewarming */
+ );
+ }
+}
diff --git a/src_overlay/mock/com/android/launcher3/overlay/OverlayCallbackImpl.java b/src_overlay/mock/com/android/launcher3/overlay/OverlayCallbackImpl.java
new file mode 100644
index 0000000..449cef8
--- /dev/null
+++ b/src_overlay/mock/com/android/launcher3/overlay/OverlayCallbackImpl.java
@@ -0,0 +1,121 @@
+/*
+ * 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.overlay;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.android.launcher3.Launcher;
+import com.android.systemui.plugins.shared.LauncherOverlayManager;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
+import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks;
+
+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,
+ SharedPreferences.OnSharedPreferenceChangeListener {
+
+ public OverlayCallbackImpl(Launcher launcher) {
+ }
+
+ @Override
+ public void onDeviceProvideChanged() {
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ }
+
+ @Override
+ public void dump(String prefix, PrintWriter w) {
+ }
+
+ @Override
+ public void openOverlay() {
+ }
+
+ @Override
+ public void hideOverlay(boolean animate) {
+ }
+
+ @Override
+ public void hideOverlay(int duration) {
+ }
+
+ @Override
+ public void onActivityStarted() {
+ }
+
+ @Override
+ public void onActivityResumed() {
+ }
+
+ @Override
+ public void onActivityPaused() {
+ }
+
+ @Override
+ public void onActivityStopped() {
+ }
+
+ @Override
+ public void onActivityDestroyed() {
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ }
+
+ @Override
+ public void onServiceStateChanged(boolean overlayAttached, boolean hotwordActive) {
+ }
+
+ @Override
+ public void onOverlayScrollChanged(float progress) {
+ }
+
+ @Override
+ public void onScrollInteractionBegin() {
+ }
+
+ @Override
+ public void onScrollInteractionEnd() {
+ }
+
+ @Override
+ public void onScrollChange(float progress, boolean rtl) {
+ }
+
+ @Override
+ public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks) {
+ }
+}
diff --git a/src_overlay/mock/com/google/android/libraries/gsa/launcherclient/LauncherClientCallbacks.java b/src_overlay/mock/com/google/android/libraries/gsa/launcherclient/LauncherClientCallbacks.java
new file mode 100644
index 0000000..3f9e6d1
--- /dev/null
+++ b/src_overlay/mock/com/google/android/libraries/gsa/launcherclient/LauncherClientCallbacks.java
@@ -0,0 +1,5 @@
+package com.google.android.libraries.gsa.launcherclient;
+public interface LauncherClientCallbacks {
+ void onOverlayScrollChanged(float progress);
+ void onServiceStateChanged(boolean overlayAttached, boolean hotwordActive);
+}
\ No newline at end of file