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

Commit d821a32b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 0036ef2c 2f022184
Loading
Loading
Loading
Loading
+20 −41
Original line number Original line Diff line number Diff line
@@ -30,7 +30,6 @@ import android.net.NetworkPolicy;
import android.net.NetworkStatsHistory;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.net.TrafficStats;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
@@ -55,11 +54,6 @@ import com.android.settingslib.net.ChartData;
import com.android.settingslib.net.ChartDataLoader;
import com.android.settingslib.net.ChartDataLoader;
import com.android.settingslib.net.UidDetailProvider;
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,
public class AppDataUsage extends DataUsageBase implements Preference.OnPreferenceChangeListener,
        DataSaverBackend.Listener {
        DataSaverBackend.Listener {


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


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


    private final ArraySet<String> mPackages = new ArraySet<>();
    private final ArraySet<String> mPackages = new ArraySet<>();
    private Preference mTotalUsage;
    private Preference mTotalUsage;
@@ -104,12 +99,6 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
    private SwitchPreference mUnrestrictedData;
    private SwitchPreference mUnrestrictedData;
    private DataSaverBackend mDataSaverBackend;
    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
    @Override
    public void onCreate(Bundle icicle) {
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        super.onCreate(icicle);
@@ -196,14 +185,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen


            if (mPackages.size() > 1) {
            if (mPackages.size() > 1) {
                mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST);
                mAppList = (PreferenceCategory) findPreference(KEY_APP_LIST);
                final int packageSize = mPackages.size();
                getLoaderManager().initLoader(LOADER_APP_PREF, Bundle.EMPTY, mAppPrefCallbacks);
                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));
                }
            } else {
            } else {
                removePreference(KEY_APP_LIST);
                removePreference(KEY_APP_LIST);
            }
            }
@@ -408,31 +390,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
            @Override
        protected Preference doInBackground(String... params) {
            public Loader<ArraySet<Preference>> onCreateLoader(int i, Bundle bundle) {
            PackageManager pm = getPackageManager();
                return new AppPrefLoader(getPrefContext(), mPackages, 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;
            }
            }


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


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

    @Override
    @Override
    public void onDataSaverChanged(boolean isDataSaving) {
    public void onDataSaverChanged(boolean isDataSaving) {


+58 −0
Original line number Original line 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 Original line 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();
    }

}