1/*
2 * Copyright (C) 2017 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.providers.settings;
18
19import static junit.framework.Assert.assertEquals;
20import static junit.framework.Assert.assertFalse;
21import static junit.framework.Assert.assertTrue;
22
23import android.content.Context;
24import android.content.pm.UserInfo;
25import android.os.Process;
26import android.os.SystemClock;
27import android.os.UserManager;
28import android.provider.Settings;
29import android.support.test.InstrumentationRegistry;
30import android.support.test.filters.LargeTest;
31import android.util.Log;
32
33import org.junit.After;
34import org.junit.Before;
35import org.junit.Test;
36
37import java.io.BufferedReader;
38import java.io.FileInputStream;
39import java.io.IOException;
40import java.io.InputStreamReader;
41import java.util.ArrayList;
42import java.util.List;
43
44@LargeTest
45public class InstallNonMarketAppsDeprecationTest extends BaseSettingsProviderTest {
46
47    private static final String TAG = InstallNonMarketAppsDeprecationTest.class.getSimpleName();
48    private static final long USER_RESTRICTION_CHANGE_TIMEOUT = 5000;
49
50    private UserManager mUm;
51    private boolean mHasUserRestriction;
52    private boolean mSystemSetUserRestriction;
53    private List<Integer> mUsersAddedByTest;
54
55    private String waitTillValueChanges(String errorMessage, String oldValue) {
56        boolean interrupted = false;
57        final long startTime = SystemClock.uptimeMillis();
58        String newValue = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
59        while (newValue.equals(oldValue) && SystemClock.uptimeMillis() <= (startTime
60                + USER_RESTRICTION_CHANGE_TIMEOUT)) {
61            try {
62                Thread.sleep(1000);
63            } catch (InterruptedException exc) {
64                interrupted = true;
65            }
66            newValue = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
67        }
68        if (interrupted) {
69            Thread.currentThread().interrupt();
70        }
71        assertFalse(errorMessage, oldValue.equals(newValue));
72        return newValue;
73    }
74
75    private String getSecureSettingForUserViaShell(int userId) throws IOException {
76        StringBuilder sb = new StringBuilder("settings get --user ");
77        sb.append(userId + " secure ");
78        sb.append(Settings.Secure.INSTALL_NON_MARKET_APPS);
79        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(
80                InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
81                        sb.toString()).getFileDescriptor())));
82        String line = reader.readLine();
83        return line.trim();
84    }
85
86    @Before
87    public void setUp() {
88        mUm = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
89        mHasUserRestriction = mUm.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
90        mSystemSetUserRestriction = mUm.getUserRestrictionSource(
91                UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle())
92                == UserManager.RESTRICTION_SOURCE_SYSTEM;
93        mUsersAddedByTest = new ArrayList<>();
94    }
95
96    @Test
97    public void testValueDefaults() throws Exception {
98        if (mHasUserRestriction) {
99            // Default values don't apply when user restriction is set. Pass.
100            Log.w(TAG, "User restriction for unknown sources set. Skipping testValueDefaults test");
101            return;
102        }
103        String value = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
104        assertEquals("install_non_market_apps should be 1", value, "1");
105
106        setSettingViaShell(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS, "0",
107                false);
108        resetSettingsViaShell(SETTING_TYPE_SECURE, Settings.RESET_MODE_TRUSTED_DEFAULTS);
109
110        value = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
111        assertEquals("install_non_market_apps not reset to 1", value, "1");
112    }
113
114    @Test
115    public void testValueForNewUser() throws Exception {
116        UserInfo newUser = mUm.createUser("TEST_USER", 0);
117        mUsersAddedByTest.add(newUser.id);
118        String value = getSecureSettingForUserViaShell(newUser.id);
119        assertEquals("install_non_market_apps should be 1 for a new user", value, "1");
120    }
121
122    @Test
123    public void testValueRespectsUserRestriction() {
124        String value = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
125        assertEquals(value, mHasUserRestriction ? "0" : "1");
126
127        if (mHasUserRestriction && !mSystemSetUserRestriction) {
128            // User restriction set by device policy. This case should be covered in DO/PO related
129            // tests. Pass.
130            Log.w(TAG, "User restriction set by PO/DO. Skipping testValueRespectsUserRestriction");
131            return;
132        }
133
134        mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, !mHasUserRestriction);
135        value = waitTillValueChanges(
136                "Changing user restriction did not change the value of install_non_market_apps",
137                value);
138        assertTrue("Invalid value", value.equals("1") || value.equals("0"));
139
140        mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, mHasUserRestriction);
141        value = waitTillValueChanges(
142                "Changing user restriction did not change the value of install_non_market_apps",
143                value);
144        assertTrue("Invalid value", value.equals("1") || value.equals("0"));
145    }
146
147    @After
148    public void tearDown() {
149        if (!mHasUserRestriction || mSystemSetUserRestriction) {
150            // The test may have modified the user restriction state. Restore it.
151            mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
152                    mHasUserRestriction);
153        }
154        for (int userId : mUsersAddedByTest) {
155            mUm.removeUser(userId);
156        }
157    }
158}
159