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

Commit 071aa6b8 authored by Doris Ling's avatar Doris Ling Committed by android-build-merger
Browse files

Merge "Change AppPrefLoader from AsyncTask to AsyncLoader." into oc-dev

am: d821a32b

Change-Id: If0208dec8535fe72b14f73f42eb56ecfd7c9d2f7
parents 2fdb4591 d821a32b
Loading
Loading
Loading
Loading
+20 −41
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.net.NetworkPolicy;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -56,11 +55,6 @@ import com.android.settingslib.net.ChartDataLoader;
import com.android.settingslib.net.UidDetail;
import com.android.settingslib.net.UidDetailProvider;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener,
        DataSaverBackend.Listener {

@@ -79,6 +73,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
    private static final String KEY_UNRESTRICTED_DATA = "unrestricted_data_saver";

    private static final int LOADER_CHART_DATA = 2;
    private static final int LOADER_APP_PREF = 3;

    private final ArraySet<String> mPackages = new ArraySet<>();
    private Preference mTotalUsage;
@@ -105,12 +100,6 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
    private SwitchPreference mUnrestrictedData;
    private DataSaverBackend mDataSaverBackend;

    // Parameters to construct an efficient ThreadPoolExecutor
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
@@ -197,14 +186,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen

            if (mPackages.size() > 1) {
                mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST);
                final int packageSize = mPackages.size();
                final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(packageSize);
                final ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_POOL_SIZE,
                        MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, workQueue);
                for (int i = 1; i < mPackages.size(); i++) {
                    final AppPrefLoader loader = new AppPrefLoader();
                        loader.executeOnExecutor(executor, mPackages.valueAt(i));
                }
                getLoaderManager().initLoader(LOADER_APP_PREF, Bundle.EMPTY, mAppPrefCallbacks);
            } else {
                removePreference(KEY_APP_LIST);
            }
@@ -399,31 +381,28 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
        }
    };

    private class AppPrefLoader extends AsyncTask<String, Void, Preference> {
    private final LoaderManager.LoaderCallbacks<ArraySet<Preference>> mAppPrefCallbacks =
        new LoaderManager.LoaderCallbacks<ArraySet<Preference>>() {
            @Override
        protected Preference doInBackground(String... params) {
            PackageManager pm = getPackageManager();
            String pkg = params[0];
            try {
                ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
                Preference preference = new Preference(getPrefContext());
                preference.setIcon(info.loadIcon(pm));
                preference.setTitle(info.loadLabel(pm));
                preference.setSelectable(false);
                return preference;
            } catch (PackageManager.NameNotFoundException e) {
            }
            return null;
            public Loader<ArraySet<Preference>> onCreateLoader(int i, Bundle bundle) {
                return new AppPrefLoader(getPrefContext(), mPackages, getPackageManager());
            }

            @Override
        protected void onPostExecute(Preference pref) {
            if (pref != null && mAppList != null) {
                mAppList.addPreference(pref);
            public void onLoadFinished(Loader<ArraySet<Preference>> loader,
                    ArraySet<Preference> preferences) {
                if (preferences != null && mAppList != null) {
                    for (Preference preference : preferences) {
                        mAppList.addPreference(preference);
                    }
                }
            }

            @Override
            public void onLoaderReset(Loader<ArraySet<Preference>> loader) {
            }
        };

    @Override
    public void onDataSaverChanged(boolean isDataSaving) {

+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.datausage;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.support.v7.preference.Preference;
import android.util.ArraySet;
import com.android.settings.utils.AsyncLoader;

public class AppPrefLoader extends AsyncLoader<ArraySet<Preference>> {
    private ArraySet<String> mPackages;
    private PackageManager mPackageManager;
    private Context mPrefContext;

    public AppPrefLoader(Context prefContext, ArraySet<String> pkgs, PackageManager pm) {
        super(prefContext);
        mPackages = pkgs;
        mPackageManager = pm;
        mPrefContext = prefContext;
    }

    @Override
    public ArraySet<Preference> loadInBackground() {
        ArraySet<Preference> results = new ArraySet<>();
        for (int i = 1, size = mPackages.size(); i < size; i++) {
            try {
                ApplicationInfo info = mPackageManager.getApplicationInfo(mPackages.valueAt(i), 0);
                Preference preference = new Preference(mPrefContext);
                preference.setIcon(info.loadIcon(mPackageManager));
                preference.setTitle(info.loadLabel(mPackageManager));
                preference.setSelectable(false);
                results.add(preference);
            } catch (PackageManager.NameNotFoundException e) {
            }
        }
        return results;
    }

    @Override
    protected void onDiscardResult(ArraySet<Preference> result) {
    }
}
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.datausage;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.support.v7.preference.Preference;

import android.util.ArraySet;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;


@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AppPrefLoaderTest {

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Context mContext;
    @Mock
    private PackageManager mPackageManager;

    private AppPrefLoader mLoader;


    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        final ArraySet<String> pkgs = new ArraySet<>();
        pkgs.add("pkg0");
        pkgs.add("pkg1");
        mLoader =
            new AppPrefLoader(RuntimeEnvironment.application, pkgs, mPackageManager);
    }

    @Test
    public void loadInBackground_packageNotFound_shouldReturnEmptySet()
            throws NameNotFoundException {
        when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
            .thenThrow(new NameNotFoundException());

        ArraySet<Preference> preferences = mLoader.loadInBackground();
        assertThat(preferences).isEmpty();
    }

    @Test
    public void loadInBackground_shouldReturnPreference() throws NameNotFoundException {
        ApplicationInfo info = mock(ApplicationInfo.class);
        when(mPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(info);
        final Drawable drawable = mock(Drawable.class);
        final String label = "Label1";
        when(info.loadIcon(mPackageManager)).thenReturn(drawable);
        when(info.loadLabel(mPackageManager)).thenReturn(label);

        Preference preference = mLoader.loadInBackground().valueAt(0);
        assertThat(preference.getTitle()).isEqualTo(label);
        assertThat(preference.getIcon()).isEqualTo(drawable);
        assertThat(preference.isSelectable()).isFalse();
    }

}