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

Commit e79790b2 authored by Jason Monk's avatar Jason Monk
Browse files

Speed up setting launch

Try to avoid too many calls to the PM and cache the info we get
from it to avoid too much stuff during settings launch.

Change-Id: I64132cbe47cf8eac6080c8c82583b0b5eeb75a28
parent ce890c32
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -74,6 +74,11 @@ public class DashboardTile implements Parcelable {
     */
    public int priority;

    /**
     * The metaData from the activity that defines this tile.
     */
    public Bundle metaData;

    public DashboardTile() {
        // Empty
    }
@@ -107,6 +112,7 @@ public class DashboardTile implements Parcelable {
        dest.writeBundle(extras);
        dest.writeString(category);
        dest.writeInt(priority);
        dest.writeBundle(metaData);
    }

    public void readFromParcel(Parcel in) {
@@ -125,6 +131,7 @@ public class DashboardTile implements Parcelable {
        extras = in.readBundle();
        category = in.readString();
        priority = in.readInt();
        metaData = in.readBundle();
    }

    DashboardTile(Parcel in) {
+80 −8
Original line number Diff line number Diff line
@@ -18,9 +18,15 @@ package com.android.settingslib.drawer;
import android.annotation.LayoutRes;
import android.annotation.Nullable;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -33,21 +39,30 @@ import android.widget.ListView;
import android.widget.Toolbar;
import com.android.settingslib.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class SettingsDrawerActivity extends Activity {

    protected static final boolean DEBUG_TIMING = false;
    private static final String TAG = "SettingsDrawerActivity";

    private static List<DashboardCategory> sDashboardCategories;
    private static HashMap<Pair<String, String>, DashboardTile> sTileCache;

    private final PackageReceiver mPackageReceiver = new PackageReceiver();
    private final List<CategoryListener> mCategoryListeners = new ArrayList<>();

    private SettingsDrawerAdapter mDrawerAdapter;
    // Hold on to a cache of tiles to avoid loading the info multiple times.
    private final HashMap<Pair<String, String>, DashboardTile> mTileCache = new HashMap<>();
    private List<DashboardCategory> mDashboardCategories;
    private DrawerLayout mDrawerLayout;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        long startTime = System.currentTimeMillis();

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.setContentView(R.layout.settings_with_drawer);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
@@ -62,6 +77,10 @@ public class SettingsDrawerActivity extends Activity {
            mDrawerLayout = null;
            return;
        }
        if (sDashboardCategories == null) {
            sTileCache = new HashMap<>();
            sDashboardCategories = TileUtils.getCategories(this, sTileCache);
        }
        setActionBar(toolbar);
        mDrawerAdapter = new SettingsDrawerAdapter(this);
        ListView listView = (ListView) findViewById(R.id.left_drawer);
@@ -72,6 +91,8 @@ public class SettingsDrawerActivity extends Activity {
                onTileClicked(mDrawerAdapter.getTile(position));
            };
        });
        if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
                + " ms");
    }

    @Override
