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

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

Merge "Fix race condition and optimize categoryUpdater refresh"

parents aadd26e3 aeb94f0e
Loading
Loading
Loading
Loading
+55 −35
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import android.support.v7.preference.PreferenceManager;
import android.text.TextUtils;
import android.transition.TransitionManager;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@@ -64,7 +63,6 @@ import com.android.settings.development.DevelopmentSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DynamicIndexableContentMonitor;
import com.android.settings.search.SearchActivity;
import com.android.settings.search.SearchFeatureProvider;
import com.android.settings.wfd.WifiDisplaySettings;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.drawer.DashboardCategory;
@@ -770,68 +768,81 @@ public class SettingsActivity extends SettingsDrawerActivity
        PackageManager pm = getPackageManager();
        final UserManager um = UserManager.get(this);
        final boolean isAdmin = um.isAdminUser();

        boolean somethingChanged = false;
        String packageName = getPackageName();
        setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin);
        somethingChanged = setTileEnabled(
                new ComponentName(packageName, WifiSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin) || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.BluetoothSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin);
                pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.DataUsageSummaryActivity.class.getName()),
                Utils.isBandwidthControlEnabled(), isAdmin);
                Utils.isBandwidthControlEnabled(), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.SimSettingsActivity.class.getName()),
                Utils.showSimCardTile(this), isAdmin);
                Utils.showSimCardTile(this), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.PowerUsageSummaryActivity.class.getName()),
                mBatteryPresent, isAdmin);
                mBatteryPresent, isAdmin) || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.UserSettingsActivity.class.getName()),
                UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
                        && !Utils.isMonkeyRunning(), isAdmin);
                        && !Utils.isMonkeyRunning(), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.NetworkDashboardActivity.class.getName()),
                !UserManager.isDeviceInDemoMode(this), isAdmin);
                !UserManager.isDeviceInDemoMode(this), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.ConnectedDeviceDashboardActivity.class.getName()),
                !UserManager.isDeviceInDemoMode(this), isAdmin);
                !UserManager.isDeviceInDemoMode(this), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.DateTimeSettingsActivity.class.getName()),
                !UserManager.isDeviceInDemoMode(this), isAdmin);
                !UserManager.isDeviceInDemoMode(this), isAdmin)
                || somethingChanged;
        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.PaymentSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_NFC)
                        && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
                        && adapter != null && adapter.isEnabled(), isAdmin);
                        && adapter != null && adapter.isEnabled(), isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.PrintSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin);
                pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin)
                || somethingChanged;

        final boolean showDev = mDevelopmentPreferences.getBoolean(
                DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
                && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.DevelopmentSettingsActivity.class.getName()),
                showDev, isAdmin);
                showDev, isAdmin)
                || somethingChanged;

        // Enable/disable backup settings depending on whether the user is admin.
        setTileEnabled(new ComponentName(packageName,
                        BackupSettingsActivity.class.getName()), true, isAdmin);
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                BackupSettingsActivity.class.getName()), true, isAdmin)
                || somethingChanged;

        setTileEnabled(new ComponentName(packageName,
        somethingChanged = setTileEnabled(new ComponentName(packageName,
                        Settings.WifiDisplaySettingsActivity.class.getName()),
                WifiDisplaySettings.isAvailable(this), isAdmin);
                WifiDisplaySettings.isAvailable(this), isAdmin)
                || somethingChanged;

        if (UserHandle.MU_ENABLED && !isAdmin) {

@@ -848,7 +859,8 @@ public class SettingsActivity extends SettingsDrawerActivity
                                SettingsGateway.SETTINGS_FOR_RESTRICTED, name);
                        if (packageName.equals(component.getPackageName())
                                && !isEnabledForRestricted) {
                            setTileEnabled(component, false, isAdmin);
                            somethingChanged = setTileEnabled(component, false, isAdmin)
                                    || somethingChanged;
                        }
                    }
                }
