1f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov/*
2f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * Copyright (C) 2017 The Android Open Source Project
3f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov *
4f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * Licensed under the Apache License, Version 2.0 (the "License");
5f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * you may not use this file except in compliance with the License.
6f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * You may obtain a copy of the License at
7f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov *
8f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov *      http://www.apache.org/licenses/LICENSE-2.0
9f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov *
10f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * Unless required by applicable law or agreed to in writing, software
11f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * distributed under the License is distributed on an "AS IS" BASIS,
12f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * See the License for the specific language governing permissions and
14f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov * limitations under the License
15f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov */
16f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
17f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovpackage com.android.settings.backup;
18f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
19e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lamimport static com.google.common.truth.Truth.assertThat;
20f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.mockito.Matchers.any;
21f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.mockito.Matchers.anyInt;
22f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.mockito.Matchers.isA;
23f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.mockito.Mockito.doReturn;
24f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.mockito.Mockito.verify;
2522a39c2b93bc66db71238274a7683d329232d124James Lemieuximport static org.mockito.Mockito.when;
26f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport static org.robolectric.Shadows.shadowOf;
27f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
28f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.app.Application;
29f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.app.Fragment;
30f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.app.FragmentManager;
31f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.app.FragmentTransaction;
32f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.content.ComponentName;
33f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.content.Intent;
34f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport android.content.pm.PackageManager;
359a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippovimport android.os.UserHandle;
36f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
379a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippovimport com.android.settings.search.SearchIndexableRaw;
38e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lamimport com.android.settings.testutils.SettingsRobolectricTestRunner;
39f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
409a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippovimport org.junit.After;
41f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.junit.Before;
42f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.junit.Test;
43f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.junit.runner.RunWith;
44f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.mockito.Mock;
45f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.mockito.MockitoAnnotations;
46f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.robolectric.Robolectric;
47f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.robolectric.RuntimeEnvironment;
48e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lamimport org.robolectric.Shadows;
49e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lamimport org.robolectric.android.controller.ActivityController;
50f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.robolectric.annotation.Config;
51f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.robolectric.annotation.Implementation;
52f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovimport org.robolectric.annotation.Implements;
539a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippovimport org.robolectric.annotation.Resetter;
54e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lamimport org.robolectric.shadows.ShadowPackageManager;
55f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
569a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippovimport java.util.List;
579a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
58f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov@RunWith(SettingsRobolectricTestRunner.class)
5922a39c2b93bc66db71238274a7683d329232d124James Lemieux@Config(shadows = {BackupSettingsActivityTest.ShadowBackupSettingsHelper.class,
609a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov                BackupSettingsActivityTest.ShadowUserHandle.class})
61f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippovpublic class BackupSettingsActivityTest {
62f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private ActivityController<BackupSettingsActivity> mActivityController;
63f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private BackupSettingsActivity mActivity;
64f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private Application mApplication;
65e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lam    private ShadowPackageManager mPackageManager;
66f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private static boolean mIsBackupProvidedByOEM;
67f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
68f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Mock
69f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private FragmentManager mFragmentManager;
70f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
71f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Mock
72f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private FragmentTransaction mFragmentTransaction;
73f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Mock
74f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private static Intent mIntent;
75f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Mock
76f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    private ComponentName mComponent;
77f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
78f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Before
79f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    public void setUp() {
80f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        MockitoAnnotations.initMocks(this);
81f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
82f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mApplication = RuntimeEnvironment.application;
83f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mActivityController = Robolectric.buildActivity(BackupSettingsActivity.class);
84f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mActivity = mActivityController.get();
85e18902ec6764e138cd4bb5a452a9c25736764252Maurice Lam        mPackageManager = Shadows.shadowOf(mApplication.getPackageManager());
8622a39c2b93bc66db71238274a7683d329232d124James Lemieux        when(mIntent.getComponent()).thenReturn(mComponent);
8722a39c2b93bc66db71238274a7683d329232d124James Lemieux    }
8822a39c2b93bc66db71238274a7683d329232d124James Lemieux
8922a39c2b93bc66db71238274a7683d329232d124James Lemieux    @After
9022a39c2b93bc66db71238274a7683d329232d124James Lemieux    public void resetShadows() {
9122a39c2b93bc66db71238274a7683d329232d124James Lemieux        ShadowUserHandle.reset();
92f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    }
93f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
94f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Test
95f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    public void onCreate_launchActivity() {
96f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mIsBackupProvidedByOEM = false;
97f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
98f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        // Testing the scenario when the activity is disabled
9922a39c2b93bc66db71238274a7683d329232d124James Lemieux        mApplication.getPackageManager().setComponentEnabledSetting(mComponent,
100f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
101f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
102f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mActivityController.create();
103f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
104f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        // Verify that the component to launch was enabled.
10522a39c2b93bc66db71238274a7683d329232d124James Lemieux        final int flags = mPackageManager.getComponentEnabledSettingFlags(mComponent);
10622a39c2b93bc66db71238274a7683d329232d124James Lemieux        assertThat(flags & PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
10722a39c2b93bc66db71238274a7683d329232d124James Lemieux            .isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
108f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
109f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        // Verify that the intent returned by BackupSettingsHelper.getIntentForBackupSettings()
110f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        // was launched.
111f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        assertThat(shadowOf(mApplication).getNextStartedActivity()).isEqualTo(mIntent);
112f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    }
113f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
114f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Test
115f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    public void onCreate_hasManufacturerIntent() {
116f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mIsBackupProvidedByOEM = true;
117f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
118f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        // Fragments are tested separately, so mock out the manager.
119f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mActivity.setFragmentManager(mFragmentManager);
120f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        doReturn(mFragmentTransaction).when(mFragmentTransaction).replace(anyInt(),
121f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov                any(Fragment.class));
122f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
123f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
124f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        mActivityController.create();
125f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
126f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        assertThat(shadowOf(mApplication).getNextStartedActivity()).isNull();
127f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        verify(mFragmentTransaction).replace(anyInt(), isA(BackupSettingsFragment.class));
128f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    }
129f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
1309a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    @Test
1319a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    public void getNonIndexableKeys_SystemUser() {
13222a39c2b93bc66db71238274a7683d329232d124James Lemieux        assertThat(BackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(
13322a39c2b93bc66db71238274a7683d329232d124James Lemieux                mApplication, true)).isNotEmpty();
13422a39c2b93bc66db71238274a7683d329232d124James Lemieux        assertThat(BackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
13522a39c2b93bc66db71238274a7683d329232d124James Lemieux                mApplication)).isEmpty();
1369a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    }
1379a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1389a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    @Test
1399a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    public void getNonIndexableKeys_NonSystemUser() {
1409a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        ShadowUserHandle.setUid(1); // Non-SYSTEM user.
1419a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1429a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        final List<SearchIndexableRaw> indexableRaws =
1439a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov                BackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(
14422a39c2b93bc66db71238274a7683d329232d124James Lemieux                        mApplication, true);
1459a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        final List<String> nonIndexableKeys =
1469a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov                BackupSettingsActivity.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(
14722a39c2b93bc66db71238274a7683d329232d124James Lemieux                        mApplication);
1489a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1499a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        assertThat(indexableRaws).isNotNull();
1509a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        assertThat(indexableRaws).isNotEmpty();
1519a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        assertThat(nonIndexableKeys).isNotEmpty();
1529a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    }
1539a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
154f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    @Implements(BackupSettingsHelper.class)
155f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    public static class ShadowBackupSettingsHelper {
156f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        @Implementation
157f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        public Intent getIntentForBackupSettings() {
158f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov            return mIntent;
159f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        }
160f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov
161f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        @Implementation
162f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        public boolean isBackupProvidedByManufacturer() {
163f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov            return mIsBackupProvidedByOEM;
164f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov        }
165f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov    }
1669a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1679a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    @Implements(UserHandle.class)
1689a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    public static class ShadowUserHandle {
1699a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        private static int sUid = 0; // SYSTEM by default
1709a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1719a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        public static void setUid(int uid) {
1729a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov            sUid = uid;
1739a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        }
1749a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1759a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        @Implementation
1769a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        public static int myUserId() {
1779a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov            return sUid;
1789a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        }
1799a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov
1809a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        @Resetter
1819a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        public static void reset() {
1829a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov            sUid = 0;
1839a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov        }
1849a5220e7c3c9730b3cb362dab898e5f8ae8d6d5bAnton Philippov    }
185f8b3154586c48dd26fac3545b614e1ff6fc5cf70Anton Philippov}
186