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

Commit 290ca6ec authored by Jason Monk's avatar Jason Monk
Browse files

Don't use ApplicationsState for summaries

Since it grabs a lock that can be slow on the main thread, don't use
ApplicationsState in any of the summaries, instead load the information
directly from the PM.

Change-Id: Ibefe867810d2a9926177a8de4e23a7faea4b1c3b
Fixes: 28435146
parent 77ad3c25
Loading
Loading
Loading
Loading
+70 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

package com.android.settings.applications;

import android.app.AppGlobals;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
import android.os.AsyncTask;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;

public abstract class AppCounter extends AsyncTask<Void, Void, Integer> {

    protected final PackageManager mPm;
    protected final IPackageManager mIpm;
    protected final UserManager mUm;

    public AppCounter(Context context) {
        mPm = context.getPackageManager();
        mIpm = AppGlobals.getPackageManager();
        mUm = UserManager.get(context);
    }

    @Override
    protected Integer doInBackground(Void... params) {
        int count = 0;
        for (UserInfo user : mUm.getProfiles(UserHandle.myUserId())) {
            try {
                @SuppressWarnings("unchecked")
                ParceledListSlice<ApplicationInfo> list =
                        mIpm.getInstalledApplications(PackageManager.GET_DISABLED_COMPONENTS
                                | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS
                                | (user.isAdmin() ? PackageManager.GET_UNINSTALLED_PACKAGES : 0),
                                user.id);
                for (ApplicationInfo info : list.getList()) {
                    if (includeInCount(info)) {
                        count++;
                    }
                }
            } catch (RemoteException e) {
            }
        }
        return count;
    }

    @Override
    protected void onPostExecute(Integer count) {
        onCountComplete(count);
    }

    protected abstract void onCountComplete(int num);
    protected abstract boolean includeInCount(ApplicationInfo info);
}
+36 −67
Original line number Diff line number Diff line
@@ -17,14 +17,18 @@
package com.android.settings.applications;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.icu.text.AlphabeticIndex;
import android.os.*;
import android.os.Bundle;
import android.os.Environment;
import android.os.LocaleList;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.PreferenceFrameLayout;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -49,7 +53,6 @@ import android.widget.SectionIndexer;
import android.widget.Spinner;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.AppHeader;
import com.android.settingslib.HelpUtils;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.Settings.AllApplicationsActivity;
@@ -71,6 +74,7 @@ import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.NotificationBackend.AppRow;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
@@ -80,6 +84,7 @@ import com.android.settingslib.applications.ApplicationsState.VolumeFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

/**
@@ -1248,84 +1253,48 @@ public class ManageApplications extends InstrumentedFragment
        }
    }

    private static class SummaryProvider implements SummaryLoader.SummaryProvider,
            ApplicationsState.Callbacks {
    private static class SummaryProvider implements SummaryLoader.SummaryProvider {

        private final Context mContext;
        private final SummaryLoader mLoader;
        // TODO: Can probably hack together with less than full app state.
        private final ApplicationsState mAppState;
        private final Handler mHandler;
        private ApplicationsState.Session mSession;

        private SummaryProvider(Context context, SummaryLoader loader) {
            mContext = context;
            mLoader = loader;
            mAppState =
                    ApplicationsState.getInstance((Application) context.getApplicationContext());
            mHandler = new Handler(mAppState.getBackgroundLooper());
        }

        @Override
        public void setListening(boolean listening) {
            if (listening) {
                mSession = mAppState.newSession(this);
                mSession.resume();
            } else {
                mSession.pause();
                mSession.release();
            }
        }

        private void updateSummary(ArrayList<AppEntry> apps) {
            if (apps == null) return;
            mLoader.setSummary(this, mContext.getString(R.string.apps_summary, apps.size()));
        }

        private void postRebuild() {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateSummary(mSession.rebuild(ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER,
                            null, false));
                }
            });
        }

                new AppCounter(mContext) {
                    @Override
        public void onRebuildComplete(ArrayList<AppEntry> apps) {
            updateSummary(apps);
                    protected void onCountComplete(int num) {
                        mLoader.setSummary(SummaryProvider.this,
                                mContext.getString(R.string.apps_summary, num));
                    }

                    @Override
        public void onPackageListChanged() {
            postRebuild();
        }

        @Override
        public void onLauncherInfoChanged() {
            postRebuild();
                    protected boolean includeInCount(ApplicationInfo info) {
                        if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                            return true;
                        } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                            return true;
                        }

        @Override
        public void onLoadEntriesCompleted() {
            postRebuild();
                        Intent launchIntent = new Intent(Intent.ACTION_MAIN, null)
                                .addCategory(Intent.CATEGORY_LAUNCHER)
                                .setPackage(info.packageName);
                        int userId = UserHandle.getUserId(info.uid);
                        List<ResolveInfo> intents = mPm.queryIntentActivitiesAsUser(
                                launchIntent,
                                PackageManager.GET_DISABLED_COMPONENTS
                                        | PackageManager.MATCH_DIRECT_BOOT_AWARE
                                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                                userId);
                        return intents != null && intents.size() != 0;
                    }

        @Override
        public void onRunningStateChanged(boolean running) {
                }.execute();
            }

        @Override
        public void onPackageIconChanged() {
        }

        @Override
        public void onPackageSizeChanged(String packageName) {
        }

        @Override
        public void onAllSizesComputed() {
        }
    }

+19 −80
Original line number Diff line number Diff line
@@ -15,19 +15,11 @@
package com.android.settings.applications;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.content.pm.ApplicationInfo;
import com.android.settings.R;
import com.android.settings.applications.AppStateBaseBridge.Callback;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.dashboard.SummaryLoader.SummaryProvider;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.Callbacks;

import java.util.ArrayList;

/**
 * Extension of ManageApplications with no changes other than having its own
@@ -35,96 +27,43 @@ import java.util.ArrayList;
 */
