fix: Adapt clean workspace to 16-dev-qpr1
This commit is contained in:
@@ -166,6 +166,8 @@
|
||||
<string name="home_screen_label">Home screen</string>
|
||||
<string name="home_screen_description">Feed, grid, icons</string>
|
||||
|
||||
<string name="home_screen_actions">Home screen actions</string>
|
||||
|
||||
<string name="dock_label">Dock</string>
|
||||
<string name="dock_description">Search bar, icon count</string>
|
||||
|
||||
@@ -277,6 +279,9 @@
|
||||
<string name="reset_custom_icons">Reset custom icons</string>
|
||||
<string name="reset_custom_icons_confirmation">All custom icons will be reset. Do you want to continue?</string>
|
||||
|
||||
<string name="remove_all_views_from_home_screen">Clear home screen</string>
|
||||
<string name="remove_all_views_from_home_screen_desc">Home screen will be cleared. Do you want to continue?</string>
|
||||
|
||||
<!-- Icon picker -->
|
||||
<string name="icon_picker_default_category">Icons</string>
|
||||
<string name="icon_picker_reset_to_default">Reset to default</string>
|
||||
@@ -777,7 +782,7 @@
|
||||
|
||||
-->
|
||||
<!-- Launcher strings used -->
|
||||
<string name="all_apps_device_search_hint">Search apps, web, and more</string>
|
||||
<string name="all_apps_device_search_hint">Search web and more</string>
|
||||
<string name="all_apps_search_bar_hint">Search apps</string>
|
||||
<string name="all_apps_no_search_results">No apps found matching \"<xliff:g example="Android" id="query">%1$s</xliff:g>\"</string>
|
||||
|
||||
@@ -909,4 +914,6 @@
|
||||
<string name="grant_requested_permissions">Grant permissions</string>
|
||||
<string name="permissions_needed">Permissions needed</string>
|
||||
<string name="grant_requested_permissions_tap">Tap to grant permissions</string>
|
||||
<!-- Message shown when all home screen views are removed -->
|
||||
<string name="home_screen_all_views_removed_msg">Home screen cleared</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,10 +7,10 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.lawnchair.data.folder.model.FolderOrderUtils
|
||||
import app.lawnchair.data.folder.model.FolderViewModel
|
||||
import app.lawnchair.flowerpot.Flowerpot
|
||||
import app.lawnchair.launcher
|
||||
import app.lawnchair.preferences.PreferenceManager
|
||||
import app.lawnchair.preferences2.PreferenceManager2
|
||||
import app.lawnchair.util.categorizeAppsWithSystemAndGoogle
|
||||
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener
|
||||
import com.android.launcher3.allapps.AllAppsStore
|
||||
import com.android.launcher3.allapps.AlphabeticalAppsList
|
||||
@@ -45,7 +45,6 @@ class LawnchairAlphabeticalAppsList<T>(
|
||||
private val filteredList = mutableListOf<AppInfo>()
|
||||
|
||||
private val folderOrder = FolderOrderUtils.stringToIntList(prefs.drawerListOrder.get())
|
||||
private val potsManager = Flowerpot.Manager.getInstance(context)
|
||||
|
||||
init {
|
||||
context.launcher.deviceProfile.inv.addOnChangeListener(this)
|
||||
@@ -88,8 +87,10 @@ class LawnchairAlphabeticalAppsList<T>(
|
||||
if (isWorkOrPrivateSpace(appList)) return super.addAppsWithSections(appList, position)
|
||||
|
||||
if (!drawerListDefault) {
|
||||
val categorizedApps = potsManager.categorizeApps(appList)
|
||||
categorizedApps.forEach { (category, apps) ->
|
||||
val validApps = appList.mapNotNull { it }
|
||||
val finalCategorizedApps = categorizeAppsWithSystemAndGoogle(validApps, context)
|
||||
|
||||
finalCategorizedApps.forEach { (category, apps) ->
|
||||
if (apps.size == 1) {
|
||||
mAdapterItems.add(AdapterItem.asApp(apps.first()))
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@ import app.lawnchair.LawnchairLauncher
|
||||
import app.lawnchair.flowerpot.Flowerpot
|
||||
import app.lawnchair.launcher
|
||||
import app.lawnchair.launcherNullable
|
||||
import app.lawnchair.util.categorizeAppsWithSystemAndGoogle
|
||||
import app.lawnchair.util.restartLauncher
|
||||
import com.android.launcher3.InvariantDeviceProfile
|
||||
import com.android.launcher3.LauncherAppState
|
||||
@@ -17,6 +18,7 @@ import com.android.launcher3.model.data.FolderInfo
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo
|
||||
import com.android.launcher3.provider.RestoreDbTask
|
||||
import com.android.launcher3.util.ComponentKey
|
||||
import com.android.launcher3.util.PackageManagerHelper
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
@@ -101,9 +103,8 @@ class LawndeckManager(private val context: Context) {
|
||||
|
||||
onProgress?.invoke("Categorizing apps...")
|
||||
|
||||
// Use flowerpot to categorize apps
|
||||
val potsManager = Flowerpot.Manager.getInstance(context)
|
||||
val categorizedApps = potsManager.categorizeApps(apps.map { it as? AppInfo })
|
||||
val validApps = apps.mapNotNull { it as? AppInfo }
|
||||
val finalCategorizedApps = categorizeAppsWithSystemAndGoogle(validApps, context)
|
||||
|
||||
onProgress?.invoke("Adding apps to workspace...")
|
||||
|
||||
@@ -115,7 +116,7 @@ class LawndeckManager(private val context: Context) {
|
||||
var singleAppCount = 0
|
||||
|
||||
// Process each category
|
||||
categorizedApps.forEach { (category, categoryApps) ->
|
||||
finalCategorizedApps.forEach { (category, categoryApps) ->
|
||||
if (categoryApps.isEmpty()) return@forEach
|
||||
|
||||
if (categoryApps.size == 1) {
|
||||
@@ -188,22 +189,32 @@ class LawndeckManager(private val context: Context) {
|
||||
val activityInfo = activities[0]
|
||||
val appInfo = AppInfo(context, activityInfo, user)
|
||||
|
||||
// Use flowerpot to categorize the app
|
||||
val potsManager = Flowerpot.Manager.getInstance(context)
|
||||
val categorizedApps = potsManager.categorizeApps(listOf(appInfo))
|
||||
val intent = appInfo.intent
|
||||
|
||||
if (categorizedApps.isEmpty()) {
|
||||
// No category found, add directly to workspace
|
||||
ItemInstallQueue.INSTANCE.get(context).queueItem(packageName, user)
|
||||
return
|
||||
}
|
||||
// Determine category: Google Apps > System Apps > Flowerpot categories
|
||||
val category = when {
|
||||
packageName.startsWith("com.google.") -> "Google Apps"
|
||||
|
||||
// Get the category for this app (categorizedApps is a Map<String, List<AppInfo>>)
|
||||
val categoryEntry = categorizedApps.entries.firstOrNull() ?: run {
|
||||
ItemInstallQueue.INSTANCE.get(context).queueItem(packageName, user)
|
||||
return
|
||||
intent != null && PackageManagerHelper.isSystemApp(context, intent) -> "System Apps"
|
||||
|
||||
else -> {
|
||||
// Use flowerpot to categorize the app
|
||||
val potsManager = Flowerpot.Manager.getInstance(context)
|
||||
val categorizedApps = potsManager.categorizeApps(listOf(appInfo))
|
||||
|
||||
if (categorizedApps.isEmpty()) {
|
||||
// No category found, add directly to workspace
|
||||
ItemInstallQueue.INSTANCE.get(context).queueItem(packageName, user)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the category from flowerpot
|
||||
categorizedApps.entries.firstOrNull()?.key ?: run {
|
||||
ItemInstallQueue.INSTANCE.get(context).queueItem(packageName, user)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
val category = categoryEntry.key
|
||||
|
||||
// Check if there's already a folder for this category on workspace
|
||||
val existingFolder = findFolderByCategory(category, dataModel)
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package app.lawnchair.ui.preferences.destinations
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -44,6 +46,9 @@ import app.lawnchair.ui.preferences.components.layout.PreferenceGroup
|
||||
import app.lawnchair.ui.preferences.components.layout.PreferenceLayout
|
||||
import app.lawnchair.ui.preferences.navigation.HomeScreenGrid
|
||||
import app.lawnchair.util.collectAsStateBlocking
|
||||
import com.android.launcher3.Launcher
|
||||
import com.android.launcher3.LauncherAppState
|
||||
import com.android.launcher3.LauncherSettings
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.Utilities
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -60,6 +65,7 @@ fun HomeScreenPreferences(
|
||||
val prefs = preferenceManager()
|
||||
val prefs2 = preferenceManager2()
|
||||
val scope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
PreferenceLayout(
|
||||
label = stringResource(id = R.string.home_screen_label),
|
||||
backArrowVisible = !LocalIsExpandedScreen.current,
|
||||
@@ -101,6 +107,19 @@ fun HomeScreenPreferences(
|
||||
)
|
||||
}
|
||||
}
|
||||
PreferenceGroup(heading = stringResource(id = R.string.home_screen_actions)) {
|
||||
Item {
|
||||
ClickablePreference(
|
||||
label = stringResource(id = R.string.remove_all_views_from_home_screen),
|
||||
confirmationText = stringResource(id = R.string.remove_all_views_from_home_screen_desc),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
clearAllViewsFromHomeScreen(context)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
val feedAvailable = OverlayCallbackImpl.minusOneAvailable(LocalContext.current)
|
||||
val enableFeedAdapter = prefs2.enableFeed.getAdapter()
|
||||
PreferenceGroup(heading = stringResource(id = R.string.minus_one)) {
|
||||
@@ -275,6 +294,20 @@ fun HomeScreenPreferences(
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearAllViewsFromHomeScreen(context: Context) {
|
||||
val model = Launcher.getLauncher(context).modelWriter
|
||||
val isViewsRemoved = model.clearAllHomeScreenViewsByType(
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP,
|
||||
)
|
||||
if (isViewsRemoved) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.home_screen_all_views_removed_msg,
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HomeScreenTextColorPreference(
|
||||
modifier: Modifier = Modifier,
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*
|
||||
* Modifications copyright 2021, Lawnchair
|
||||
*/
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
||||
import static android.content.Context.RECEIVER_EXPORTED;
|
||||
|
||||
import static com.android.launcher3.Flags.enableSmartspaceRemovalToggle;
|
||||
import static com.android.launcher3.LauncherPrefs.ICON_STATE;
|
||||
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
|
||||
import static com.android.launcher3.model.LoaderTask.SMARTSPACE_ON_HOME_SCREEN;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
|
||||
import static com.android.launcher3.util.SettingsCache.PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.LauncherApps.ArchiveCompatibilityParams;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
import com.android.launcher3.graphics.IconShape;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.ModelLauncherCallbacks;
|
||||
import com.android.launcher3.notification.NotificationListener;
|
||||
import com.android.launcher3.pm.InstallSessionHelper;
|
||||
import com.android.launcher3.pm.InstallSessionTracker;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.util.LockedUserState;
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SafeCloseable;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.launcher3.util.SimpleBroadcastReceiver;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.widget.custom.CustomWidgetManager;
|
||||
|
||||
import app.lawnchair.LawnchairAppKt;
|
||||
import app.lawnchair.icons.LawnchairIconProvider;
|
||||
|
||||
public class LauncherAppState implements SafeCloseable {
|
||||
|
||||
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
|
||||
|
||||
// We do not need any synchronization for this variable as its only written on
|
||||
// UI thread.
|
||||
public static final MainThreadInitializedObject<LauncherAppState> INSTANCE = new MainThreadInitializedObject<LauncherAppState>(
|
||||
LauncherAppState::new) {
|
||||
@Override
|
||||
protected void onPostInit(Context context) {
|
||||
super.onPostInit(context);
|
||||
LawnchairAppKt.getLawnchairApp(context).onLauncherAppStateCreated();
|
||||
}
|
||||
};
|
||||
|
||||
private Launcher mLauncher;
|
||||
private final Context mContext;
|
||||
private final LauncherModel mModel;
|
||||
private final IconProvider mIconProvider;
|
||||
private final IconCache mIconCache;
|
||||
private final InvariantDeviceProfile mInvariantDeviceProfile;
|
||||
private boolean mIsSafeModeEnabled;
|
||||
|
||||
private final RunnableList mOnTerminateCallback = new RunnableList();
|
||||
|
||||
public static LauncherAppState getInstance(Context context) {
|
||||
return INSTANCE.get(context);
|
||||
}
|
||||
|
||||
public static LauncherAppState getInstanceNoCreate() {
|
||||
return INSTANCE.getNoCreate();
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
@SuppressWarnings("NewApi")
|
||||
public LauncherAppState(Context context) {
|
||||
this(context, LauncherFiles.APP_ICONS_DB);
|
||||
Log.v(Launcher.TAG, "LauncherAppState initiated");
|
||||
Preconditions.assertUIThread();
|
||||
|
||||
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
|
||||
() -> context.getPackageManager().isSafeMode());
|
||||
mInvariantDeviceProfile.addOnChangeListener(modelPropertiesChanged -> {
|
||||
if (modelPropertiesChanged) {
|
||||
refreshAndReloadLauncher();
|
||||
}
|
||||
});
|
||||
|
||||
ModelLauncherCallbacks callbacks = mModel.newModelCallbacks();
|
||||
LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
|
||||
launcherApps.registerCallback(callbacks);
|
||||
mOnTerminateCallback.add(() -> mContext.getSystemService(LauncherApps.class).unregisterCallback(callbacks));
|
||||
|
||||
if (BuildCompat.isAtLeastV() && Flags.enableSupportForArchiving()) {
|
||||
ArchiveCompatibilityParams params = new ArchiveCompatibilityParams();
|
||||
params.setEnableUnarchivalConfirmation(false);
|
||||
launcherApps.setArchiveCompatibility(params);
|
||||
}
|
||||
|
||||
SimpleBroadcastReceiver modelChangeReceiver = new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
|
||||
modelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
|
||||
ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
|
||||
|
||||
mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
|
||||
|
||||
SafeCloseable userChangeListener = UserCache.INSTANCE.get(mContext)
|
||||
.addUserEventListener(mModel::onUserEvent);
|
||||
mOnTerminateCallback.add(userChangeListener::close);
|
||||
|
||||
if (enableSmartspaceRemovalToggle()) {
|
||||
OnSharedPreferenceChangeListener firstPagePinnedItemListener = new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(
|
||||
SharedPreferences sharedPreferences, String key) {
|
||||
if (SMARTSPACE_ON_HOME_SCREEN.equals(key)) {
|
||||
mModel.forceReload();
|
||||
}
|
||||
}
|
||||
};
|
||||
LauncherPrefs.getPrefs(mContext).registerOnSharedPreferenceChangeListener(
|
||||
firstPagePinnedItemListener);
|
||||
mOnTerminateCallback.add(() -> LauncherPrefs.getPrefs(mContext)
|
||||
.unregisterOnSharedPreferenceChangeListener(firstPagePinnedItemListener));
|
||||
}
|
||||
|
||||
LockedUserState.get(context).runOnUserUnlocked(() -> {
|
||||
CustomWidgetManager cwm = CustomWidgetManager.INSTANCE.get(mContext);
|
||||
cwm.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
|
||||
mOnTerminateCallback.add(() -> cwm.setWidgetRefreshCallback(null));
|
||||
|
||||
IconObserver observer = new IconObserver();
|
||||
SafeCloseable iconChangeTracker = mIconProvider.registerIconChangeListener(
|
||||
observer, MODEL_EXECUTOR.getHandler());
|
||||
mOnTerminateCallback.add(iconChangeTracker::close);
|
||||
MODEL_EXECUTOR.execute(observer::verifyIconChanged);
|
||||
LauncherPrefs.get(context).addListener(observer, THEMED_ICONS);
|
||||
mOnTerminateCallback.add(
|
||||
() -> LauncherPrefs.get(mContext).removeListener(observer, THEMED_ICONS));
|
||||
|
||||
InstallSessionTracker installSessionTracker = InstallSessionHelper.INSTANCE.get(context)
|
||||
.registerInstallTracker(mModel);
|
||||
mOnTerminateCallback.add(installSessionTracker::unregister);
|
||||
});
|
||||
|
||||
// Register an observer to rebind the notification listener when dots are
|
||||
// re-enabled.
|
||||
SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext);
|
||||
SettingsCache.OnChangeListener notificationLister = this::onNotificationSettingsChanged;
|
||||
settingsCache.register(NOTIFICATION_BADGING_URI, notificationLister);
|
||||
onNotificationSettingsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
|
||||
mOnTerminateCallback.add(() -> settingsCache.unregister(NOTIFICATION_BADGING_URI, notificationLister));
|
||||
// Register an observer to notify Launcher about Private Space settings toggle.
|
||||
registerPrivateSpaceHideWhenLockListener(settingsCache);
|
||||
}
|
||||
|
||||
public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
|
||||
mContext = context;
|
||||
|
||||
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
|
||||
mIconProvider = new LawnchairIconProvider(context, Themes.isThemedIconEnabled(context));
|
||||
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
|
||||
iconCacheFileName, mIconProvider);
|
||||
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext),
|
||||
PackageManagerHelper.INSTANCE.get(context), iconCacheFileName != null);
|
||||
mOnTerminateCallback.add(mIconCache::close);
|
||||
mOnTerminateCallback.add(mModel::destroy);
|
||||
}
|
||||
|
||||
private void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
|
||||
if (areNotificationDotsEnabled) {
|
||||
NotificationListener.requestRebind(new ComponentName(
|
||||
mContext, NotificationListener.class));
|
||||
}
|
||||
}
|
||||
|
||||
private void registerPrivateSpaceHideWhenLockListener(SettingsCache settingsCache) {
|
||||
SettingsCache.OnChangeListener psHideWhenLockChangedListener = this::onPrivateSpaceHideWhenLockChanged;
|
||||
settingsCache.register(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, psHideWhenLockChangedListener);
|
||||
mOnTerminateCallback.add(() -> settingsCache.unregister(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI,
|
||||
psHideWhenLockChangedListener));
|
||||
}
|
||||
|
||||
private void onPrivateSpaceHideWhenLockChanged(boolean isPrivateSpaceHideOnLockEnabled) {
|
||||
mModel.forceReload();
|
||||
}
|
||||
|
||||
public void reloadIcons() {
|
||||
refreshAndReloadLauncher();
|
||||
}
|
||||
|
||||
public void clearAllViewsFromHomeScreen() {
|
||||
final boolean isViewsRemoved =
|
||||
mLauncher.getModelWriter().clearAllHomeScreenViewsByType(
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP);
|
||||
if (isViewsRemoved) {
|
||||
Toast.makeText(
|
||||
mLauncher,
|
||||
R.string.home_screen_all_views_removed_msg,
|
||||
Toast.LENGTH_SHORT
|
||||
).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshAndReloadLauncher() {
|
||||
LauncherIcons.clearPool(mContext);
|
||||
mIconCache.updateIconParams(
|
||||
mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
|
||||
mModel.forceReload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call from Application.onTerminate(), which is not guaranteed to ever be
|
||||
* called.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
mOnTerminateCallback.executeAllAndDestroy();
|
||||
}
|
||||
|
||||
public IconProvider getIconProvider() {
|
||||
return mIconProvider;
|
||||
}
|
||||
|
||||
public void setLauncher(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
public Launcher getLauncher() {
|
||||
return mLauncher;
|
||||
}
|
||||
|
||||
public IconCache getIconCache() {
|
||||
return mIconCache;
|
||||
}
|
||||
|
||||
public LauncherModel getModel() {
|
||||
return mModel;
|
||||
}
|
||||
|
||||
public InvariantDeviceProfile getInvariantDeviceProfile() {
|
||||
return mInvariantDeviceProfile;
|
||||
}
|
||||
|
||||
public boolean isSafeModeEnabled() {
|
||||
return mIsSafeModeEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for {@link #getInvariantDeviceProfile()}
|
||||
*/
|
||||
public static InvariantDeviceProfile getIDP(Context context) {
|
||||
return InvariantDeviceProfile.INSTANCE.get(context);
|
||||
}
|
||||
|
||||
private class IconObserver
|
||||
implements IconProvider.IconChangeListener, OnSharedPreferenceChangeListener {
|
||||
|
||||
@Override
|
||||
public void onAppIconChanged(String packageName, UserHandle user) {
|
||||
mModel.onAppIconChanged(packageName, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSystemIconStateChanged(String iconState) {
|
||||
IconShape.INSTANCE.get(mContext).pickBestShape(mContext);
|
||||
refreshAndReloadLauncher();
|
||||
LauncherPrefs.get(mContext).put(ICON_STATE, iconState);
|
||||
}
|
||||
|
||||
void verifyIconChanged() {
|
||||
String iconState = mIconProvider.getSystemIconState();
|
||||
if (!iconState.equals(LauncherPrefs.get(mContext).get(ICON_STATE))) {
|
||||
onSystemIconStateChanged(iconState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
if (Themes.KEY_THEMED_ICONS.equals(key)) {
|
||||
mIconProvider.setIconThemeSupported(Themes.isThemedIconEnabled(mContext));
|
||||
verifyIconChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
|
||||
import static com.android.launcher3.provider.LauncherDbUtils.itemIdMatch;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
@@ -153,6 +154,27 @@ public class ModelWriter {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all views from the home screen.
|
||||
*/
|
||||
public boolean clearAllHomeScreenViewsByType(int type) {
|
||||
final ArrayList<ItemInfo> itemsToRemove = new ArrayList<>();
|
||||
synchronized (mBgDataModel) {
|
||||
for (ItemInfo item : mBgDataModel.itemsIdMap) {
|
||||
if (item.container == type) {
|
||||
itemsToRemove.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToRemove.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
deleteItemsFromDatabase(itemsToRemove, "clearAllHomeScreenViewsByType");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item in the DB to a new <container, screen, cellX, cellY>
|
||||
|
||||
Reference in New Issue
Block a user