Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d164b7f4 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fixing static instance of Indexer being created in the model

Indexer depends on the locale and should be created when ever the config
changes. Moving the widget indexing to the adapter (similar to allApps)
which gets created whenever the activity is recreated.
This fixes the bug where widgets indexing breaks if locale changes while launcher
process is alive
Also fixing the bug in widget model cloning where the HashMap was not cloning
the underlying ArrayList

Change-Id: I7dbe6290e73299c4c07aa7fa564077a2649e1a4c
parent 67115b1a
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -103,7 +103,8 @@ import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.DeepShortcutsContainer;
@@ -229,7 +230,7 @@ public class Launcher extends Activity

    // Main container view and the model for the widget tray screen.
    @Thunk WidgetsContainerView mWidgetsView;
    @Thunk WidgetsModel mWidgetsModel;
    @Thunk MultiHashMap<PackageItemInfo, WidgetItem> mAllWidgets;

    // We set the state in both onCreate and then onNewIntent in some cases, which causes both
    // scroll issues (because the workspace may not have been measured yet) and extra work.
@@ -3836,22 +3837,22 @@ public class Launcher extends Activity
        }
    }

    private Runnable mBindWidgetModelRunnable = new Runnable() {
    private Runnable mBindAllWidgetsRunnable = new Runnable() {
            public void run() {
                bindWidgetsModel(mWidgetsModel);
                bindAllWidgets(mAllWidgets);
            }
        };

    @Override
    public void bindWidgetsModel(WidgetsModel model) {
        if (waitUntilResume(mBindWidgetModelRunnable, true)) {
            mWidgetsModel = model;
    public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> allWidgets) {
        if (waitUntilResume(mBindAllWidgetsRunnable, true)) {
            mAllWidgets = allWidgets;
            return;
        }

        if (mWidgetsView != null && model != null) {
            mWidgetsView.addWidgets(model);
            mWidgetsModel = null;
        if (mWidgetsView != null && allWidgets != null) {
            mWidgetsView.setWidgets(allWidgets);
            mAllWidgets = null;
        }
    }

+13 −9
Original line number Diff line number Diff line
@@ -61,7 +61,9 @@ import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.SdCardAvailableReceiver;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.provider.ImportDataTask;
import com.android.launcher3.provider.LauncherDbUtils;
@@ -198,7 +200,7 @@ public class LauncherModel extends BroadcastReceiver
                UserHandleCompat user);
        public void bindAppInfosRemoved(ArrayList<AppInfo> appInfos);
        public void notifyWidgetProvidersChanged();
        public void bindWidgetsModel(WidgetsModel model);
        public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets);
        public void onPageBoundSynchronously(int page);
        public void executeOnNextDraw(ViewOnDrawExecutor executor);
        public void bindDeepShortcutMap(MultiHashMap<ComponentKey, String> deepShortcutMap);
@@ -209,7 +211,7 @@ public class LauncherModel extends BroadcastReceiver
        Context context = app.getContext();
        mApp = app;
        mBgAllAppsList = new AllAppsList(iconCache, appFilter);
        mBgWidgetsModel = new WidgetsModel(context, iconCache, appFilter);
        mBgWidgetsModel = new WidgetsModel(iconCache, appFilter);
        mIconCache = iconCache;
        mDeepShortcutManager = deepShortcutManager;

@@ -3263,13 +3265,15 @@ public class LauncherModel extends BroadcastReceiver
        }
    }

    private void bindWidgetsModel(final Callbacks callbacks, final WidgetsModel model) {
    private void bindWidgetsModel(final Callbacks callbacks) {
        final MultiHashMap<PackageItemInfo, WidgetItem> widgets
                = mBgWidgetsModel.getWidgetsMap().clone();
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Callbacks cb = getCallback();
                if (callbacks == cb && cb != null) {
                    callbacks.bindWidgetsModel(model);
                    callbacks.bindAllWidgets(widgets);
                }
            }
        });
@@ -3281,13 +3285,13 @@ public class LauncherModel extends BroadcastReceiver
            @Override
            public void run() {
                if (bindFirst && !mBgWidgetsModel.isEmpty()) {
                    bindWidgetsModel(callbacks, mBgWidgetsModel.clone());
                    bindWidgetsModel(callbacks);
                }
                final WidgetsModel model = mBgWidgetsModel.updateAndClone(mApp.getContext());
                bindWidgetsModel(callbacks, model);
                ArrayList<WidgetItem> allWidgets = mBgWidgetsModel.update(mApp.getContext());
                bindWidgetsModel(callbacks);

                // update the Widget entries inside DB on the worker thread.
                LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(
                        model.getRawList());
                LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews(allWidgets);
            }
        });
    }
+8 −12
Original line number Diff line number Diff line
@@ -23,8 +23,8 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;
import com.android.launcher3.model.AppNameComparator;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LabelComparator;

