Merge tag 'android-14.0.0_r50' into leaf-3.2
Android 14.0.0 Release 50 (AP2A.240605.024)
* tag 'android-14.0.0_r50': (577 commits)
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
Support toggling Taskbar All Apps with 3P Launcher.
Close the KQS view when touching the gesture nav region
Do not report finish in mergeAnimation...
Disable two line text legacy flag.
Update KQS task view layouts to new specs
Removes recovery
Cancel animations after reading MotionPauseDetector#isPaused()
Reset stashed in Taskbar All Apps for gestures instead of IME insets.
Fix bug where folder with 1 icon can exist
Set next page immediately on subsequent arrow/tab presses when navigating overivew.
Allow Task menu to draw down to screen bottom
Update Launcher state anim duration for pinned & transient taskbar
Fix overview live tile flickers when clicking on overview action buttons
Disable slow recents animation handling
Fix split selection for 3P launcher with animations off
Enable Omnient master flags in client code.
When mLastComputedTaskSize is empty we will recalculate and set it before determining scale and pivot
Adds new AssistStateManager settings
...
Change-Id: I99f5f74f7da353c6f8952a28a49532bd5c3f1bf1
diff --git a/.gitignore b/.gitignore
index 694b40c..85bd93a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@
build/
gradlew*
.DS_Store
+.settings
diff --git a/Android.bp b/Android.bp
index 78db013..99c0e32 100644
--- a/Android.bp
+++ b/Android.bp
@@ -398,6 +398,7 @@
enabled: false,
},
+ certificate: "platform",
platform_apis: true,
min_sdk_version: "current",
target_sdk_version: "current",
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index a31ee80..6dfbf1c 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -41,11 +41,15 @@
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.VIBRATE"/>
+ <uses-permission android:name="android.permission.SUSPEND_APPS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<!-- for rotating surface by arbitrary degree -->
<uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
<uses-permission android:name="android.permission.WAKEUP_SURFACE_FLINGER" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+
<!--
Permissions required for read/write access to the workspace data. These permission name
should not conflict with that defined in other apps, as such an app should embed its package
@@ -138,7 +142,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 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/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index c6e2d8c..1d7405e 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/drawable/ic_lens.xml b/quickstep/res/drawable/ic_lens.xml
new file mode 100644
index 0000000..e372e83
--- /dev/null
+++ b/quickstep/res/drawable/ic_lens.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector android:height="24.0dip" android:width="24.0dip" android:viewportWidth="24.0" android:viewportHeight="24.0"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#ff000000" android:pathData="M8.4445,5.7778C6.9689,5.7778 5.7778,6.9689 5.7778,8.4445L5.7778,10.2222L4,10.2222L4,8.4445C4,5.9911 5.9911,4 8.4445,4L10.2222,4v1.7778zM17.3333,17.3333m-1.7778,0a1.7778,1.7778 0,1 1,3.5555 0,1.7778 1.7778,0 1,1 -3.5555,0M12,12m-3.1111,0a3.1111,3.1111 0,1 1,6.2222 0,3.1111 3.1111,0 1,1 -6.2222,0M8.4444,18.2222c-1.4755,0 -2.6667,-1.1911 -2.6667,-2.6667L5.7777,13.7778L4,13.7778v1.7778C4,18.0089 5.9911,20 8.4445,20L10.2222,20L10.2222,18.2222ZM15.5555,5.7778c1.4755,0 2.6667,1.1911 2.6667,2.6667L18.2222,10.2222L20,10.2222L20,8.4445C20,5.9911 18.0089,4 15.5555,4h-1.7778v1.7778z" />
+</vector>
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 0fda0bf..f13e139 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -60,6 +60,23 @@
android:layout_height="1dp"
android:layout_weight="1" />
+ <Button
+ android:drawableStart="@drawable/ic_lens"
+ style="@style/OverviewActionButton"
+ android:id="@+id/action_lens"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/action_lens"
+ android:theme="@style/ThemeControlHighlightWorkspaceColor"
+ android:visibility="gone" />
+
+ <Space
+ android:id="@+id/lens_space"
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:layout_weight="1"
+ android:visibility="gone" />
+
<Space
android:id="@+id/oav_three_button_space"
android:layout_width="0dp"
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index ecbc7e7..45631e8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -109,6 +109,9 @@
private static final Uri NAV_BAR_KIDS_MODE = Settings.Secure.getUriFor(
Settings.Secure.NAV_BAR_KIDS_MODE);
+ private static final Uri ENABLE_TASKBAR_URI = Settings.System.getUriFor(
+ Settings.System.ENABLE_TASKBAR);
+
private final Context mContext;
private final @Nullable Context mNavigationBarPanelContext;
private final DeviceStateManager mDeviceStateManager;
@@ -152,6 +155,7 @@
}
}
private final SettingsCache.OnChangeListener mOnSettingsChangeListener = c -> recreateTaskbar();
+ private final SettingsCache.OnChangeListener mEnableTaskBarListener;
private boolean mUserUnlocked = false;
@@ -324,6 +328,18 @@
.register(USER_SETUP_COMPLETE_URI, mOnSettingsChangeListener);
SettingsCache.INSTANCE.get(mContext)
.register(NAV_BAR_KIDS_MODE, mOnSettingsChangeListener);
+ mEnableTaskBarListener = c -> {
+ // Create the illusion of this taking effect immediately
+ // Also needed because TaskbarManager inits before SystemUiProxy on start
+ boolean enabled = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.ENABLE_TASKBAR, 0) == 1;
+ SystemUiProxy.INSTANCE.get(mContext).setTaskbarEnabled(enabled);
+
+ // Restart launcher
+ System.exit(0);
+ };
+ SettingsCache.INSTANCE.get(mContext)
+ .register(ENABLE_TASKBAR_URI, mEnableTaskBarListener);
Log.d(TASKBAR_NOT_DESTROYED_TAG, "registering component callbacks from constructor.");
mContext.registerComponentCallbacks(mComponentCallbacks);
mShutdownReceiver.register(mContext, Intent.ACTION_SHUTDOWN);
@@ -482,9 +498,10 @@
+ " [dp != null (i.e. mUserUnlocked)]=" + (dp != null)
+ " FLAG_HIDE_NAVBAR_WINDOW=" + ENABLE_TASKBAR_NAVBAR_UNIFICATION
+ " dp.isTaskbarPresent=" + (dp == null ? "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/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 2c45129..6226e93 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -46,6 +46,7 @@
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.DONT_SUGGEST_APP;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
+import static com.android.launcher3.popup.SystemShortcut.PAUSE_APPS;
import static com.android.launcher3.popup.SystemShortcut.PRIVATE_PROFILE_INSTALL;
import static com.android.launcher3.popup.SystemShortcut.UNINSTALL_APP;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
@@ -436,6 +437,7 @@
List<SystemShortcut.Factory> shortcuts = new ArrayList(Arrays.asList(
APP_INFO, WellbeingModel.SHORTCUT_FACTORY, mHotseatPredictionController));
shortcuts.addAll(getSplitShortcuts());
+ shortcuts.add(PAUSE_APPS);
shortcuts.add(WIDGETS);
shortcuts.add(INSTALL);
if (Flags.enablePrivateSpaceInstallShortcut()) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 7650235..8e5ce22 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -23,6 +23,8 @@
import android.graphics.Rect;
import android.os.SystemProperties;
+import androidx.core.graphics.ColorUtils;
+
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
@@ -155,7 +157,8 @@
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
+ return ColorUtils.setAlphaComponent(
+ Themes.getAttrColor(launcher, R.attr.overviewScrimColor), 100);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/ImageActionsApi.java b/quickstep/src/com/android/quickstep/ImageActionsApi.java
index 2273806..b7acd29 100644
--- a/quickstep/src/com/android/quickstep/ImageActionsApi.java
+++ b/quickstep/src/com/android/quickstep/ImageActionsApi.java
@@ -31,6 +31,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
+import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -108,6 +109,11 @@
ImageActionUtils.startShareActivity(mContext, mBitmapSupplier, crop, null, TAG);
}
+ @UiThread
+ public void startLensActivity() {
+ ImageActionUtils.startLensActivity(mContext, mBitmapSupplier, null, null, TAG);
+ }
+
/**
* @param screenshot to be saved to the media store.
* @param screenshotBounds the location of where the bitmap was laid out on the screen in
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 97c48e6..ea1b430 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -239,7 +239,7 @@
@Override
public void onStateTransitionComplete(LauncherState toState) {
// Are we going from Recents to Workspace?
- if (toState == LauncherState.NORMAL) {
+ if (toState == LauncherState.NORMAL || toState == LauncherState.ALL_APPS) {
exitRunnable.run();
notifyRecentsOfOrientation(deviceState);
stateManager.removeStateListener(this);
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 72f67fc..24db2ed 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -499,6 +499,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/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index e6febff..0647276 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -32,6 +32,7 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.SparseArray;
+import android.view.accessibility.AccessibilityManager;
import androidx.annotation.WorkerThread;
@@ -46,7 +47,6 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.TaskKeyLruCache;
import com.android.quickstep.util.TaskVisualsChangeListener;
@@ -63,6 +63,7 @@
public class TaskIconCache implements DisplayInfoChangeListener {
private final Executor mBgExecutor;
+ private final AccessibilityManager mAccessibilityManager;
private final Context mContext;
private final TaskKeyLruCache<TaskCacheEntry> mIconCache;
@@ -79,6 +80,7 @@
public TaskIconCache(Context context, Executor bgExecutor, IconProvider iconProvider) {
mContext = context;
mBgExecutor = bgExecutor;
+ mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
mIconProvider = iconProvider;
Resources res = context.getResources();
@@ -232,11 +234,14 @@
if ((index = mDefaultIcons.indexOfKey(userId)) >= 0) {
return mDefaultIcons.valueAt(index).newIcon(mContext);
} else {
- BitmapInfo info = mDefaultIconBase.withFlags(
- UserCache.INSTANCE.get(mContext).getUserInfo(UserHandle.of(userId))
- .applyBitmapInfoFlags(FlagOp.NO_OP));
- mDefaultIcons.put(userId, info);
- return info.newIcon(mContext);
+ try (BaseIconFactory li = getIconFactory()) {
+ BitmapInfo info = mDefaultIconBase.withFlags(
+ li.getBitmapFlagOp(new IconOptions()
+ .setUser(UserCache.INSTANCE.get(mContext)
+ .getUserInfo(UserHandle.of(userId)))));
+ mDefaultIcons.put(userId, info);
+ return info.newIcon(mContext);
+ }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 312cdc9..67b691d 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -329,6 +329,14 @@
public void onSplit() {
endLiveTileMode(TaskOverlay.this::enterSplitSelect);
}
+
+ public void onLens() {
+ if (mIsAllowedByPolicy) {
+ endLiveTileMode(() -> mImageApi.startLensActivity());
+ } else {
+ showBlockedByPolicyMessage();
+ }
+ }
}
}
@@ -342,5 +350,7 @@
/** User wants to start split screen with current app. */
void onSplit();
+
+ void onLens();
}
}
diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
index 99f564c..76339c6 100644
--- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -130,7 +130,8 @@
// The API's full zoom-out is three times larger than the zoom-out we apply to the
// icons. To keep the two consistent throughout the animation while keeping Launcher's
// concept of full depth unchanged, we divide the depth by 3 here.
- mWallpaperManager.setWallpaperZoomOut(windowToken, depth / 3);
+ mWallpaperManager.setWallpaperZoomOut(windowToken,
+ Utilities.canZoomWallpaper(mLauncher) ? depth / 3 : 1);
}
if (!BlurUtils.supportsBlursOnWindows()) {
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index 3a1c99b..b39c93e 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -45,12 +45,14 @@
import android.util.Log;
import android.view.View;
+import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import androidx.core.content.FileProvider;
import com.android.internal.app.ChooserActivity;
import com.android.internal.util.ScreenshotRequest;
import com.android.launcher3.BuildConfig;
+import com.android.launcher3.Utilities;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
@@ -159,6 +161,19 @@
});
}
+ @UiThread
+ public static void startLensActivity(Context context, Supplier<Bitmap> bitmapSupplier,
+ Rect crop, Intent intent, String tag) {
+ if (bitmapSupplier.get() == null) {
+ Log.e(tag, "No snapshot available, not starting share.");
+ return;
+ }
+
+ UI_HELPER_EXECUTOR.execute(() -> persistBitmapAndStartActivity(context,
+ bitmapSupplier.get(), crop, intent, ImageActionUtils::getLensIntentForImageUri,
+ tag));
+ }
+
/**
* Starts activity based on given intent created from image uri.
*/
@@ -299,6 +314,24 @@
return new Intent[]{Intent.createChooser(intent, null).addFlags(FLAG_ACTIVITY_NEW_TASK)};
}
+ @WorkerThread
+ private static Intent[] getLensIntentForImageUri(Uri uri, Intent intent) {
+ if (intent == null) {
+ intent = new Intent();
+ }
+ ClipData clipdata = new ClipData(new ClipDescription("content",
+ new String[]{"image/png"}),
+ new ClipData.Item(uri));
+ intent.setAction(Intent.ACTION_SEND)
+ .setComponent(new ComponentName(Utilities.GSA_PACKAGE, Utilities.LENS_SHARE_ACTIVITY))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(FLAG_GRANT_READ_URI_PERMISSION)
+ .setType("image/png")
+ .putExtra(Intent.EXTRA_STREAM, uri)
+ .setClipData(clipdata);
+ return new Intent[]{Intent.createChooser(intent, null).addFlags(FLAG_ACTIVITY_NEW_TASK)};
+ }
+
private static void clearOldCacheFiles(Context context) {
THREAD_POOL_EXECUTOR.execute(() -> {
File parent = new File(context.getCacheDir(), SUB_FOLDER);
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 8281ad7..dc95226 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -32,6 +32,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
import com.android.launcher3.Insettable;
+import com.android.launcher3.Utilities;
import com.android.launcher3.R;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
@@ -141,6 +142,13 @@
findViewById(R.id.action_screenshot).setOnClickListener(this);
mSplitButton = findViewById(R.id.action_split);
mSplitButton.setOnClickListener(this);
+
+ if (Utilities.isGSAEnabled(getContext())) {
+ View lens = findViewById(R.id.action_lens);
+ findViewById(R.id.action_lens).setOnClickListener(this);
+ lens.setVisibility(VISIBLE);
+ findViewById(R.id.lens_space).setVisibility(VISIBLE);
+ }
}
/**
@@ -162,6 +170,8 @@
mCallbacks.onScreenshot();
} else if (id == R.id.action_split) {
mCallbacks.onSplit();
+ } else if (id == R.id.action_lens) {
+ mCallbacks.onLens();
}
}
diff --git a/res/drawable/all_apps_search_hint.xml b/res/drawable/all_apps_search_hint.xml
deleted file mode 100644
index b2ff7a4..0000000
--- a/res/drawable/all_apps_search_hint.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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.
--->
-<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
diff --git a/res/drawable/bg_all_apps_searchbox.xml b/res/drawable/bg_all_apps_searchbox.xml
index 3c321e4..b95e468 100644
--- a/res/drawable/bg_all_apps_searchbox.xml
+++ b/res/drawable/bg_all_apps_searchbox.xml
@@ -14,7 +14,6 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
- <solid android:color="?attr/popupColorPrimary" />
+ <solid android:color="?attr/allappsHeaderProtectionColor" />
<corners android:radius="@dimen/rounded_button_radius" />
- <stroke android:color="?attr/allappsHeaderProtectionColor" android:width=".5dp" />
</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_allapps_search.xml b/res/drawable/ic_allapps_search.xml
index 0c3ab78..9ab2872 100644
--- a/res/drawable/ic_allapps_search.xml
+++ b/res/drawable/ic_allapps_search.xml
@@ -1,25 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- Copyright (C) 2016 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ 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
+ 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.
--->
+ 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="24dp"
- android:height="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0"
- android:autoMirrored="true">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/textColorSecondary"
+ android:autoMirrored="true">
<path
android:fillColor="?attr/widgetPickerSearchTextColor"
- android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
+ android:pathData="M20.49,19l-5.73,-5.73C15.53,12.2 16,10.91 16,9.5C16,5.91 13.09,3 9.5,3S3,5.91 3,9.5C3,13.09 5.91,16 9.5,16c1.41,0 2.7,-0.47 3.77,-1.24L19,20.49L20.49,19zM5,9.5C5,7.01 7.01,5 9.5,5S14,7.01 14,9.5S11.99,14 9.5,14S5,11.99 5,9.5z"/>
</vector>
diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml
index e04b207..fb9b047 100644
--- a/res/layout/all_apps_personal_work_tabs.xml
+++ b/res/layout/all_apps_personal_work_tabs.xml
@@ -36,6 +36,7 @@
android:layout_weight="1"
android:background="@drawable/all_apps_tabs_background"
android:text="@string/all_apps_personal_tab"
+ android:textAllCaps="false"
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp"
style="?android:attr/borderlessButtonStyle" />
@@ -48,6 +49,7 @@
android:layout_weight="1"
android:background="@drawable/all_apps_tabs_background"
android:text="@string/all_apps_work_tab"
+ android:textAllCaps="false"
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp"
style="?android:attr/borderlessButtonStyle" />
diff --git a/res/layout/search_container_all_apps.xml b/res/layout/search_container_all_apps.xml
index db218c3..47acde0 100644
--- a/res/layout/search_container_all_apps.xml
+++ b/res/layout/search_container_all_apps.xml
@@ -17,21 +17,25 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/search_container_all_apps"
android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_search_bar_field_height"
+ android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_gravity="top|center_horizontal"
android:background="@drawable/bg_all_apps_searchbox"
android:focusableInTouchMode="true"
- android:gravity="center"
+ android:gravity="center_vertical"
android:hint="@string/all_apps_search_bar_hint"
android:imeOptions="actionSearch|flagNoExtractUi"
android:importantForAutofill="no"
android:inputType="text|textNoSuggestions|textCapWords"
android:maxLines="1"
- android:padding="8dp"
+ android:paddingVertical="12dp"
+ android:paddingStart="12dp"
+ android:paddingEnd="12dp"
+ android:drawablePadding="8dp"
+ android:drawableStart="@drawable/ic_allapps_search"
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:textColorHint="?android:attr/textColorSecondary"
+ android:textSize="20sp" />
\ No newline at end of file
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index e2f610e..7756b4d 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_text_color_light">@android:color/system_neutral1_900</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>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a912e2d..90a08c8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -103,7 +103,12 @@
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
<!-- all_apps_search_bar_field_height / 2 -->
<dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
- <dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
+ <!-- affects padding above apps lists when tabs and floating header rows are not visible -->
+ <!-- (always affects padding above search results) -->
+ <dimen name="all_apps_search_bar_bottom_padding">24dp</dimen>
+ <!-- margin adjustment for layout relative to bottom of search container -->
+ <!-- if the search container is obscuring things, try adjusting this -->
+ <dimen name="all_apps_search_bar_bottom_adjustment">-6dp</dimen>
<dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
<dimen name="all_apps_search_top_row_extra_height">4dp</dimen>
<dimen name="all_apps_header_pill_height">48dp</dimen>
@@ -114,7 +119,10 @@
<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>
- <dimen name="all_apps_header_bottom_padding">14dp</dimen>
+ <!-- influences header protection drawn height below personal/work tabs -->
+ <!-- if app icons are appearing above the protection rectangle, or if they are shifted below
+ it and cropped at the top, try adjusting this -->
+ <dimen name="all_apps_header_bottom_padding">10dp</dimen>
<dimen name="all_apps_header_top_adjustment">6dp</dimen>
<dimen name="all_apps_header_bottom_adjustment">4dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
diff --git a/res/values/leaf_strings.xml b/res/values/leaf_strings.xml
new file mode 100644
index 0000000..76cfedd
--- /dev/null
+++ b/res/values/leaf_strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2022 The LeafOS 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>
+ <!-- Recents -->
+ <string name="action_lens">Lens</string>
+
+ <!-- Gestures -->
+ <string name="pref_dt_gesture_title">Double tap gesture</string>
+ <string name="pref_dt_gesture_summary">Double tap on empty space for power-off</string>
+
+ <!-- Pause apps -->
+ <string name="pause">Pause</string>
+ <string name="pause_apps_dialog_title">Pause %1$s?</string>
+ <string name="pause_apps_dialog_message">Notifications for %1$s will be paused</string>
+ <string name="paused_apps_dialog_title">App paused</string>
+ <string name="paused_apps_dialog_message">%1$s was directly paused from the launcher</string>
+ <string name="paused_apps_drop_target_label">Pause app</string>
+
+ <!-- Wallpaper zooming -->
+ <string name="allow_wallpaper_zooming">Wallpaper zooming</string>
+ <string name="allow_wallpaper_zooming_summary">Zoom in or out the wallpaper when using drawer or recent apps</string>
+</resources>
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 c9a44a1..d63cfb4 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -18,6 +18,38 @@
<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:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ <display-option
+ launcher:name="Shorter Stubby"
+ launcher:minWidthDps="200"
+ launcher:minHeightDps="300"
+ launcher:iconImageSize="48"
+ launcher:iconTextSize="12.0"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+ <grid-option
launcher:name="3_by_3"
launcher:numRows="3"
launcher:numColumns="3"
@@ -33,7 +65,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="300"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -43,7 +75,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="400"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -68,7 +100,7 @@
launcher:minWidthDps="275"
launcher:minHeightDps="420"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -78,7 +110,7 @@
launcher:minWidthDps="255"
launcher:minHeightDps="450"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -88,7 +120,7 @@
launcher:minWidthDps="296"
launcher:minHeightDps="491.33"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -98,7 +130,7 @@
launcher:minWidthDps="359"
launcher:minHeightDps="567"
launcher:iconImageSize="54"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -108,7 +140,7 @@
launcher:minWidthDps="335"
launcher:minHeightDps="567"
launcher:iconImageSize="54"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -133,7 +165,7 @@
launcher:minWidthDps="406"
launcher:minHeightDps="694"
launcher:iconImageSize="56"
- launcher:iconTextSize="14.4"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -143,7 +175,7 @@
launcher:minWidthDps="406"
launcher:minHeightDps="694"
launcher:iconImageSize="56"
- launcher:iconTextSize="14.4"
+ launcher:iconTextSize="12.0"
launcher:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -153,7 +185,53 @@
launcher:minWidthDps="255"
launcher:minHeightDps="400"
launcher:iconImageSize="48"
- launcher:iconTextSize="13.0"
+ launcher:iconTextSize="12.0"
+ launcher:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ 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:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ 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:allAppsBorderSpace="16"
launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
@@ -208,4 +286,27 @@
</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:allAppsBorderSpace="16"
+ launcher:allAppsCellHeight="104"
+ launcher:canBeDefault="true" />
+
+ </grid-option>
+
+</profiles>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 284ab9e..c9f585b 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -50,4 +50,17 @@
launcher:logIdOn="615"
launcher:logIdOff="616" />
+ <SwitchPreference
+ android:key="pref_dt_gesture"
+ android:title="@string/pref_dt_gesture_title"
+ android:summary="@string/pref_dt_gesture_summary"
+ android:defaultValue="true"
+ android:persistent="true"/>
+
+ <SwitchPreference
+ android:key="pref_allow_wallpaper_zooming"
+ android:title="@string/allow_wallpaper_zooming"
+ android:summary="@string/allow_wallpaper_zooming_summary"
+ android:defaultValue="true" />
+
</androidx.preference.PreferenceScreen>
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 4a277f0..f0bc16c 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -15,7 +15,6 @@
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -236,23 +235,6 @@
mMaxHSpan = info.maxSpanX;
mMaxVSpan = info.maxSpanY;
- // Only show resize handles for the directions in which resizing is possible.
- InvariantDeviceProfile idp = LauncherAppState.getIDP(cellLayout.getContext());
- mVerticalResizeActive = (info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0
- && mMinVSpan < idp.numRows && mMaxVSpan > 1
- && mMinVSpan < mMaxVSpan;
- if (!mVerticalResizeActive) {
- mDragHandles[INDEX_TOP].setVisibility(GONE);
- mDragHandles[INDEX_BOTTOM].setVisibility(GONE);
- }
- mHorizontalResizeActive = (info.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0
- && mMinHSpan < idp.numColumns && mMaxHSpan > 1
- && mMinHSpan < mMaxHSpan;
- if (!mHorizontalResizeActive) {
- mDragHandles[INDEX_LEFT].setVisibility(GONE);
- mDragHandles[INDEX_RIGHT].setVisibility(GONE);
- }
-
mReconfigureButton = (ImageButton) findViewById(R.id.widget_reconfigure_button);
if (info.isReconfigurable()) {
mReconfigureButton.setVisibility(VISIBLE);
@@ -315,12 +297,10 @@
}
public boolean beginResizeIfPointInRegion(int x, int y) {
- mLeftBorderActive = (x < mTouchTargetWidth) && mHorizontalResizeActive;
- mRightBorderActive = (x > getWidth() - mTouchTargetWidth) && mHorizontalResizeActive;
- mTopBorderActive = (y < mTouchTargetWidth + mTopTouchRegionAdjustment)
- && mVerticalResizeActive;
- mBottomBorderActive = (y > getHeight() - mTouchTargetWidth + mBottomTouchRegionAdjustment)
- && mVerticalResizeActive;
+ mLeftBorderActive = x < mTouchTargetWidth;
+ mRightBorderActive = x > getWidth() - mTouchTargetWidth;
+ mTopBorderActive = y < mTouchTargetWidth + mTopTouchRegionAdjustment;
+ mBottomBorderActive = y > getHeight() - mTouchTargetWidth + mBottomTouchRegionAdjustment;
boolean anyBordersActive = mLeftBorderActive || mRightBorderActive
|| mTopBorderActive || mBottomBorderActive;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index f96d59e..ae5f9b6 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -40,6 +40,7 @@
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.Surface;
@@ -348,7 +349,9 @@
isTablet = info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && isMultiDisplay;
- isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
+ boolean isTaskBarEnabled = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.ENABLE_TASKBAR, isTablet ? 1 : 0) == 1;
+ isTaskbarPresent = isTaskBarEnabled && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
// Some more constants.
context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c1ebbe5..fcb6d99 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -93,6 +93,7 @@
import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
+import static com.android.launcher3.popup.SystemShortcut.PAUSE_APPS;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
@@ -3023,7 +3024,7 @@
}
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
- return Stream.of(APP_INFO, WIDGETS, INSTALL);
+ return Stream.of(APP_INFO, PAUSE_APPS, WIDGETS, INSTALL);
}
/**
@@ -3077,4 +3078,4 @@
}
// End of Getters and Setters
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index d730cea..1355230 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/Utilities.java b/src/com/android/launcher3/Utilities.java
index d44438f..72c10bb 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
@@ -29,6 +30,8 @@
import android.app.Person;
import android.app.WallpaperManager;
import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
@@ -77,6 +80,7 @@
import androidx.annotation.WorkerThread;
import androidx.core.graphics.ColorUtils;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.icons.BitmapInfo;
@@ -130,11 +134,15 @@
@ChecksSdkIntAtLeast(api = VERSION_CODES.UPSIDE_DOWN_CAKE, codename = "U")
public static final boolean ATLEAST_U = Build.VERSION.SDK_INT >= VERSION_CODES.UPSIDE_DOWN_CAKE;
+ private static final long WAIT_BEFORE_RESTART = 250;
+
/**
* Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}.
*/
public static final int EDGE_NAV_BAR = 1 << 8;
+ public static final String KEY_DT_GESTURE = "pref_dt_gesture";
+
/**
* Indicates if the device has a debug build. Should only be used to store additional info or
* add extra logging and not for changing the app behavior.
@@ -151,6 +159,10 @@
@IntDef({TRANSLATE_UP, TRANSLATE_DOWN, TRANSLATE_LEFT, TRANSLATE_RIGHT})
public @interface AdjustmentDirection{}
+ public static final String GSA_PACKAGE = "com.google.android.googlequicksearchbox";
+ public static final String LENS_SHARE_ACTIVITY = "com.google.android.apps.search.lens.LensShareEntryPointActivity";
+ public static final String KEY_ALLOW_WALLPAPER_ZOOMING = "pref_allow_wallpaper_zooming";
+
/**
* Returns true if theme is dark.
*/
@@ -667,11 +679,13 @@
}
if (badge == null) {
- badge = BitmapInfo.LOW_RES_INFO.withFlags(
- UserCache.INSTANCE.get(context)
- .getUserInfo(info.user)
- .applyBitmapInfoFlags(FlagOp.NO_OP))
- .getBadgeDrawable(context, useTheme);
+ try (LauncherIcons li = LauncherIcons.obtain(context)) {
+ badge = BitmapInfo.LOW_RES_INFO.withFlags(
+ UserCache.INSTANCE.get(context)
+ .getUserInfo(info.user)
+ .applyBitmapInfoFlags(FlagOp.NO_OP))
+ .getBadgeDrawable(context, useTheme);
+ }
if (badge == null) {
badge = new ColorDrawable(Color.TRANSPARENT);
}
@@ -836,4 +850,32 @@
return Flags.enableSupportForArchiving()
|| getSystemProperty("pm.archiving.enabled", "false").equals("true");
}
+
+ public static void restart(final Context context) {
+ MODEL_EXECUTOR.execute(() -> {
+ try {
+ Thread.sleep(WAIT_BEFORE_RESTART);
+ } catch (Exception ignored) {
+ }
+ android.os.Process.killProcess(android.os.Process.myPid());
+ });
+ }
+
+ public static boolean isGSAEnabled(Context context) {
+ try {
+ return context.getPackageManager().getApplicationInfo(GSA_PACKAGE, 0).enabled;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ public static boolean isDoubleTapGestureEnabled(Context context) {
+ SharedPreferences prefs = LauncherPrefs.getPrefs(context.getApplicationContext());
+ return prefs.getBoolean(KEY_DT_GESTURE, true);
+ }
+
+ public static boolean canZoomWallpaper(Context context) {
+ SharedPreferences prefs = LauncherPrefs.getPrefs(context.getApplicationContext());
+ return prefs.getBoolean(KEY_ALLOW_WALLPAPER_ZOOMING, true);
+ }
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ca34dd1..0924a1f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2226,7 +2226,7 @@
private Runnable getWidgetResizeFrameRunnable(DragOptions options,
LauncherAppWidgetHostView hostView, CellLayout cellLayout) {
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
- if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE) {
+ if (pInfo != null && !options.isAccessibleDrag) {
return () -> {
if (!isPageInTransition()) {
AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 6acfcd0..8d6ae1b 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -128,7 +128,8 @@
public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
private static final int SCROLL_TO_BOTTOM_DURATION = 500;
- private static final long DEFAULT_SEARCH_TRANSITION_DURATION_MS = 300;
+ // As of this writing, search transition does not seem to work properly, so set duration to 0.
+ private static final long DEFAULT_SEARCH_TRANSITION_DURATION_MS = 0;
// Render the header protection at all times to debug clipping issues.
private static final boolean DEBUG_HEADER_PROTECTION = false;
/** Context of an activity or window that is inflating this container. */
@@ -409,6 +410,7 @@
// If exiting search, revert predictive back scale on all apps
mAllAppsTransitionController.animateAllAppsToNoScale();
}
+ setScrollbarVisibility(!goingToSearch);
mSearchTransitionController.animateToState(goingToSearch, durationMs,
/* onEndRunnable = */ () -> {
mIsSearching = goingToSearch;
@@ -752,13 +754,22 @@
tabsHidden);
int padding = mHeader.getMaxTranslation();
- mAH.forEach(adapterHolder -> {
- adapterHolder.mPadding.top = padding;
+ for (int i = 0; i < mAH.size(); i++) {
+ final AdapterHolder adapterHolder = mAH.get(i);
+ // Search and other adapters need to be handled a bit differently; otherwise, when
+ // when leaving search, the All Apps view may be noticeably shifted downward because
+ // its padding was unnecessarily impacted, and never restored, upon entering search.
+ if (i != AdapterHolder.SEARCH && !tabsHidden && mHeader.getFloatingRowsHeight() == 0) {
+ // Only the Search adapter needs padding when there are tabs but no floating rows.
+ adapterHolder.mPadding.top = 0;
+ } else {
+ adapterHolder.mPadding.top = padding;
+ }
adapterHolder.applyPadding();
if (adapterHolder.mRecyclerView != null) {
adapterHolder.mRecyclerView.scrollToTop();
}
- });
+ }
removeCustomRules(mHeader);
if (!isSearchSupported()) {
@@ -782,6 +793,7 @@
mTabsProtectionAlpha = tabsAlpha;
invalidateHeader();
}
+ getSearchView().setBackgroundResource(R.drawable.bg_all_apps_searchbox);
if (mSearchUiManager.getEditText() == null) {
return;
}
@@ -867,13 +879,15 @@
}
RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
- layoutParams.addRule(RelativeLayout.ALIGN_TOP, R.id.search_container_all_apps);
+ layoutParams.addRule(RelativeLayout.BELOW, R.id.search_container_all_apps);
int topMargin = getContext().getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_top_margin);
+ R.dimen.all_apps_search_bar_bottom_adjustment);
if (includeTabsMargin) {
topMargin += getContext().getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_pill_height);
+ R.dimen.all_apps_header_pill_height)
+ + getContext().getResources().getDimensionPixelSize(
+ R.dimen.all_apps_tabs_margin_top);
}
layoutParams.topMargin = topMargin;
}
@@ -901,6 +915,7 @@
layoutParams.removeRule(RelativeLayout.ABOVE);
layoutParams.removeRule(RelativeLayout.ALIGN_TOP);
layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
+ layoutParams.removeRule(RelativeLayout.BELOW);
}
protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList) {
@@ -1209,6 +1224,13 @@
}
}
+ protected void setScrollbarVisibility(boolean visible) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null && rv.getScrollbar() != null) {
+ rv.getScrollbar().setVisibility(visible ? VISIBLE : GONE);
+ }
+ }
+
protected void updateSearchResultsVisibility() {
if (isSearching()) {
getSearchRecyclerView().setVisibility(VISIBLE);
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index a1f6ebe..2c7c9f7 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -228,7 +228,6 @@
mTabsHidden = tabsHidden;
maybeSetTabVisibility(VISIBLE);
- updateExpectedHeight();
mMainRV = mainRV;
mWorkRV = workRV;
mSearchRV = searchRV;
@@ -251,6 +250,8 @@
: rvType == AdapterHolder.WORK ? mWorkRV : mSearchRV;
mCurrentRV.addOnScrollListener(mOnScrollListener);
maybeSetTabVisibility(rvType == AdapterHolder.SEARCH ? GONE : VISIBLE);
+
+ updateExpectedHeight();
}
/** Update tab visibility to the given state, only if tabs are active (work profile exists). */
@@ -265,10 +266,7 @@
return;
}
mMaxTranslation += mFloatingRowsHeight;
- if (!mTabsHidden) {
- mMaxTranslation += mTabsAdditionalPaddingBottom
- + getResources().getDimensionPixelSize(R.dimen.all_apps_tabs_margin_top);
- }
+ // No need for mMaxTranslation to be any taller now that we align below the header.
}
int getMaxTranslation() {
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index f9d047b..d02987a 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -135,7 +135,7 @@
public boolean onBackKey() {
// Only hide the search field if there is no query
String query = Utilities.trim(mInput.getEditableText().toString());
- if (query.isEmpty()) {
+ if (!query.isEmpty()) {
reset();
return true;
}
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 78c305b..d83efd6 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -77,7 +77,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_content_overlap);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 262b2a1..e56946c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -361,7 +361,7 @@
// TODO(Block 20): Clean up flags
public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(270393276,
- "ENABLE_SCRIM_FOR_APP_LAUNCH", DISABLED, "Enables scrim during app launch animation.");
+ "ENABLE_SCRIM_FOR_APP_LAUNCH", ENABLED, "Enables scrim during app launch animation.");
public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag(270393426,
"ENABLE_BACK_SWIPE_HOME_ANIMATION", ENABLED,
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 0ba468d..1ad4a33 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -116,11 +116,15 @@
: ItemInfoMatcher.ofPackages(packageSet, mUser);
final HashSet<ComponentName> removedComponents = new HashSet<>();
final HashMap<String, List<LauncherActivityInfo>> activitiesLists = new HashMap<>();
+ boolean needsRestart = false;
switch (mOp) {
case OP_ADD: {
for (int i = 0; i < N; i++) {
if (DEBUG) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]);
+ if (isTargetPackage(packages[i])) {
+ needsRestart = true;
+ }
iconCache.updateIconsForPkg(packages[i], mUser);
if (FeatureFlags.PROMISE_APPS_IN_ALL_APPS.get()) {
appsList.removePackage(packages[i], mUser);
@@ -148,6 +152,9 @@
for (int i = 0; i < N; i++) {
FileLog.d(TAG, "Removing app icon: " + packages[i]);
iconCache.removeIconsForPkg(packages[i], mUser);
+ if (isTargetPackage(packages[i])) {
+ needsRestart = true;
+ }
}
// Fall through
}
@@ -164,6 +171,11 @@
WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED, mOp == OP_SUSPEND);
if (DEBUG) Log.d(TAG, "mAllAppsList.(un)suspend " + N);
appsList.updateDisabledFlags(matcher, flagOp);
+ for (int i = 0; i < N; i++) {
+ if (isTargetPackage(packages[i])) {
+ needsRestart = true;
+ }
+ }
break;
case OP_USER_AVAILABILITY_CHANGE: {
UserManagerState ums = new UserManagerState();
@@ -393,6 +405,10 @@
}
bindUpdatedWidgets(dataModel);
}
+
+ if (needsRestart) {
+ Utilities.restart(context);
+ }
}
/**
@@ -415,4 +431,8 @@
}
return false;
}
+
+ private boolean isTargetPackage(String packageName) {
+ return packageName.equals(Utilities.GSA_PACKAGE);
+ }
}
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 0af7e67..4944c69 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -1,5 +1,7 @@
package com.android.launcher3.popup;
+import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_UNSUSPEND;
+
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_INSTALL_SYSTEM_SHORTCUT_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_PRIVATE_SPACE_UNINSTALL_SYSTEM_SHORTCUT_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP;
@@ -7,12 +9,18 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP;
import android.app.ActivityOptions;
+import android.app.AlertDialog;
+import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.SuspendDialogInfo;
import android.graphics.Rect;
+import android.os.RemoteException;
import android.os.Process;
import android.os.UserHandle;
+import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
@@ -311,6 +319,60 @@
}
}
+ public static final Factory<BaseDraggingActivity> PAUSE_APPS =
+ (activity, itemInfo, originalView) -> {
+ if (new PackageManagerHelper(activity).isAppSuspended(
+ itemInfo.getTargetComponent().getPackageName(), itemInfo.user)) {
+ return null;
+ }
+ return new PauseApps(activity, itemInfo, originalView);
+ };
+
+ public static class PauseApps<T extends Context & ActivityContext> extends SystemShortcut<T> {
+
+ public PauseApps(T target, ItemInfo itemInfo, View originalView) {
+ super(R.drawable.ic_hourglass_top, R.string.paused_apps_drop_target_label, target,
+ itemInfo, originalView);
+ }
+
+ @Override
+ public void onClick(View view) {
+ CharSequence appLabel = view.getContext().getPackageManager().getApplicationLabel(
+ new PackageManagerHelper(view.getContext()).getApplicationInfo(
+ mItemInfo.getTargetComponent().getPackageName(), mItemInfo.user, 0));
+ new AlertDialog.Builder(view.getContext())
+ .setIcon(R.drawable.ic_hourglass_top)
+ .setTitle(view.getContext().getString(R.string.pause_apps_dialog_title,
+ appLabel))
+ .setMessage(view.getContext().getString(R.string.pause_apps_dialog_message,
+ appLabel))
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(R.string.pause, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ try {
+ AppGlobals.getPackageManager().setPackagesSuspendedAsUser(
+ new String[]{
+ mItemInfo.getTargetComponent().getPackageName()},
+ true, null, null,
+ new SuspendDialogInfo.Builder()
+ .setIcon(R.drawable.ic_hourglass_top)
+ .setTitle(R.string.paused_apps_dialog_title)
+ .setMessage(R.string.paused_apps_dialog_message)
+ .setNeutralButtonAction(BUTTON_ACTION_UNSUSPEND)
+ .build(), 0, view.getContext().getOpPackageName(),
+ view.getContext().getUserId(),
+ mItemInfo.user.getIdentifier());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to pause app", e);
+ }
+ }
+ })
+ .show();
+ AbstractFloatingView.closeAllOpenViews(mTarget);
+ }
+ }
+
public static final Factory<ActivityContext> DONT_SUGGEST_APP =
(activity, itemInfo, originalView) -> {
if (!itemInfo.isPredictedItem()) {
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index 0ff10c2..178be1e 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -27,8 +27,10 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_INTERRUPTED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WORKSPACE_LONGPRESS;
+import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.PowerManager;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
@@ -48,6 +50,8 @@
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.TouchUtil;
+import com.android.launcher3.Utilities;
+
/**
* Helper class to handle touch on empty space in workspace and show options popup on long press
*/
@@ -73,15 +77,21 @@
private int mLongPressState = STATE_CANCELLED;
+ private final PowerManager mPm;
+
private final GestureDetector mGestureDetector;
+ private final Context mContext;
+
public WorkspaceTouchListener(Launcher launcher, Workspace<?> workspace) {
mLauncher = launcher;
mWorkspace = workspace;
+ mContext = workspace.getContext();
// Use twice the touch slop as we are looking for long press which is more
// likely to cause movement.
mTouchSlop = 2 * ViewConfiguration.get(launcher).getScaledTouchSlop();
- mGestureDetector = new GestureDetector(workspace.getContext(), this);
+ mPm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mGestureDetector = new GestureDetector(mContext, this);
}
@Override
@@ -215,4 +225,11 @@
}
}
}
+
+ @Override
+ public boolean onDoubleTap(MotionEvent event) {
+ if (Utilities.isDoubleTapGestureEnabled(mContext))
+ mPm.goToSleep(event.getEventTime());
+ return true;
+ }
}
diff --git a/src_build_config/com/android/launcher3/BuildConfig.java b/src_build_config/com/android/launcher3/BuildConfig.java
index 3841969..ae151ab 100644
--- a/src_build_config/com/android/launcher3/BuildConfig.java
+++ b/src_build_config/com/android/launcher3/BuildConfig.java
@@ -24,7 +24,7 @@
* Flag to state if the QSB is on the first screen and placed on the top,
* this can be overwritten in other launchers with a different value, if needed.
*/
- public static final boolean QSB_ON_FIRST_SCREEN = true;
+ public static final boolean QSB_ON_FIRST_SCREEN = false;
/**
* Flag to state if the widget on the top of the first screen should be shown.