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

Commit 8b5c1f48 authored by Shahriyar Amini's avatar Shahriyar Amini Committed by Android (Google) Code Review
Browse files

Merge "Implement summary provider for Security."

parents 09989dd2 5c1ad614
Loading
Loading
Loading
Loading
+81 −10
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -38,6 +39,7 @@ import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.security.KeyStore;
import android.service.trust.TrustAgentService;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
@@ -49,6 +51,7 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -56,6 +59,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.fingerprint.FingerprintSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -69,6 +73,7 @@ import com.android.settingslib.RestrictedSwitchPreference;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.drawer.TileUtils;

import java.util.ArrayList;
import java.util.List;
@@ -120,6 +125,11 @@ public class SecuritySettings extends SettingsPreferenceFragment
    private static final String KEY_TRUST_AGENT = "trust_agent";
    private static final String KEY_SCREEN_PINNING = "screen_pinning_settings";

    // Package verifier Settings
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    static final String KEY_PACKAGE_VERIFIER_STATE = "package_verifier_state";
    private static final int PACKAGE_VERIFIER_STATE_ENABLED = 1;

    // These switch preferences need special handling since they're not all stored in Settings.
    private static final String SWITCH_PREFERENCE_KEYS[] = {
            KEY_SHOW_PASSWORD, KEY_TOGGLE_INSTALL_APPLICATIONS, KEY_UNIFICATION,
@@ -414,6 +424,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
        Index.getInstance(getActivity())
                .updateFromClassNameResource(SecuritySettings.class.getName(), true, true);

        if (mDashboardFeatureProvider.isEnabled()) {
            final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
                    getActivity(), getPrefContext(), CategoryKey.CATEGORY_SECURITY);
            if (tilePrefs != null && !tilePrefs.isEmpty()) {
@@ -422,10 +433,11 @@ public class SecuritySettings extends SettingsPreferenceFragment
                }
            }

        // Update preference data with tile data. Security feature provider only updates the data
        // if it actually needs to be changed.
            // Update preference data with tile data. Security feature provider only updates the
            // data if it actually needs to be changed.
            mSecurityFeatureProvider.updatePreferences(getActivity(), root,
                    mDashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY));
        }

        for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
            final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
@@ -1306,4 +1318,63 @@ public class SecuritySettings extends SettingsPreferenceFragment
        }
    }

    static class SummaryProvider implements SummaryLoader.SummaryProvider {

        private final Context mContext;
        private final SummaryLoader mSummaryLoader;

        public SummaryProvider(Context context, SummaryLoader summaryLoader) {
            mContext = context;
            mSummaryLoader = summaryLoader;
        }

        @Override
        public void setListening(boolean listening) {
            if (!listening) {
                return;
            }
            int packageVerifierState = Settings.Secure.getInt(mContext.getContentResolver(),
                    Settings.Secure.PACKAGE_VERIFIER_STATE, 0);
            DashboardFeatureProvider dashboardFeatureProvider =
                    FeatureFactory.getFactory(mContext).getDashboardFeatureProvider(mContext);
            if (dashboardFeatureProvider.isEnabled()
                    && (packageVerifierState == PACKAGE_VERIFIER_STATE_ENABLED)) {
                DashboardCategory dashboardCategory =
                        dashboardFeatureProvider.getTilesForCategory(CategoryKey.CATEGORY_SECURITY);
                mSummaryLoader.setSummary(this, getPackageVerifierSummary(dashboardCategory));
            } else {
                mSummaryLoader.setSummary(this, null);
            }
        }

        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
        String getPackageVerifierSummary(DashboardCategory dashboardCategory) {
            int tilesCount = (dashboardCategory != null) ? dashboardCategory.getTilesCount() : 0;
            if (tilesCount == 0) {
                return null;
            }
            for (int i = 0; i < tilesCount; i++) {
                Tile tile = dashboardCategory.getTile(i);
                if (!KEY_PACKAGE_VERIFIER_STATE.equals(tile.key)) {
                    continue;
                }
                String summaryUri = tile.metaData.getString(
                        TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, null);
                return TileUtils.getTextFromUri(mContext, summaryUri,
                            new ArrayMap<String, IContentProvider>(),
                            TileUtils.META_DATA_PREFERENCE_SUMMARY);
            }
            return null;
        }
    }

    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
            new SummaryLoader.SummaryProviderFactory() {
        @Override
        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
                SummaryLoader summaryLoader) {
            return new SummaryProvider(activity, summaryLoader);
        }
    };

}
+156 −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;

import android.content.Context;
import android.content.ContentResolver;
import android.content.IContentProvider;
import android.provider.Settings;
import android.os.Bundle;

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

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

import java.util.HashMap;
import java.util.Map;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

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

    private static final String MOCK_SUMMARY = "summary";

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Context mContext;
    @Mock
    private DashboardCategory mDashboardCategory;
    @Mock
    private SummaryLoader mSummaryLoader;

    private SecuritySettings.SummaryProvider mSummaryProvider;

    @Implements(Settings.Secure.class)
    public static class ShadowSecureSettings {

        private static final Map<String, Object> mValueMap = new HashMap<>();

        @Implementation
        public static boolean putInt(ContentResolver resolver, String name, int value) {
            mValueMap.put(name, value);
            return true;
        }

        @Implementation
        public static int getInt(ContentResolver resolver, String name, int defaultValue) {
            Integer value = (Integer) mValueMap.get(name);
            return value == null ? defaultValue : value;
        }
    }

    @Implements(com.android.settingslib.drawer.TileUtils.class)
    public static class ShadowTileUtils {
        @Implementation
        public static String getTextFromUri(Context context, String uriString,
                Map<String, IContentProvider> providerMap, String key) {
            return MOCK_SUMMARY;
        }
    }

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        FakeFeatureFactory.setupForTest(mContext);
        mSummaryProvider = new SecuritySettings.SummaryProvider(mContext, mSummaryLoader);
    }

    @Test
    public void testSummaryProvider_notListening() {
        mSummaryProvider.setListening(false);

        verifyNoMoreInteractions(mSummaryLoader);
    }

    @Test
    @Config(shadows = {
            ShadowSecureSettings.class,
    })
    public void testSummaryProvider_packageVerifierDisabled() {
        // Package verifier state is set to disabled.
        ShadowSecureSettings.putInt(null, Settings.Secure.PACKAGE_VERIFIER_STATE, -1);
        mSummaryProvider.setListening(true);

        verify(mSummaryLoader, times(1)).setSummary(any(), isNull(String.class));
    }

    @Test
    public void testGetPackageVerifierSummary_nullInput() {
        assertThat(mSummaryProvider.getPackageVerifierSummary(null)).isNull();

        when(mDashboardCategory.getTilesCount()).thenReturn(0);

        assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory)).isNull();
    }

    @Test
    public void testGetPackageVerifierSummary_noMatchingTile() {
        when(mDashboardCategory.getTilesCount()).thenReturn(1);
        when(mDashboardCategory.getTile(0)).thenReturn(new Tile());

        assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory)).isNull();
    }

    @Test
    @Config(shadows = {
            ShadowTileUtils.class,
    })
    public void testGetPackageVerifierSummary_matchingTile() {
        when(mDashboardCategory.getTilesCount()).thenReturn(1);
        Tile tile = new Tile();
        tile.key = SecuritySettings.KEY_PACKAGE_VERIFIER_STATE;
        Bundle bundle = new Bundle();
        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, "content://host/path");
        tile.metaData = bundle;
        when(mDashboardCategory.getTile(0)).thenReturn(tile);

        assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory))
                .isEqualTo(MOCK_SUMMARY);
    }
}