@@ -856,16 +868,24 @@ public class SettingsActivity extends SettingsDrawerActivity
        }

        // Final step, refresh categories.
        if (somethingChanged) {
            Log.d(LOG_TAG, "Enabled state changed for some tiles, reloading all categories");
            updateCategories();
        } else {
            Log.d(LOG_TAG, "No enabled state changed, skipping updateCategory call");
        }
    }

    private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin) {
    /**
     * @return whether or not the enabled state actually changed.
     */
    private boolean setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin) {
        if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
                && !ArrayUtils.contains(SettingsGateway.SETTINGS_FOR_RESTRICTED,
                component.getClassName())) {
            enabled = false;
        }
        setTileEnabled(component, enabled);
        return setTileEnabled(component, enabled);
    }

    private void getMetaData() {
+2 −0
Original line number Diff line number Diff line
@@ -294,10 +294,12 @@ public class DashboardSummary extends InstrumentedFragment

        final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory(
                CategoryKey.CATEGORY_HOMEPAGE);
        mSummaryLoader.updateSummaryToCache(category);
        if (suggestions != null) {
            mAdapter.setCategoriesAndSuggestions(category, suggestions);
        } else {
            mAdapter.setCategory(category);
        }
    }

}
+25 −24
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import android.util.Log;
import com.android.settings.SettingsActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.SettingsDrawerActivity;
import com.android.settingslib.drawer.Tile;

