diff --git a/build.gradle b/build.gradle index 969f3e3013a..d17404ec99e 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { id 'org.jetbrains.kotlin.plugin.serialization' version "1.9.22" id "com.google.devtools.ksp" version "1.9.22-1.0.17" id 'com.google.protobuf' version "0.9.4" - id 'app.cash.licensee' version "1.8.0" + id 'app.cash.licensee' version "1.9.0" id 'dev.rikka.tools.refine' version "4.4.0" id 'org.gradle.android.cache-fix' version '3.0' id 'com.diffplug.spotless' version '6.25.0' @@ -362,7 +362,7 @@ dependencies { implementation "com.google.accompanist:accompanist-insets-ui:$accompanistVersion" implementation "com.google.accompanist:accompanist-permissions:$accompanistVersion" implementation "com.google.android.material:material:1.11.0" - implementation "io.github.fornewid:material-motion-compose-core:1.1.1" + implementation "io.github.fornewid:material-motion-compose-core:1.2.0" implementation 'dev.kdrag0n:colorkt:1.0.5' implementation 'io.coil-kt:coil-compose:2.5.0' implementation 'me.xdrop:fuzzywuzzy:1.4.0' diff --git a/lawnchair/res/values/config.xml b/lawnchair/res/values/config.xml index 2283cb51d8c..664e3048d3a 100644 --- a/lawnchair/res/values/config.xml +++ b/lawnchair/res/values/config.xml @@ -113,6 +113,8 @@ true false true + true + true 1.0 1.0 @@ -128,6 +130,7 @@ 3 5 2 + 200 1.0 diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index ee851778687..ed268f7d752 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -205,6 +205,11 @@ Prevents changes to the home screen layout. Unlock Home Screen Home Screen is locked. + Show dot pagination + Enable showing dot pagination in workspace. + Show Material U Popup + Enable bouncy and slightly consolidated popup. + Pop-up Menu Show Lock Button @@ -347,8 +352,10 @@ Max Suggestion Result Count Max Settings Entry Result Count Max History Result Count + Max Web Suggestion Delay + - Clear + Clear @@ -358,6 +365,7 @@ Device Search Files + Suggestions Web suggestions (via Startpage) Advanced Search Search your contacts, files, and settings in app drawer search. diff --git a/lawnchair/src/app/lawnchair/allapps/SearchResultRightLeftIcon.kt b/lawnchair/src/app/lawnchair/allapps/SearchResultRightLeftIcon.kt index ceb8499e2e8..1772e0a158c 100644 --- a/lawnchair/src/app/lawnchair/allapps/SearchResultRightLeftIcon.kt +++ b/lawnchair/src/app/lawnchair/allapps/SearchResultRightLeftIcon.kt @@ -16,12 +16,14 @@ import app.lawnchair.util.AppInfo import app.lawnchair.util.AppInfoHelper import app.lawnchair.util.ImageViewWrapper import com.android.app.search.LayoutType +import com.android.launcher3.DeviceProfile import com.android.launcher3.R class SearchResultRightLeftIcon(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs), SearchResultView { private val launcher = context.launcher + private var grid: DeviceProfile = launcher.deviceProfile private lateinit var title: TextView private lateinit var avatar: SearchResultIcon private lateinit var call: ImageView @@ -66,7 +68,7 @@ class SearchResultRightLeftIcon(context: Context, attrs: AttributeSet?) : LayoutParams.MATCH_PARENT, heightRes, ) - val horizontalMargin = 48 + val horizontalMargin = grid.allAppsLeftRightMargin layoutParams.leftMargin = horizontalMargin layoutParams.rightMargin = horizontalMargin this.layoutParams = layoutParams diff --git a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt index 36da7114c53..6b82b08a492 100644 --- a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt +++ b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt @@ -73,8 +73,9 @@ class PreferenceManager private constructor(private val context: Context) : Base val fontBody = FontPref("pref_fontBody", fontCache.uiText, recreate) val fontBodyMedium = FontPref("pref_fontBodyMedium", fontCache.uiTextMedium, recreate) - val deviceSearch = BoolPref("device_search", true, recreate) - val searchResultShortcuts = BoolPref("pref_searchResultShortcuts", true) + // TODO REMOVE + val deviceSearch = BoolPref("device_search", false, recreate) + val searchResultShortcuts = BoolPref("pref_searchResultShortcuts", false) val searchResultPeople = BoolPref("pref_searchResultPeople", false, recreate) val searchResultPixelTips = BoolPref("pref_searchResultPixelTips", false) val searchResultSettings = BoolPref("pref_searchResultSettings", false) diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt index da1d2294536..70bee3f1df4 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt @@ -379,6 +379,11 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre defaultValue = resourceProvider.getInt(R.dimen.config_default_people_max_result_count), ) + val maxWebSuggestionDelay = preference( + key = intPreferencesKey(name = "max_web_suggestion_delay"), + defaultValue = resourceProvider.getInt(R.dimen.config_default_max_web_suggestion_delay), + ) + val maxSettingsEntryResultCount = preference( key = intPreferencesKey(name = "max_settings_entry_result_count"), defaultValue = resourceProvider.getInt(R.dimen.config_default_settings_entry_max_result_count), @@ -395,6 +400,18 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre onSet = { reloadHelper.restart() }, ) + val enableDotPagination = preference( + key = booleanPreferencesKey(name = "enable_dot_pagination"), + defaultValue = context.resources.getBoolean(R.bool.config_default_enable_dot_pagination), + onSet = { reloadHelper.recreate() }, + ) + + val enableMaterialUPopUp = preference( + key = booleanPreferencesKey(name = "enable_material_u_popup"), + defaultValue = context.resources.getBoolean(R.bool.config_default_enable_material_u_popup), + onSet = { reloadHelper.recreate() }, + ) + val enableFeed = preference( key = booleanPreferencesKey(name = "enable_feed"), defaultValue = context.resources.getBoolean(R.bool.config_default_enable_feed), diff --git a/lawnchair/src/app/lawnchair/search/LawnchairSearchAdapterProvider.kt b/lawnchair/src/app/lawnchair/search/LawnchairSearchAdapterProvider.kt index 5c33679607d..e883884448a 100644 --- a/lawnchair/src/app/lawnchair/search/LawnchairSearchAdapterProvider.kt +++ b/lawnchair/src/app/lawnchair/search/LawnchairSearchAdapterProvider.kt @@ -10,6 +10,7 @@ import app.lawnchair.allapps.SearchResultView import app.lawnchair.allapps.SearchResultView.Companion.EXTRA_QUICK_LAUNCH import app.lawnchair.search.data.SearchResultActionCallBack import com.android.app.search.LayoutType +import com.android.launcher3.DeviceProfile import com.android.launcher3.R import com.android.launcher3.allapps.ActivityAllAppsContainerView import com.android.launcher3.allapps.AllAppsGridAdapter @@ -68,9 +69,10 @@ class LawnchairSearchAdapterProvider( ): BaseAllAppsAdapter.ViewHolder { val view = layoutInflater.inflate(layoutIdMap[viewType], parent, false) + val grid: DeviceProfile = mLauncher.deviceProfile if (viewType != SEARCH_RESULT_ICON) { val layoutParams = ViewGroup.MarginLayoutParams(view.layoutParams) - val horizontalMargin = 48 + val horizontalMargin = grid.allAppsLeftRightMargin layoutParams.leftMargin = horizontalMargin layoutParams.rightMargin = horizontalMargin view.layoutParams = layoutParams diff --git a/lawnchair/src/app/lawnchair/search/LawnchairSearchAlgorithm.kt b/lawnchair/src/app/lawnchair/search/LawnchairSearchAlgorithm.kt index cc943a8b260..6d26a3b82a5 100644 --- a/lawnchair/src/app/lawnchair/search/LawnchairSearchAlgorithm.kt +++ b/lawnchair/src/app/lawnchair/search/LawnchairSearchAlgorithm.kt @@ -36,7 +36,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.async import kotlinx.coroutines.withContext -import kotlinx.coroutines.withTimeout +import kotlinx.coroutines.withTimeoutOrNull sealed class LawnchairSearchAlgorithm( protected val context: Context, @@ -167,6 +167,7 @@ sealed class LawnchairSearchAlgorithm( private var maxFilesCount = 3 private var maxSettingsEntryCount = 5 private var maxRecentResultCount = 2 + private var maxWebSuggestionDelay = 200 val coroutineScope = CoroutineScope(context = Dispatchers.IO) val pref2 = PreferenceManager2.getInstance(context) @@ -186,41 +187,52 @@ sealed class LawnchairSearchAlgorithm( pref2.maxRecentResultCount.onEach(launchIn = coroutineScope) { maxRecentResultCount = it } + pref2.maxWebSuggestionDelay.onEach(launchIn = coroutineScope) { + maxWebSuggestionDelay = it + } } protected suspend fun performDeviceWideSearch(query: String, prefs: PreferenceManager): MutableList = withContext(Dispatchers.IO) { val results = ArrayList() - if (prefs.searchResultPeople.get()) { - if (requestContactPermissionGranted(context, prefs)) { - val contactResults = findContactsByName(context, query, maxPeopleCount) - results.addAll(contactResults.map { SearchResult(CONTACT, it) }) + val contactDeferred = async { + if (prefs.searchResultPeople.get() && requestContactPermissionGranted(context, prefs)) { + findContactsByName(context, query, maxPeopleCount) + .map { SearchResult(CONTACT, it) } + } else { + emptyList() } } - if (prefs.searchResultFiles.get()) { - if (checkAndRequestFilesPermission(context, prefs)) { - val fileResults = queryFilesInMediaStore(context, keyword = query, maxResult = maxFilesCount).toList() - results.addAll(fileResults.map { SearchResult(FILES, it) }) + val filesDeferred = async { + if (prefs.searchResultFiles.get() && checkAndRequestFilesPermission(context, prefs)) { + queryFilesInMediaStore(context, keyword = query, maxResult = maxFilesCount) + .toList() + .map { SearchResult(FILES, it) } + } else { + emptyList() } } - if (prefs.searchResultSettingsEntry.get()) { - val settingResult = findSettingsByNameAndAction(query, maxSettingsEntryCount) - results.addAll(settingResult.map { SearchResult(SETTING, it) }) + val settingsDeferred = async { + findSettingsByNameAndAction(query, maxSettingsEntryCount) + .map { SearchResult(SETTING, it) } } - if (prefs.searchResultStartPageSuggestion.get()) { - val startPageSuggestions = async { - try { - withTimeout(3000) { - getStartPageSuggestions(query, maxSuggestionCount) + val startPageSuggestionsDeferred = async { + try { + val timeout = maxWebSuggestionDelay.toLong() + val result = withTimeoutOrNull(timeout) { + if (prefs.searchResultStartPageSuggestion.get()) { + getStartPageSuggestions(query, maxSuggestionCount).map { SearchResult(SUGGESTION, it) } + } else { + emptyList() } - } catch (e: TimeoutCancellationException) { - emptyList() } + result ?: emptyList() + } catch (e: TimeoutCancellationException) { + emptyList() } - results.addAll(startPageSuggestions.await().map { SearchResult(SUGGESTION, it) }) } if (prefs.searchResulRecentSuggestion.get()) { @@ -244,6 +256,11 @@ sealed class LawnchairSearchAlgorithm( ) } + results.addAll(contactDeferred.await()) + results.addAll(filesDeferred.await()) + results.addAll(settingsDeferred.await()) + results.addAll(startPageSuggestionsDeferred.await()) + results } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/controls/SliderPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/controls/SliderPreference.kt index f367775b14f..f4a839f472d 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/controls/SliderPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/controls/SliderPreference.kt @@ -51,6 +51,7 @@ fun SliderPreference( valueRange: ClosedRange, step: Int, showAsPercentage: Boolean = false, + showUnit: String = "", ) { val transformedAdapter = rememberTransformAdapter( adapter = adapter, @@ -65,6 +66,7 @@ fun SliderPreference( valueRange = start..endInclusive, step = step.toFloat(), showAsPercentage = showAsPercentage, + showUnit = showUnit, ) } @@ -75,6 +77,7 @@ fun SliderPreference( valueRange: ClosedFloatingPointRange, step: Float, showAsPercentage: Boolean = false, + showUnit: String = "", ) { var adapterValue by adapter var sliderValue by remember { mutableFloatStateOf(adapterValue) } @@ -105,9 +108,9 @@ fun SliderPreference( stringResource( id = R.string.n_percent, (value * 100).roundToInt(), - ) + ) + " $showUnit" } else { - value.roundToInt().toString() + value.roundToInt().toString() + " $showUnit" }, ) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt index a3abc417193..8a6945d519d 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt @@ -200,19 +200,28 @@ fun AppDrawerPreferences() { } ExpandAndShrink(visible = showDrawerSearchBar.state.value) { - PreferenceGroup { + PreferenceGroup(heading = stringResource(id = R.string.pref_suggestion_label)) { DividerColumn { SwitchPreference( adapter = prefs.searchResultStartPageSuggestion.getAdapter(), label = stringResource(id = R.string.pref_suggestion_title), ) ExpandAndShrink(visible = prefs.searchResultStartPageSuggestion.getAdapter().state.value) { - SliderPreference( - label = stringResource(id = R.string.max_suggestion_result_count_title), - adapter = prefs2.maxSuggestionResultCount.getAdapter(), - step = 1, - valueRange = 3..10, - ) + DividerColumn { + SliderPreference( + label = stringResource(id = R.string.max_suggestion_result_count_title), + adapter = prefs2.maxSuggestionResultCount.getAdapter(), + step = 1, + valueRange = 3..10, + ) + SliderPreference( + label = stringResource(id = R.string.max_web_suggestion_delay), + adapter = prefs2.maxWebSuggestionDelay.getAdapter(), + step = 100, + valueRange = 200..5000, + showUnit = "ms", + ) + } } SwitchPreference( adapter = prefs.searchResulRecentSuggestion.getAdapter(), diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/HomeScreenPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/HomeScreenPreferences.kt index 44fd9a0fcf5..f5380a95131 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/HomeScreenPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/HomeScreenPreferences.kt @@ -36,6 +36,7 @@ import app.lawnchair.ui.preferences.components.controls.ClickablePreference import app.lawnchair.ui.preferences.components.controls.ListPreference import app.lawnchair.ui.preferences.components.controls.SliderPreference import app.lawnchair.ui.preferences.components.controls.SwitchPreference +import app.lawnchair.ui.preferences.components.layout.DividerColumn import app.lawnchair.ui.preferences.components.layout.ExpandAndShrink import app.lawnchair.ui.preferences.components.layout.PreferenceGroup import app.lawnchair.ui.preferences.components.layout.PreferenceLayout @@ -114,13 +115,25 @@ fun HomeScreenPreferences() { destination = subRoute(name = HomeScreenRoutes.GRID), subtitle = stringResource(id = R.string.x_by_y, columns, rows), ) - SwitchPreference( - adapter = lockHomeScreenAdapter, - label = stringResource(id = R.string.home_screen_lock), - description = stringResource(id = R.string.home_screen_lock_description), - ) + DividerColumn { + SwitchPreference( + adapter = lockHomeScreenAdapter, + label = stringResource(id = R.string.home_screen_lock), + description = stringResource(id = R.string.home_screen_lock_description), + ) + SwitchPreference( + adapter = prefs2.enableDotPagination.getAdapter(), + label = stringResource(id = R.string.show_dot_pagination_label), + description = stringResource(id = R.string.show_dot_pagination_description), + ) + } } PreferenceGroup(heading = stringResource(id = R.string.popup_menu)) { + SwitchPreference( + adapter = prefs2.enableMaterialUPopUp.getAdapter(), + label = stringResource(id = R.string.show_material_u_popup_label), + description = stringResource(id = R.string.show_material_u_popup_description), + ) SwitchPreference( adapter = prefs2.lockHomeScreenButtonOnPopUp.getAdapter(), label = stringResource(id = R.string.home_screen_lock_toggle_from_home_popup), diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 94a746a224a..4d92a013073 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -37,11 +37,13 @@ import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.quickstep.util.BaseDepthController; +import com.patrykmichalik.opto.core.PreferenceExtensionsKt; import java.io.PrintWriter; import java.util.function.Consumer; import app.lawnchair.compat.LawnchairQuickstepCompat; +import app.lawnchair.preferences2.PreferenceManager2; /** * Controls blur and wallpaper zoom, for the Launcher surface only. @@ -60,8 +62,12 @@ public class DepthController extends BaseDepthController implements StateHandler private View.OnAttachStateChangeListener mOnAttachListener; + private final boolean mEnableDepth; + public DepthController(Launcher l) { super(l); + var pref = PreferenceManager2.getInstance(l).getWallpaperDepthEffect(); + mEnableDepth = PreferenceExtensionsKt.firstBlocking(pref); } private void onLauncherDraw() { @@ -163,9 +169,13 @@ public void setStateWithAnimation(LauncherState toState, StateAnimationConfig co @Override public void applyDepthAndBlur() { - if (app.lawnchair.LawnchairApp.isAtleastT()) { - ensureDependencies(); - super.applyDepthAndBlur(); + try { + if (LawnchairQuickstepCompat.ATLEAST_R && mEnableDepth) { + ensureDependencies(); + super.applyDepthAndBlur(); + } + } catch (Throwable t) { + // Ignore } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java index 512b77a92a4..b5c8505437f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -32,6 +32,7 @@ import com.android.launcher3.BubbleTextView; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.FolderDotInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; @@ -163,7 +164,7 @@ public PopupContainerWithArrow showForIcon(BubbleTextView ic .filter(Objects::nonNull) .collect(Collectors.toList()); - if (ENABLE_MATERIAL_U_POPUP.get()) { + if (FeatureFlags.showMaterialUPopup(icon.getContext())) { container = (PopupContainerWithArrow) context.getLayoutInflater().inflate( R.layout.popup_container_material_u, context.getDragLayer(), false); container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 743c25ca75b..1a0b46a43b3 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -63,6 +63,7 @@ import com.android.launcher3.dragndrop.DragOptions.PreDragCondition; import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.folder.FolderIcon; +import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.graphics.PreloadIconDrawable; import com.android.launcher3.icons.DotRenderer; @@ -398,7 +399,7 @@ protected void applyIconAndLabel(ItemInfoWithIcon info) { boolean useTheme = shouldUseTheme(); FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme); mDotParams.appColor = iconDrawable.getIconColor(); - mDotParams.color = ColorTokens.DotColor.resolveColor(getContext()); + mDotParams.color = IconPalette.getMutedColor(iconDrawable.getIconColor(), 0.54f); setIcon(iconDrawable); applyLabel(info); } diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 0fdff9cd3d7..4756f59fe06 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -795,9 +795,9 @@ private void calculateAndSetWorkspaceVerticalPadding(Context context, private void updateHotseatSizes(int hotseatIconSizePx) { // Ensure there is enough space for folder icons, which have a slightly larger // radius. - hotseatCellHeightPx = getIconSizeWithOverlap(hotseatIconSizePx); + hotseatCellHeightPx = getIconSizeWithOverlap(hotseatIconSizePx * 2) - hotseatIconSizePx / 2; - var space = Math.abs(hotseatCellHeightPx / 2) - 10; + var space = Math.abs(hotseatCellHeightPx / 2) - 16; hotseatBarBottomSpacePx *= PreferenceExtensionsKt .firstBlocking(preferenceManager2.getHotseatBottomFactor()); @@ -1213,10 +1213,12 @@ public void updateIconSize(float scale, Resources res) { * width. */ private int calculateHotseatBorderSpace(float hotseatWidthPx, int numExtraBorder) { - + int numBorders = (numShownHotseatIcons - 1 + numExtraBorder); + if (numBorders <= 0) + return 0; float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons; int hotseatBorderSpacePx = (int) (hotseatWidthPx - hotseatIconsTotalPx) - / (numShownHotseatIcons - 1 + numExtraBorder); + / numBorders; return Math.min(hotseatBorderSpacePx, mMaxHotseatIconSpacePx); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b2e831c36cf..b0ad4d6ad90 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1401,7 +1401,7 @@ protected void setupViews() { mDropTargetBar.setup(mDragController); mAllAppsController.setupViews(mScrimView, mAppsView); - if (SHOW_DOT_PAGINATION.get()) { + if (FeatureFlags.showDotPagination(this)) { mWorkspace.getPageIndicator().setShouldAutoHide(true); mWorkspace.getPageIndicator().setPaintColor( Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText) @@ -1412,7 +1412,7 @@ protected void setupViews() { @Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { - if (SHOW_DOT_PAGINATION.get() && WorkspacePageIndicator.class.getName().equals(name)) { + if (FeatureFlags.showDotPagination(this) && WorkspacePageIndicator.class.getName().equals(name)) { return LayoutInflater.from(context).inflate(R.layout.page_indicator_dots, (ViewGroup) parent, false); } @@ -1531,6 +1531,7 @@ void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, if (appWidgetInfo == null) { appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId); + if (appWidgetInfo == null) return; } if (hostView == null) { @@ -1540,6 +1541,7 @@ void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, if (appWidgetInfo.provider == null) { appWidgetInfo.provider = itemInfo.getTargetComponent(); + if (appWidgetInfo.provider == null) return; } LauncherAppWidgetInfo launcherInfo; launcherInfo = new LauncherAppWidgetInfo( diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 9a12bb72013..17e637a8445 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -412,7 +412,7 @@ private void setPageIndicatorInset() { } else { lp.leftMargin = lp.rightMargin = 0; lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - lp.bottomMargin = grid.hotseatBarSizePx; + lp.bottomMargin = grid.hotseatBarSizePx - grid.workspaceCellPaddingXPx; } mPageIndicator.setLayoutParams(lp); } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 1a998edfa68..8993636c1a5 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -70,6 +70,14 @@ public static boolean topQsbOnFirstScreenEnabled(Context context) { PreferenceManager2 preferenceManager2 = PreferenceManager2.getInstance(context); return PreferenceExtensionsKt.firstBlocking(preferenceManager2.getEnableSmartspace()); } + public static boolean showDotPagination(Context context) { + PreferenceManager2 preferenceManager2 = PreferenceManager2.getInstance(context); + return PreferenceExtensionsKt.firstBlocking(preferenceManager2.getEnableDotPagination()); + } + public static boolean showMaterialUPopup(Context context) { + PreferenceManager2 preferenceManager2 = PreferenceManager2.getInstance(context); + return PreferenceExtensionsKt.firstBlocking(preferenceManager2.getEnableMaterialUPopUp()); + } /** * Feature flag to handle define config changes dynamically instead of killing the process. *

diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java index bbad36d3e96..9a31bb90e55 100644 --- a/src/com/android/launcher3/graphics/IconPalette.java +++ b/src/com/android/launcher3/graphics/IconPalette.java @@ -16,6 +16,8 @@ package com.android.launcher3.graphics; +import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound; + import android.app.Notification; import android.content.Context; import android.graphics.Color; @@ -155,4 +157,9 @@ private static int findContrastColor(int fg, int bg, double minRatio) { } return ColorUtils.LABToColor(low, a, b); } + + public static int getMutedColor(int color, float whiteScrimAlpha) { + int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha)); + return ColorUtils.compositeColors(whiteScrim, color); + } } diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index 3ce6c0163d4..8e0b5a73001 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -47,6 +47,7 @@ import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.Themes; import app.lawnchair.theme.color.ColorTokens; @@ -72,7 +73,7 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final int PAGE_INDICATOR_ALPHA = 255; private static final int DOT_ALPHA = 128; private static final float DOT_ALPHA_FRACTION = 0.5f; - private static final int DOT_GAP_FACTOR = SHOW_DOT_PAGINATION.get() ? 4 : 3; + private final int DOT_GAP_FACTOR = FeatureFlags.showDotPagination(getContext()) ? 4 : 3; private static final int VISIBLE_ALPHA = 255; private static final int INVISIBLE_ALPHA = 0; private Paint mPaginationPaint; @@ -155,7 +156,7 @@ public PageIndicatorDots(Context context, AttributeSet attrs, int defStyleAttr) mPaginationPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaginationPaint.setStyle(Style.FILL); mPaginationPaint.setColor(ColorTokens.FolderPaginationColor.resolveColor(context)); - mDotRadius = (SHOW_DOT_PAGINATION.get() + mDotRadius = (FeatureFlags.showDotPagination(context) ? getResources().getDimension(R.dimen.page_indicator_dot_size_v2) : getResources().getDimension(R.dimen.page_indicator_dot_size)) / 2; @@ -166,7 +167,7 @@ public PageIndicatorDots(Context context, AttributeSet attrs, int defStyleAttr) @Override public void setScroll(int currentScroll, int totalScroll) { - if (SHOW_DOT_PAGINATION.get() && currentScroll == 0 && totalScroll == 0) { + if (FeatureFlags.showDotPagination(getContext()) && currentScroll == 0 && totalScroll == 0) { CURRENT_POSITION.set(this, (float) mActivePage); return; } @@ -219,7 +220,7 @@ public void setScroll(int currentScroll, int totalScroll) { @Override public void setShouldAutoHide(boolean shouldAutoHide) { - mShouldAutoHide = shouldAutoHide && SHOW_DOT_PAGINATION.get(); + mShouldAutoHide = shouldAutoHide && FeatureFlags.showDotPagination(getContext()); if (shouldAutoHide && mPaginationPaint.getAlpha() > INVISIBLE_ALPHA) { hideAfterDelay(); } else if (!shouldAutoHide) { @@ -425,7 +426,7 @@ protected void onDraw(Canvas canvas) { int alpha = mPaginationPaint.getAlpha(); // Here we draw the dots - mPaginationPaint.setAlpha(SHOW_DOT_PAGINATION.get() + mPaginationPaint.setAlpha(FeatureFlags.showDotPagination(getContext()) ? ((int) (alpha * DOT_ALPHA_FRACTION)) : DOT_ALPHA); for (int i = 0; i < mNumPages; i++) { @@ -434,7 +435,7 @@ protected void onDraw(Canvas canvas) { } // Here we draw the current page indicator - mPaginationPaint.setAlpha(SHOW_DOT_PAGINATION.get() ? alpha : PAGE_INDICATOR_ALPHA); + mPaginationPaint.setAlpha(FeatureFlags.showDotPagination(getContext()) ? alpha : PAGE_INDICATOR_ALPHA); canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint); } } @@ -502,7 +503,7 @@ public void onAnimationCancel(Animator animation) { @Override public void onAnimationEnd(Animator animation) { if (!mCancelled) { - if (mShouldAutoHide && SHOW_DOT_PAGINATION.get()) { + if (mShouldAutoHide && FeatureFlags.showDotPagination(getContext())) { hideAfterDelay(); } mAnimator = null; diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index f966a09fd52..02d81faade7 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -52,6 +52,7 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.util.RunnableList; @@ -177,7 +178,7 @@ public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) { mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children); - if (!ENABLE_MATERIAL_U_POPUP.get() && mActivityContext.canUseMultipleShadesForPopup()) { + if (!FeatureFlags.showMaterialUPopup(getContext()) && mActivityContext.canUseMultipleShadesForPopup()) { mColors = new int[] { ColorTokens.PopupShadeFirst.resolveColor(context), ColorTokens.PopupShadeSecond.resolveColor(context), @@ -266,18 +267,18 @@ protected void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundCo mlp.bottomMargin = 0; if (colors != null) { - if (!ENABLE_MATERIAL_U_POPUP.get()) { + if (!FeatureFlags.showMaterialUPopup(getContext())) { backgroundColor = colors[numVisibleChild % colors.length]; } - if (ENABLE_MATERIAL_U_POPUP.get() && isShortcutContainer(view)) { + if (FeatureFlags.showMaterialUPopup(getContext()) && isShortcutContainer(view)) { setChildColor(view, colors[0], colorAnimator); mArrowColor = colors[0]; } } // Arrow color matches the first child or the last child. - if (!ENABLE_MATERIAL_U_POPUP.get() + if (!FeatureFlags.showMaterialUPopup(getContext()) && (mIsAboveIcon || (numVisibleChild == 0 && viewGroup == this))) { mArrowColor = backgroundColor; } @@ -591,7 +592,7 @@ protected View getAccessibilityInitialFocusView() { protected void animateOpen() { setVisibility(View.VISIBLE); - mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get() + mOpenCloseAnimator = FeatureFlags.showMaterialUPopup(getContext()) ? getMaterialUOpenCloseAnimator( true, OPEN_DURATION_U, @@ -691,7 +692,7 @@ protected void animateClose() { } mIsOpen = false; - mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get() + mOpenCloseAnimator = FeatureFlags.showMaterialUPopup(getContext()) ? getMaterialUOpenCloseAnimator( false, CLOSE_DURATION_U, diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 92051114cca..8f26d17a949 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -55,6 +55,7 @@ import com.android.launcher3.R; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.DotInfo; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; @@ -239,7 +240,7 @@ public static PopupContainerWithArrow showForIcon(BubbleTextView icon) .map(s -> s.getShortcut(launcher, item, icon)) .filter(Objects::nonNull) .collect(Collectors.toList()); - if (ENABLE_MATERIAL_U_POPUP.get()) { + if (FeatureFlags.showMaterialUPopup(launcher)) { container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate( R.layout.popup_container_material_u, launcher.getDragLayer(), false); container.configureForLauncher(launcher); @@ -504,7 +505,7 @@ private void addSystemShortcutsIconsOnly(List systemShortcuts) { return; } - mSystemShortcutContainer = ENABLE_MATERIAL_U_POPUP.get() + mSystemShortcutContainer = FeatureFlags.showMaterialUPopup(getContext()) ? inflateAndAdd(R.layout.system_shortcut_icons_container_material_u, this) : inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0); diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index e8be12cba65..9d95290d505 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -203,7 +203,7 @@ boolean onIconLongClicked(View v) { } int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item); final PopupContainerWithArrow container; - if (ENABLE_MATERIAL_U_POPUP.get()) { + if (FeatureFlags.showMaterialUPopup(getContext())) { container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate( R.layout.popup_container_material_u, mActivity.getDragLayer(), false); container.populateAndShowRowsMaterialU((BubbleTextView) v, deepShortcutCount, diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index 4a2665291af..770850d3c69 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -49,6 +49,7 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.StatsLogManager.EventEnum; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.model.data.WorkspaceItemInfo; @@ -153,7 +154,7 @@ protected void getTargetObjectLocation(Rect outPos) { @Override public void assignMarginsAndBackgrounds(ViewGroup viewGroup) { - if (ENABLE_MATERIAL_U_POPUP.get()) { + if (FeatureFlags.showMaterialUPopup(getContext())) { assignMarginsAndBackgrounds(viewGroup, mColors[0]); } else { diff --git a/src/com/android/launcher3/widget/LauncherWidgetHolder.java b/src/com/android/launcher3/widget/LauncherWidgetHolder.java index 125b9d71e87..ad7f7c3e7fc 100644 --- a/src/com/android/launcher3/widget/LauncherWidgetHolder.java +++ b/src/com/android/launcher3/widget/LauncherWidgetHolder.java @@ -272,9 +272,7 @@ private void sendActionCancelled(final BaseActivity activity, final int requestC private Bundle getDefaultConfigurationActivityOptions() { // Must allow background activity start for U. - return ActivityOptions.makeBasic() - .setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED) + return Utilities.allowBGLaunch(ActivityOptions.makeBasic()) .toBundle(); } @@ -296,8 +294,7 @@ protected Bundle getConfigurationActivityOptions(@NonNull BaseDraggingActivity a return getDefaultConfigurationActivityOptions(); ActivityOptionsWrapper activityOptionsWrapper = activity.getActivityLaunchOptions(view, (ItemInfo) tag); // Must allow background activity start for U. - activityOptionsWrapper.options.setPendingIntentBackgroundActivityStartMode( - ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED); + Utilities.allowBGLaunch(activityOptionsWrapper.options); Bundle bundle = activityOptionsWrapper.toBundle(); bundle.putInt(KEY_SPLASH_SCREEN_STYLE, SPLASH_SCREEN_STYLE_EMPTY); return bundle;