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

Commit c8c6c4b1 authored by William Luh's avatar William Luh Committed by Android (Google) Code Review
Browse files

Merge "Query the security feature provider on separate threads."

parents 92033fdb 4f80f221
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;

import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.List;

import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
@@ -937,8 +939,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
                        MY_USER_ID));
            }
            if (mPowerButtonInstantlyLocks != null) {
                mPowerButtonInstantlyLocks.setChecked(mLockPatternUtils.getPowerButtonInstantlyLocks(
                        MY_USER_ID));
                mPowerButtonInstantlyLocks.setChecked(
                        mLockPatternUtils.getPowerButtonInstantlyLocks(MY_USER_ID));
            }

            updateOwnerInfo();
@@ -1202,9 +1204,18 @@ public class SecuritySettings extends SettingsPreferenceFragment
                    FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext);
            if (dashboardFeatureProvider.isEnabled()
                    && (packageVerifierState == PACKAGE_VERIFIER_STATE_ENABLED)) {
                // Calling the feature provider could potentially be slow, so do this on a separate
                // thread so as to not block the loading of Settings.
                Executors.newSingleThreadExecutor().execute(new Runnable() {
                    @Override
                    public void run() {
                        DashboardCategory dashboardCategory =
                        dashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY);
                mSummaryLoader.setSummary(this, getPackageVerifierSummary(dashboardCategory));
                                dashboardFeatureProvider.getTilesForCategory(
                                        CategoryKey.CATEGORY_SECURITY);
                        mSummaryLoader.setSummary(SummaryProvider.this,
                                getPackageVerifierSummary(dashboardCategory));
                    }
                });
            } else {
                final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(mContext);
                if (fpm != null && fpm.isHardwareDetected()) {
+48 −15
Original line number Diff line number Diff line
@@ -22,9 +22,12 @@ import android.content.IContentProvider;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import com.android.settings.trustagent.TrustAgentManager;
import com.android.settings.trustagent.TrustAgentManagerImpl;
import com.android.settingslib.drawer.DashboardCategory;
import android.support.annotation.VisibleForTesting;
import android.support.v4.content.ContextCompat;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
@@ -35,6 +38,7 @@ import android.util.Pair;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;

import java.util.concurrent.Executors;
import java.util.Map;

/** Implementation for {@code SecurityFeatureProvider}. */
@@ -43,8 +47,22 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
    private TrustAgentManager mTrustAgentManager;

    /** Update preferences with data from associated tiles. */
    public void updatePreferences(Context context, PreferenceScreen preferenceScreen,
    public void updatePreferences(final Context context, final PreferenceScreen preferenceScreen,
            final DashboardCategory dashboardCategory) {
        // Fetching the summary and icon from the provider introduces latency, so do this on a
        // separate thread.
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                updatePreferencesToRunOnWorkerThread(context, preferenceScreen, dashboardCategory);
            }
        });
    }

    @VisibleForTesting
    void updatePreferencesToRunOnWorkerThread(Context context, PreferenceScreen preferenceScreen,
            DashboardCategory dashboardCategory) {

        if (preferenceScreen == null) {
            return;
        }
@@ -82,18 +100,31 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
                        TileUtils.getIconFromUri(context, packageName, iconUri, providerMap);
                if (icon != null) {
                    // Icon is only returned if the icon belongs to Settings or the target app.
                    // setIcon must be called on the UI thread.
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                matchingPref.setIcon(context.getPackageManager()
                                        .getResourcesForApplication(icon.first /* package name */)
                                        .getDrawable(icon.second /* res id */, context.getTheme()));
                    } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
                        // Intentionally ignored. If icon resources cannot be found, do not update.
                                                .getDrawable(icon.second /* res id */,
                                                        context.getTheme()));
                            } catch (PackageManager.NameNotFoundException
                                    | Resources.NotFoundException e) {
                                // Intentionally ignored. If icon resources cannot be found, do not
                                // update.
                            }
                        }
                    });
                }
            }
            if (!TextUtils.isEmpty(summaryUri)) {
                String summary = TileUtils.getTextFromUri(context, summaryUri, providerMap,
                        TileUtils.META_DATA_PREFERENCE_SUMMARY);
                // setSummary must be called on UI thread.
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        // Only update the summary if it has actually changed.
                        if (summary == null) {
                            if (matchingPref.getSummary() != null) {
@@ -103,6 +134,8 @@ public class SecurityFeatureProviderImpl implements SecurityFeatureProvider {
                            matchingPref.setSummary(summary);
                        }
                    }
                });
            }
        }
    }

+16 −6
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowLooper;

import java.util.Map;

@@ -102,8 +103,11 @@ public class SecurityFeatureProviderImplTest {

    @Test
    public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() {
        mImpl.updatePreferences(mContext, null, null);
        mImpl.updatePreferences(mContext, new PreferenceScreen(mContext, null), null);
        mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null);
        ShadowLooper.runUiThreadTasks();
        mImpl.updatePreferencesToRunOnWorkerThread(
                mContext, new PreferenceScreen(mContext, null), null);
        ShadowLooper.runUiThreadTasks();
        verifyNoMoreInteractions(mPackageManager);
    }

@@ -111,13 +115,17 @@ public class SecurityFeatureProviderImplTest {
    public void updateTilesData_shouldNotProcessNonMatchingPreference() {
        DashboardCategory dashboardCategory = new DashboardCategory();
        dashboardCategory.addTile(new Tile());
        mImpl.updatePreferences(mContext, getPreferenceScreen(), dashboardCategory);
        mImpl.updatePreferencesToRunOnWorkerThread(
                mContext, getPreferenceScreen(), dashboardCategory);
        ShadowLooper.runUiThreadTasks();
        verifyNoMoreInteractions(mPackageManager);
    }

    @Test
    public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() {
        mImpl.updatePreferences(mContext, getPreferenceScreen(), getDashboardCategory());
        mImpl.updatePreferencesToRunOnWorkerThread(
                mContext, getPreferenceScreen(), getDashboardCategory());
        ShadowLooper.runUiThreadTasks();
        verifyNoMoreInteractions(mPackageManager);
    }

@@ -135,7 +143,8 @@ public class SecurityFeatureProviderImplTest {
        dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
        dashboardCategory.getTile(0).metaData = bundle;

        mImpl.updatePreferences(mContext, screen, dashboardCategory);
        mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
        ShadowLooper.runUiThreadTasks();
        verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
        verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
    }
@@ -157,7 +166,8 @@ public class SecurityFeatureProviderImplTest {
        dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
        dashboardCategory.getTile(0).metaData = bundle;

        mImpl.updatePreferences(mContext, screen, dashboardCategory);
        mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
        ShadowLooper.runUiThreadTasks();
        verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString());
    }