public class NotificationApps extends ManageApplications {

    private static class SummaryProvider implements SummaryLoader.SummaryProvider,
            Callbacks, Callback {
    private static class SummaryProvider implements SummaryLoader.SummaryProvider {

        private final Context mContext;
        private final SummaryLoader mLoader;

        private final ApplicationsState mAppState;
        private final NotificationBackend mNotifBackend;
        private final Handler mHandler;
        private AppStateNotificationBridge mExtraInfoBridge;
        private ApplicationsState.Session mSession;
        private final NotificationBackend mNotificationBackend;

        private SummaryProvider(Context context, SummaryLoader loader) {
            mContext = context;
            mLoader = loader;
            mAppState =
                    ApplicationsState.getInstance((Application) context.getApplicationContext());
            mNotifBackend = new NotificationBackend();
            mHandler = new Handler(mAppState.getBackgroundLooper());
            mNotificationBackend = new NotificationBackend();
        }

        @Override
        public void setListening(boolean listening) {
            if (listening) {
                mSession = mAppState.newSession(this);
                mExtraInfoBridge = new AppStateNotificationBridge(mContext,
                        mAppState, this, mNotifBackend);
                mSession.resume();
                mExtraInfoBridge.resume();
            } else {
                mSession.pause();
                mExtraInfoBridge.pause();
                mSession.release();
                mExtraInfoBridge.release();
            }
        }

        private void updateSummary(ArrayList<AppEntry> apps) {
            if (apps == null) return;
            if (apps.size() == 0) {
                mLoader.setSummary(this, mContext.getString(R.string.notification_summary_none));
            } else {
                mLoader.setSummary(this, mContext.getResources().getQuantityString(
                        R.plurals.notification_summary, apps.size(), apps.size()));
            }
        }

                new AppCounter(mContext) {
                    @Override
        public void onRebuildComplete(ArrayList<AppEntry> apps) {
            updateSummary(apps);
                    protected void onCountComplete(int num) {
                        updateSummary(num);
                    }

                    @Override
        public void onExtraInfoUpdated() {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    updateSummary(mSession.rebuild(
                            AppStateNotificationBridge.FILTER_APP_NOTIFICATION_BLOCKED,
                            null, false));
                    protected boolean includeInCount(ApplicationInfo info) {
                        return mNotificationBackend.getNotificationsBanned(info.packageName,
                                info.uid);
                    }
            });
                }.execute();
            }

        @Override
        public void onPackageListChanged() {
        }

        @Override
        public void onLauncherInfoChanged() {
        }

        @Override
        public void onLoadEntriesCompleted() {
        }

        @Override
        public void onRunningStateChanged(boolean running) {
        }

        @Override
        public void onPackageIconChanged() {
        }

        @Override
        public void onPackageSizeChanged(String packageName) {
        private void updateSummary(int count) {
            if (count == 0) {
                mLoader.setSummary(this, mContext.getString(R.string.notification_summary_none));
            } else {
                mLoader.setSummary(this, mContext.getResources().getQuantityString(
                        R.plurals.notification_summary, count, count));
            }

        @Override
        public void onAllSizesComputed() {
        }
    }