Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.security;
     18 
     19 import android.content.Context;
     20 import android.content.IContentProvider;
     21 import android.content.Intent;
     22 import android.content.pm.PackageManager;
     23 import android.content.res.Resources;
     24 import android.graphics.drawable.Drawable;
     25 import android.os.Bundle;
     26 import android.support.v7.preference.Preference;
     27 import android.support.v7.preference.PreferenceScreen;
     28 import android.util.Pair;
     29 
     30 import com.android.settings.testutils.SettingsRobolectricTestRunner;
     31 import com.android.settings.R;
     32 import com.android.settings.TestConfig;
     33 import com.android.settingslib.drawer.DashboardCategory;
     34 import com.android.settingslib.drawer.Tile;
     35 import com.android.settingslib.drawer.TileUtils;
     36 
     37 import org.junit.Before;
     38 import org.junit.Test;
     39 import org.junit.runner.RunWith;
     40 import org.mockito.Mock;
     41 import org.mockito.MockitoAnnotations;
     42 import org.robolectric.RuntimeEnvironment;
     43 import org.robolectric.annotation.Config;
     44 import org.robolectric.annotation.Implementation;
     45 import org.robolectric.annotation.Implements;
     46 import org.robolectric.shadows.ShadowLooper;
     47 
     48 import java.util.Map;
     49 
     50 import static org.mockito.Matchers.any;
     51 import static org.mockito.Matchers.anyInt;
     52 import static org.mockito.Matchers.anyString;
     53 import static org.mockito.Mockito.mock;
     54 import static org.mockito.Mockito.never;
     55 import static org.mockito.Mockito.spy;
     56 import static org.mockito.Mockito.verify;
     57 import static org.mockito.Mockito.verifyNoMoreInteractions;
     58 import static org.mockito.Mockito.when;
     59 
     60 @RunWith(SettingsRobolectricTestRunner.class)
     61 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
     62 public class SecurityFeatureProviderImplTest {
     63 
     64     private static final String MOCK_KEY = "key";
     65     private static final String MOCK_SUMMARY = "summary";
     66     private static final String URI_GET_SUMMARY = "content://package/text/summary";
     67     private static final String URI_GET_ICON = "content://package/icon/my_icon";
     68 
     69     @Mock
     70     private Drawable mMockDrawable;
     71     @Mock
     72     private Context mContext;
     73     @Mock
     74     private PackageManager mPackageManager;
     75     @Mock
     76     private Resources mResources;
     77 
     78     private SecurityFeatureProviderImpl mImpl;
     79 
     80     @Implements(com.android.settingslib.drawer.TileUtils.class)
     81     public static class ShadowTileUtils {
     82         @Implementation
     83         public static Pair getIconFromUri(Context context, String packageName, String uriString,
     84                 Map<String, IContentProvider> providerMap) {
     85             return Pair.create("package", 161803);
     86         }
     87 
     88         @Implementation
     89         public static String getTextFromUri(Context context, String uriString,
     90                 Map<String, IContentProvider> providerMap, String key) {
     91             return MOCK_SUMMARY;
     92         }
     93     }
     94 
     95     @Before
     96     public void setUp() throws PackageManager.NameNotFoundException {
     97         MockitoAnnotations.initMocks(this);
     98         mContext = spy(RuntimeEnvironment.application);
     99         mImpl = new SecurityFeatureProviderImpl();
    100         when(mContext.getPackageManager()).thenReturn(mPackageManager);
    101         when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
    102         when(mResources.getDrawable(anyInt(), any())).thenReturn(mMockDrawable);
    103     }
    104 
    105     @Test
    106     public void updateTilesData_shouldNotProcessEmptyScreenOrTiles() {
    107         mImpl.updatePreferencesToRunOnWorkerThread(mContext, null, null);
    108         ShadowLooper.runUiThreadTasks();
    109         mImpl.updatePreferencesToRunOnWorkerThread(
    110                 mContext, new PreferenceScreen(mContext, null), null);
    111         ShadowLooper.runUiThreadTasks();
    112         verifyNoMoreInteractions(mPackageManager);
    113     }
    114 
    115     @Test
    116     public void updateTilesData_shouldNotProcessNonMatchingPreference() {
    117         DashboardCategory dashboardCategory = new DashboardCategory();
    118         dashboardCategory.addTile(new Tile());
    119         mImpl.updatePreferencesToRunOnWorkerThread(
    120                 mContext, getPreferenceScreen(), dashboardCategory);
    121         ShadowLooper.runUiThreadTasks();
    122         verifyNoMoreInteractions(mPackageManager);
    123     }
    124 
    125     @Test
    126     public void updateTilesData_shouldNotProcessMatchingPreferenceWithNoData() {
    127         mImpl.updatePreferencesToRunOnWorkerThread(
    128                 mContext, getPreferenceScreen(), getDashboardCategory());
    129         ShadowLooper.runUiThreadTasks();
    130         verifyNoMoreInteractions(mPackageManager);
    131     }
    132 
    133     @Test
    134     @Config(shadows = {
    135             ShadowTileUtils.class,
    136     })
    137     public void updateTilesData_shouldUpdateMatchingPreference() {
    138         Bundle bundle = new Bundle();
    139         bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
    140         bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
    141 
    142         PreferenceScreen screen = getPreferenceScreen();
    143         DashboardCategory dashboardCategory = getDashboardCategory();
    144         dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
    145         dashboardCategory.getTile(0).metaData = bundle;
    146 
    147         mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
    148         ShadowLooper.runUiThreadTasks();
    149         verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
    150         verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
    151     }
    152 
    153     @Test
    154     @Config(shadows = {
    155             ShadowTileUtils.class,
    156     })
    157     public void updateTilesData_shouldNotUpdateAlreadyUpdatedPreference() {
    158         Bundle bundle = new Bundle();
    159         bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
    160         bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
    161 
    162         PreferenceScreen screen = getPreferenceScreen();
    163         when(screen.findPreference(MOCK_KEY).getSummary()).thenReturn(MOCK_SUMMARY);
    164         when(screen.findPreference(MOCK_KEY).getIcon()).thenReturn(mMockDrawable);
    165 
    166         DashboardCategory dashboardCategory = getDashboardCategory();
    167         dashboardCategory.getTile(0).intent = new Intent().setPackage("package");
    168         dashboardCategory.getTile(0).metaData = bundle;
    169 
    170         mImpl.updatePreferencesToRunOnWorkerThread(mContext, screen, dashboardCategory);
    171         ShadowLooper.runUiThreadTasks();
    172         verify(screen.findPreference(MOCK_KEY), never()).setSummary(anyString());
    173     }
    174 
    175     @Test
    176     public void initPreferences_shouldLoadDefaults() {
    177         PreferenceScreen screen = getPreferenceScreen();
    178         DashboardCategory dashboardCategory = getDashboardCategory();
    179         dashboardCategory.getTile(0).metaData = new Bundle();
    180 
    181         mImpl.initPreferences(mContext, screen, dashboardCategory);
    182         verify(screen.findPreference(MOCK_KEY)).setIcon(SecurityFeatureProviderImpl.DEFAULT_ICON);
    183         verify(screen.findPreference(MOCK_KEY))
    184                 .setSummary(mContext.getString(R.string.summary_placeholder));
    185     }
    186 
    187     @Test
    188     @Config(shadows = {
    189             ShadowTileUtils.class,
    190     })
    191     public void initPreferences_shouldLoadCached() {
    192         Bundle bundle = new Bundle();
    193         bundle.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, URI_GET_ICON);
    194         bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
    195 
    196         PreferenceScreen screen = getPreferenceScreen();
    197         DashboardCategory dashboardCategory = getDashboardCategory();
    198         dashboardCategory.getTile(0).metaData = bundle;
    199 
    200         SecurityFeatureProviderImpl.sIconCache.put(
    201                 URI_GET_ICON,
    202                 ShadowTileUtils.getIconFromUri(null, null, null, null));
    203         SecurityFeatureProviderImpl.sSummaryCache.put(
    204                 URI_GET_SUMMARY,
    205                 MOCK_SUMMARY);
    206 
    207         mImpl.initPreferences(mContext, screen, dashboardCategory);
    208         verify(screen.findPreference(MOCK_KEY)).setIcon(mMockDrawable);
    209         verify(screen.findPreference(MOCK_KEY)).setSummary(MOCK_SUMMARY);
    210     }
    211 
    212     private PreferenceScreen getPreferenceScreen() {
    213         final PreferenceScreen screen = mock(PreferenceScreen.class);
    214         final Preference pref = mock(Preference.class);
    215         when(screen.findPreference(MOCK_KEY)).thenReturn(pref);
    216         when(pref.getKey()).thenReturn(MOCK_KEY);
    217         return screen;
    218     }
    219 
    220     private static DashboardCategory getDashboardCategory() {
    221         DashboardCategory dashboardCategory = new DashboardCategory();
    222         Tile tile = new Tile();
    223         tile.key = MOCK_KEY;
    224         dashboardCategory.addTile(tile);
    225         return dashboardCategory;
    226     }
    227 }
    228