@@ -88,7 +109,29 @@ public class SettingsDrawerActivity extends Activity {
    protected void onResume() {
        super.onResume();

        updateDrawer();
        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        filter.addDataScheme("package");
        registerReceiver(mPackageReceiver, filter);

        new CategoriesUpdater().execute();
    }

    @Override
    protected void onPause() {
        unregisterReceiver(mPackageReceiver);

        super.onPause();
    }

    public void addCategoryListener(CategoryListener listener) {
        mCategoryListeners.add(listener);
    }

    public void remCategoryListener(CategoryListener listener) {
        mCategoryListeners.remove(listener);
    }

    public void openDrawer() {
@@ -134,11 +177,16 @@ public class SettingsDrawerActivity extends Activity {
        }
    }

    public List<DashboardCategory> getDashboardCategories(boolean force) {
        if (force) {
            mDashboardCategories = TileUtils.getCategories(this, mTileCache);
    public List<DashboardCategory> getDashboardCategories() {
        return sDashboardCategories;
    }

    protected void onCategoriesChanged() {
        updateDrawer();
        final int N = mCategoryListeners.size();
        for (int i = 0; i < N; i++) {
            mCategoryListeners.get(i).onCategoriesChanged();
        }
        return mDashboardCategories;
    }

    public boolean openTile(DashboardTile tile) {
@@ -167,4 +215,28 @@ public class SettingsDrawerActivity extends Activity {
    public void onProfileTileOpen() {
        finish();
    }

    public interface CategoryListener {
        void onCategoriesChanged();
    }

    private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
        @Override
        protected List<DashboardCategory> doInBackground(Void... params) {
            return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
        }

        @Override
        protected void onPostExecute(List<DashboardCategory> dashboardCategories) {
            sDashboardCategories = dashboardCategories;
            onCategoriesChanged();
        }
    }

    private class PackageReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            new CategoriesUpdater().execute();
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public class SettingsDrawerAdapter extends BaseAdapter {
    }

    void updateCategories() {
        List<DashboardCategory> categories = mActivity.getDashboardCategories(true);
        List<DashboardCategory> categories = mActivity.getDashboardCategories();
        mItems.clear();
        for (int i = 0; i < categories.size(); i++) {
            Item category = new Item();
+49 −58
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
@@ -35,6 +36,7 @@ import java.util.Map;
public class TileUtils {

    private static final boolean DEBUG = false;
    private static final boolean DEBUG_TIMING = true;

    private static final String LOG_TAG = "TileUtils";

@@ -105,12 +107,9 @@ public class TileUtils {

    private static final String SETTING_PKG = "com.android.settings";

    public static List<DashboardCategory> getCategories(Context context) {
        return getCategories(context, new HashMap<Pair<String, String>, DashboardTile>());
    }

    public static List<DashboardCategory> getCategories(Context context,
            HashMap<Pair<String, String>, DashboardTile> cache) {
        final long startTime = System.currentTimeMillis();
        ArrayList<DashboardTile> tiles = new ArrayList<>();
        UserManager userManager = UserManager.get(context);
        for (UserHandle user : userManager.getUserProfiles()) {
@@ -143,6 +142,8 @@ public class TileUtils {
            Collections.sort(category.tiles, TILE_COMPARATOR);
        }
        Collections.sort(categories, CATEGORY_COMPARATOR);
        if (DEBUG_TIMING) Log.d(LOG_TAG, "getCategories took "
                + (System.currentTimeMillis() - startTime) + " ms");
        return categories;
    }

@@ -207,7 +208,9 @@ public class TileUtils {
                        activityInfo.packageName, activityInfo.name);
                tile.category = categoryKey;
                tile.priority = requireSettings ? resolved.priority : 0;
                updateTileData(context, tile);
                tile.metaData = activityInfo.metaData;
                updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
                        pm);
                if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);

                addedCache.put(key, tile);
@@ -231,19 +234,9 @@ public class TileUtils {
        return null;
    }

    private static boolean updateTileData(Context context, DashboardTile tile) {
        Intent intent = tile.intent;
        if (intent != null) {
            // Find the activity that is in the system image
            PackageManager pm = context.getPackageManager();
            List<ResolveInfo> list = tile.userHandle.size() != 0
                    ? pm.queryIntentActivitiesAsUser(intent, PackageManager.GET_META_DATA,
                            tile.userHandle.get(0).getIdentifier())
                    : pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
            int listSize = list.size();
            for (int i = 0; i < listSize; i++) {
                ResolveInfo resolveInfo = list.get(i);
                if (resolveInfo.activityInfo.applicationInfo.isSystemApp()) {
    private static boolean updateTileData(Context context, DashboardTile tile,
            ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm) {
        if (applicationInfo.isSystemApp()) {
            int icon = 0;
            CharSequence title = null;
            String summary = null;
@@ -251,8 +244,8 @@ public class TileUtils {
            // Get the activity's meta-data
            try {
                Resources res = pm.getResourcesForApplication(
                                resolveInfo.activityInfo.packageName);
                        Bundle metaData = resolveInfo.activityInfo.metaData;
                        applicationInfo.packageName);
                Bundle metaData = activityInfo.metaData;

                if (res != null && metaData != null) {
                    if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
@@ -272,24 +265,22 @@ public class TileUtils {
            // Set the preference title to the activity's label if no
            // meta-data is found
            if (TextUtils.isEmpty(title)) {
                        title = resolveInfo.loadLabel(pm).toString();
                title = activityInfo.loadLabel(pm).toString();
            }
            if (icon == 0) {
                        icon = resolveInfo.activityInfo.icon;
                icon = activityInfo.icon;
            }

            // Set icon, title and summary for the preference
                    tile.icon = Icon.createWithResource(resolveInfo.activityInfo.packageName, icon);
            tile.icon = Icon.createWithResource(activityInfo.packageName, icon);
            tile.title = title;
            tile.summary = summary;
            // Replace the intent with this specific activity
                    tile.intent = new Intent().setClassName(resolveInfo.activityInfo.packageName,
                            resolveInfo.activityInfo.name);
            tile.intent = new Intent().setClassName(activityInfo.packageName,
                    activityInfo.name);

            return true;
        }
            }
        }

        return false;
    }