import java.lang.reflect.Field;
@@ -47,7 +46,8 @@ public class SummaryLoader {
    public static final String SUMMARY_PROVIDER_FACTORY = "SUMMARY_PROVIDER_FACTORY";

    private final Activity mActivity;
    private final ArrayMap<SummaryProvider, ComponentName> mSummaryMap = new ArrayMap<>();
    private final ArrayMap<SummaryProvider, ComponentName> mSummaryProviderMap = new ArrayMap<>();
    private final ArrayMap<String, CharSequence> mSummaryTextMap = new ArrayMap<>();
    private final DashboardFeatureProvider mDashboardFeatureProvider;
    private final String mCategoryKey;

@@ -111,7 +111,7 @@ public class SummaryLoader {
    }

    public void setSummary(SummaryProvider provider, final CharSequence summary) {
        final ComponentName component = mSummaryMap.get(provider);
        final ComponentName component = mSummaryProviderMap.get(provider);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
@@ -142,6 +142,7 @@ public class SummaryLoader {
            }
            return;
        }
        mSummaryTextMap.put(mDashboardFeatureProvider.getDashboardKeyForTile(tile), summary);
        tile.summary = summary;
        if (mSummaryConsumer != null) {
            mSummaryConsumer.notifySummaryChanged(tile);
@@ -223,11 +224,27 @@ public class SummaryLoader {
        });
    }

    /**
     * Updates all tile's summary to latest cached version. This is necessary to handle the case
     * where category is updated after summary change.
     */
    public void updateSummaryToCache(DashboardCategory category) {
        if (category == null) {
            return;
        }
        for (Tile tile : category.tiles) {
            final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
            if (mSummaryTextMap.containsKey(key)) {
                tile.summary = mSummaryTextMap.get(key);
            }
        }
    }

    private synchronized void setListeningW(boolean listening) {
        if (mWorkerListening == listening) return;
        mWorkerListening = listening;
        if (DEBUG) Log.d(TAG, "Listening " + listening);
        for (SummaryProvider p : mSummaryMap.keySet()) {
        for (SummaryProvider p : mSummaryProviderMap.keySet()) {
            try {
                p.setListening(listening);
            } catch (Exception e) {
@@ -240,26 +257,8 @@ public class SummaryLoader {
        SummaryProvider provider = getSummaryProvider(tile);
        if (provider != null) {
            if (DEBUG) Log.d(TAG, "Creating " + tile);
            mSummaryMap.put(provider, tile.intent.getComponent());
        }
    }

    private Tile getTileFromCategory(List<DashboardCategory> categories, ComponentName component) {
        if (categories == null) {
            if (DEBUG) {
                Log.d(TAG, "Category is null, can't find tile");
            }
            return null;
        }
        final int categorySize = categories.size();
        for (int i = 0; i < categorySize; i++) {
            final DashboardCategory category = categories.get(i);
            final Tile tile = getTileFromCategory(category, component);
            if (tile != null) {
                return tile;
            }
            mSummaryProviderMap.put(provider, tile.intent.getComponent());
        }
        return null;
    }

    private Tile getTileFromCategory(DashboardCategory category, ComponentName component) {
@@ -276,6 +275,8 @@ public class SummaryLoader {
        return null;
    }



    public interface SummaryProvider {
        void setListening(boolean listening);
    }
+8 −1
Original line number Diff line number Diff line
@@ -19,11 +19,12 @@ package com.android.settings.dashboard;
import android.app.Activity;
import android.support.v7.widget.LinearLayoutManager;

import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.conditional.ConditionManager;
import com.android.settings.dashboard.conditional.FocusRecyclerView;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;

import org.junit.Before;
@@ -34,6 +35,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;

import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -57,6 +59,8 @@ public class DashboardSummaryTest {
    private LinearLayoutManager mLayoutManager;
    @Mock
    private ConditionManager mConditionManager;
    @Mock
    private SummaryLoader mSummaryLoader;

    private DashboardSummary mSummary;

@@ -70,12 +74,15 @@ public class DashboardSummaryTest {
        ReflectionHelpers.setField(mSummary, "mDashboard", mDashboard);
        ReflectionHelpers.setField(mSummary, "mLayoutManager", mLayoutManager);
        ReflectionHelpers.setField(mSummary, "mConditionManager", mConditionManager);
        ReflectionHelpers.setField(mSummary, "mSummaryLoader", mSummaryLoader);
    }

    @Test
    public void updateCategoryAndSuggestion_shouldGetCategoryFromFeatureProvider() {
        doReturn(mock(Activity.class)).when(mSummary).getActivity();
        mSummary.updateCategoryAndSuggestion(null);

        verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class));
        verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE);
    }

+37 −1
Original line number Diff line number Diff line
@@ -17,13 +17,21 @@
package com.android.settings.dashboard;

import android.app.Activity;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import android.content.Context;
import android.content.Intent;

import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;

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.Robolectric;
import org.robolectric.annotation.Config;

@@ -31,18 +39,27 @@ import java.util.ArrayList;
import java.util.List;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;

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

    private static final String SUMMARY_1 = "summary1";
    private static final String SUMMARY_2 = "summary2";

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Context mContext;
    private SummaryLoader mSummaryLoader;
    private boolean mCallbackInvoked;
    private Tile mTile;
    private FakeFeatureFactory mFeatureFactory;

    @Before
    public void SetUp() {
        MockitoAnnotations.initMocks(this);
        mFeatureFactory = FakeFeatureFactory.setupForTest(mContext);

        mTile = new Tile();
        mTile.summary = SUMMARY_1;
        mCallbackInvoked = false;
@@ -71,4 +88,23 @@ public class SummaryLoaderTest {

        assertThat(mCallbackInvoked).isTrue();
    }

    @Test
    public void testUpdateSummaryToCache_hasCache_shouldUpdate() {

        final String testSummary = "test_summary";
        final DashboardCategory category = new DashboardCategory();
        final Tile tile = new Tile();
        tile.key = "123";
        tile.intent = new Intent();
        category.addTile(tile);
        when(mFeatureFactory.dashboardFeatureProvider.getDashboardKeyForTile(tile))
                .thenReturn(tile.key);

        mSummaryLoader.updateSummaryIfNeeded(tile, testSummary);
        tile.summary = null;
        mSummaryLoader.updateSummaryToCache(category);

        assertThat(tile.summary).isEqualTo(testSummary);
    }
}