import java.util.ArrayList;
import java.util.Collections;
@@ -163,7 +163,7 @@ public class AlphabeticalAppsList {
    private HashMap<CharSequence, String> mCachedSectionNames = new HashMap<>();
    private AllAppsGridAdapter mAdapter;
    private AlphabeticIndexCompat mIndexer;
    private AppNameComparator mAppNameComparator;
    private AppInfoComparator mAppNameComparator;
    private int mNumAppsPerRow;
    private int mNumPredictedAppsPerRow;
    private int mNumAppRowsInAdapter;
@@ -171,7 +171,7 @@ public class AlphabeticalAppsList {
    public AlphabeticalAppsList(Context context) {
        mLauncher = Launcher.getLauncher(context);
        mIndexer = new AlphabeticIndexCompat(context);
        mAppNameComparator = new AppNameComparator(context);
        mAppNameComparator = new AppInfoComparator(context);
    }

    /**
@@ -305,17 +305,16 @@ public class AlphabeticalAppsList {
        // Sort the list of apps
        mApps.clear();
        mApps.addAll(mComponentToAppMap.values());
        Collections.sort(mApps, mAppNameComparator.getAppInfoComparator());
        Collections.sort(mApps, mAppNameComparator);

        // As a special case for some languages (currently only Simplified Chinese), we may need to
        // coalesce sections
        Locale curLocale = mLauncher.getResources().getConfiguration().locale;
        TreeMap<String, ArrayList<AppInfo>> sectionMap = null;
        boolean localeRequiresSectionSorting = curLocale.equals(Locale.SIMPLIFIED_CHINESE);
        if (localeRequiresSectionSorting) {
            // Compute the section headers. We use a TreeMap with the section name comparator to
            // ensure that the sections are ordered when we iterate over it later
            sectionMap = new TreeMap<>(mAppNameComparator.getSectionNameComparator());
            TreeMap<String, ArrayList<AppInfo>> sectionMap = new TreeMap<>(new LabelComparator());
            for (AppInfo info : mApps) {
                // Add the section to the cache
                String sectionName = getAndUpdateCachedSectionName(info.title);
@@ -330,13 +329,10 @@ public class AlphabeticalAppsList {
            }

            // Add each of the section apps to the list in order
            List<AppInfo> allApps = new ArrayList<>(mApps.size());
            mApps.clear();
            for (Map.Entry<String, ArrayList<AppInfo>> entry : sectionMap.entrySet()) {
                allApps.addAll(entry.getValue());
                mApps.addAll(entry.getValue());
            }

            mApps.clear();
            mApps.addAll(allApps);
        } else {
            // Just compute the section headers for use below
            for (AppInfo info : mApps) {
+23 −8
Original line number Diff line number Diff line
@@ -13,36 +13,51 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.launcher3.model;
package com.android.launcher3.allapps;

import android.content.Context;

import com.android.launcher3.ItemInfo;
import com.android.launcher3.AppInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.util.LabelComparator;

import java.util.Comparator;

/**
 * A comparator to arrange items based on user profiles.
 */
public abstract class AbstractUserComparator<T extends ItemInfo> implements Comparator<T> {
public class AppInfoComparator implements Comparator<AppInfo> {

    private final UserManagerCompat mUserManager;
    private final UserHandleCompat mMyUser;
    private final LabelComparator mLabelComparator;

    public AbstractUserComparator(Context context) {
    public AppInfoComparator(Context context) {
        mUserManager = UserManagerCompat.getInstance(context);
        mMyUser = UserHandleCompat.myUserHandle();
        mLabelComparator = new LabelComparator();
    }

    @Override
    public int compare(T lhs, T rhs) {
        if (mMyUser.equals(lhs.user)) {
    public int compare(AppInfo a, AppInfo b) {
        // Order by the title in the current locale
        int result = mLabelComparator.compare(a.title.toString(), b.title.toString());
        if (result != 0) {
            return result;
        }

        // If labels are same, compare component names
        result = a.componentName.compareTo(b.componentName);
        if (result != 0) {
            return result;
        }

        if (mMyUser.equals(a.user)) {
            return -1;
        } else {
            Long aUserSerial = mUserManager.getSerialNumberForUser(lhs.user);
            Long bUserSerial = mUserManager.getSerialNumberForUser(rhs.user);
            Long aUserSerial = mUserManager.getSerialNumberForUser(a.user);
            Long bUserSerial = mUserManager.getSerialNumberForUser(b.user);
            return aUserSerial.compareTo(bUserSerial);
        }
    }
+0 −6
Original line number Diff line number Diff line
@@ -40,12 +40,6 @@ public class PackageItemInfo extends ItemInfo {
     */
    public String packageName;

    /**
     * Character that is used as a section name for the {@link ItemInfo#title}.
     * (e.g., "G" will be stored if title is "Google")
     */
    public String titleSectionName;

    PackageItemInfo(String packageName) {
        this.packageName = packageName;
    }
Loading