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
17package com.android.settings.language;
18
19import static com.google.common.truth.Truth.assertThat;
20import static org.mockito.Matchers.any;
21import static org.mockito.Mockito.doReturn;
22import static org.mockito.Mockito.mock;
23import static org.mockito.Mockito.spy;
24import static org.mockito.Mockito.times;
25import static org.mockito.Mockito.verify;
26import static org.mockito.Mockito.when;
27
28import android.app.Activity;
29import android.app.admin.DevicePolicyManager;
30import android.content.ComponentName;
31import android.content.Context;
32import android.content.pm.PackageManager;
33import android.hardware.input.InputManager;
34import android.os.UserManager;
35import android.provider.Settings;
36import android.view.autofill.AutofillManager;
37import android.view.inputmethod.InputMethodInfo;
38import android.view.inputmethod.InputMethodManager;
39import android.view.textservice.TextServicesManager;
40
41import com.android.internal.hardware.AmbientDisplayConfiguration;
42import com.android.settings.R;
43import com.android.settings.SettingsRobolectricTestRunner;
44import com.android.settings.TestConfig;
45import com.android.settings.core.PreferenceController;
46import com.android.settings.core.lifecycle.Lifecycle;
47import com.android.settings.core.lifecycle.LifecycleObserver;
48import com.android.settings.dashboard.SummaryLoader;
49import com.android.settings.fuelgauge.PowerUsageSummary;
50import com.android.settings.testutils.XmlTestUtils;
51import com.android.settings.testutils.shadow.ShadowSecureSettings;
52
53import org.junit.Before;
54import org.junit.Test;
55import org.junit.runner.RunWith;
56import org.mockito.Answers;
57import org.mockito.Mock;
58import org.mockito.MockitoAnnotations;
59import org.robolectric.RuntimeEnvironment;
60import org.robolectric.annotation.Config;
61
62import java.util.ArrayList;
63import java.util.List;
64
65@RunWith(SettingsRobolectricTestRunner.class)
66@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
67public class LanguageAndInputSettingsTest {
68
69    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
70    private Context mContext;
71    @Mock
72    private PackageManager mPackageManager;
73    @Mock
74    private InputManager mIm;
75    @Mock
76    private InputMethodManager mImm;
77    @Mock
78    private DevicePolicyManager mDpm;
79    @Mock
80    private InputMethodManager mInputMethodManager;
81    @Mock
82    private AutofillManager mAutofillManager;
83    private TestFragment mFragment;
84
85    @Before
86    public void setUp() {
87        MockitoAnnotations.initMocks(this);
88        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mock(UserManager.class));
89        when(mContext.getSystemService(Context.INPUT_SERVICE)).thenReturn(mock(InputManager.class));
90        when(mContext.getSystemService(Context.INPUT_SERVICE)).thenReturn(mIm);
91        when(mContext.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE))
92                .thenReturn(mock(TextServicesManager.class));
93        when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(mDpm);
94        when(mContext.getSystemService(Context.INPUT_METHOD_SERVICE)).thenReturn(mImm);
95        when(mContext.getSystemService(AutofillManager.class)).thenReturn(mAutofillManager);
96        mFragment = new TestFragment(mContext);
97    }
98
99    @Test
100    public void testGetPreferenceScreenResId() {
101        assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(R.xml.language_and_input);
102    }
103
104    @Test
105    public void testGetPreferenceControllers_shouldRegisterLifecycleObservers() {
106        final List<PreferenceController> controllers = mFragment.getPreferenceControllers(mContext);
107        int lifecycleObserverCount = 0;
108        for (PreferenceController controller : controllers) {
109            if (controller instanceof LifecycleObserver) {
110                lifecycleObserverCount++;
111            }
112        }
113        verify(mFragment.getLifecycle(), times(lifecycleObserverCount))
114                .addObserver(any(LifecycleObserver.class));
115    }
116
117    @Test
118
119    public void testGetPreferenceControllers_shouldAllBeCreated() {
120        final List<PreferenceController> controllers = mFragment.getPreferenceControllers(mContext);
121
122        assertThat(controllers.isEmpty()).isFalse();
123    }
124
125    @Test
126    @Config(shadows = {
127            ShadowSecureSettings.class,
128    })
129    public void testSummary_shouldSetToCurrentImeName() {
130        final Activity activity = mock(Activity.class);
131        final SummaryLoader loader = mock(SummaryLoader.class);
132        final ComponentName componentName = new ComponentName("pkg", "cls");
133        ShadowSecureSettings.putString(null, Settings.Secure.DEFAULT_INPUT_METHOD,
134                componentName.flattenToString());
135        when(activity.getSystemService(Context.INPUT_METHOD_SERVICE))
136                .thenReturn(mInputMethodManager);
137        when(activity.getPackageManager()).thenReturn(mPackageManager);
138        final List<InputMethodInfo> imis = new ArrayList<>();
139        imis.add(mock(InputMethodInfo.class));
140        when(imis.get(0).getPackageName()).thenReturn(componentName.getPackageName());
141        when(mInputMethodManager.getInputMethodList()).thenReturn(imis);
142
143        SummaryLoader.SummaryProvider provider = mFragment.SUMMARY_PROVIDER_FACTORY
144                .createSummaryProvider(activity, loader);
145
146        provider.setListening(true);
147
148        verify(imis.get(0)).loadLabel(mPackageManager);
149        verify(loader).setSummary(provider, null);
150    }
151
152    @Test
153    public void testNonIndexableKeys_existInXmlLayout() {
154        final Context context = spy(RuntimeEnvironment.application);
155        //(InputManager) context.getSystemService(Context.INPUT_SERVICE);
156        InputManager manager = mock(InputManager.class);
157        when(manager.getInputDeviceIds()).thenReturn(new int[]{});
158        doReturn(manager).when(context).getSystemService(Context.INPUT_SERVICE);
159        final List<String> niks = LanguageAndInputSettings.SEARCH_INDEX_DATA_PROVIDER
160                .getNonIndexableKeys(context);
161        final int xmlId = (new LanguageAndInputSettings()).getPreferenceScreenResId();
162
163        final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
164
165        assertThat(keys).containsAllIn(niks);
166    }
167
168    @Test
169    public void testPreferenceControllers_getPreferenceKeys_existInPreferenceScreen() {
170        final Context context = RuntimeEnvironment.application;
171        final LanguageAndInputSettings fragment = new LanguageAndInputSettings();
172        final List<String> preferenceScreenKeys = XmlTestUtils.getKeysFromPreferenceXml(context,
173                fragment.getPreferenceScreenResId());
174        final List<String> preferenceKeys = new ArrayList<>();
175
176        for (PreferenceController controller : fragment.getPreferenceControllers(context)) {
177            preferenceKeys.add(controller.getPreferenceKey());
178        }
179
180        assertThat(preferenceScreenKeys).containsAllIn(preferenceKeys);
181    }
182
183    /**
184     * Test fragment to expose lifecycle and context so we can verify behavior for observables.
185     */
186    public static class TestFragment extends LanguageAndInputSettings {
187
188        private Lifecycle mLifecycle;
189        private Context mContext;
190
191        public TestFragment(Context context) {
192            mContext = context;
193            mLifecycle = mock(Lifecycle.class);
194            setAmbientDisplayConfig(mock(AmbientDisplayConfiguration.class));
195        }
196
197        @Override
198        public Context getContext() {
199            return mContext;
200        }
201
202        @Override
203        protected Lifecycle getLifecycle() {
204            if (mLifecycle == null) {
205                return super.getLifecycle();
206            }
207            return mLifecycle;
208        }
209    }
210}
211