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 
17 package com.android.settings.applications.appinfo;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 import static org.robolectric.Shadows.shadowOf;
26 
27 import android.app.Activity;
28 import android.app.role.RoleManager;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.os.UserManager;
32 
33 import androidx.preference.Preference;
34 
35 import com.android.settings.R;
36 
37 import org.junit.Before;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.mockito.ArgumentCaptor;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 import org.robolectric.Robolectric;
44 import org.robolectric.RobolectricTestRunner;
45 import org.robolectric.annotation.Config;
46 import org.robolectric.shadows.ShadowActivity;
47 import org.robolectric.shadows.ShadowApplication;
48 import org.robolectric.shadows.ShadowUserManager;
49 
50 import java.util.Collections;
51 import java.util.concurrent.Executor;
52 import java.util.function.Consumer;
53 
54 @RunWith(RobolectricTestRunner.class)
55 @Config(shadows = ShadowUserManager.class)
56 public class DefaultAppShortcutPreferenceControllerBaseTest {
57 
58     private static final String TEST_PREFERENCE_KEY = "TestKey";
59     private static final String TEST_ROLE_NAME = "TestRole";
60     private static final String TEST_PACKAGE_NAME = "TestPackage";
61 
62     @Mock
63     private RoleManager mRoleManager;
64     @Mock
65     private Preference mPreference;
66 
67     private Activity mActivity;
68     private ShadowUserManager mShadowUserManager;
69 
70     private TestRolePreferenceController mController;
71 
72     @Before
setUp()73     public void setUp() {
74         MockitoAnnotations.initMocks(this);
75         ShadowApplication shadowApplication = ShadowApplication.getInstance();
76         shadowApplication.setSystemService(Context.ROLE_SERVICE, mRoleManager);
77         mActivity = Robolectric.setupActivity(Activity.class);
78         mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
79         mController = new TestRolePreferenceController(mActivity);
80         when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
81     }
82 
83     @Test
constructor_callsIsApplicationVisibleForRole()84     public void constructor_callsIsApplicationVisibleForRole() {
85         verify(mRoleManager).isApplicationVisibleForRole(eq(TEST_ROLE_NAME), eq(
86                 TEST_PACKAGE_NAME), any(Executor.class), any(Consumer.class));
87     }
88 
89     @Test
getAvailabilityStatus_isManagedProfile_shouldReturnDisabled()90     public void getAvailabilityStatus_isManagedProfile_shouldReturnDisabled() {
91         mShadowUserManager.setManagedProfile(true);
92 
93         assertThat(mController.getAvailabilityStatus()).isEqualTo(
94                 DefaultAppShortcutPreferenceControllerBase.DISABLED_FOR_USER);
95     }
96 
97     @Test
98     public void
getAvailabilityStatus_noCallback_shouldReturnUnsupported()99     getAvailabilityStatus_noCallback_shouldReturnUnsupported() {
100         assertThat(mController.getAvailabilityStatus()).isEqualTo(
101                 DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
102     }
103 
104     @Test
105     public void
getAvailabilityStatus_noCallbackForIsRoleNotVisible_shouldReturnUnsupported()106     getAvailabilityStatus_noCallbackForIsRoleNotVisible_shouldReturnUnsupported() {
107         setApplicationIsVisibleForRole(true);
108 
109         assertThat(mController.getAvailabilityStatus()).isEqualTo(
110                 DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
111     }
112 
113     @Test
getAvailabilityStatus_RoleIsNotVisible_shouldReturnUnsupported()114     public void getAvailabilityStatus_RoleIsNotVisible_shouldReturnUnsupported() {
115         setRoleIsVisible(false);
116         setApplicationIsVisibleForRole(true);
117 
118         assertThat(mController.getAvailabilityStatus()).isEqualTo(
119                 DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
120     }
121 
122     @Test
123     public void
getAvailabilityStatus_noCallbackForIsApplicationVisibleForRole_shouldReturnUnsupported()124     getAvailabilityStatus_noCallbackForIsApplicationVisibleForRole_shouldReturnUnsupported() {
125         setRoleIsVisible(true);
126 
127         assertThat(mController.getAvailabilityStatus()).isEqualTo(
128                 DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
129     }
130 
131     @Test
getAvailabilityStatus_applicationIsNotVisibleForRole_shouldReturnUnsupported()132     public void getAvailabilityStatus_applicationIsNotVisibleForRole_shouldReturnUnsupported() {
133         setRoleIsVisible(true);
134         setApplicationIsVisibleForRole(false);
135 
136         assertThat(mController.getAvailabilityStatus()).isEqualTo(
137                 DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
138     }
139 
140     @Test
getAvailabilityStatus_RoleVisibleAndApplicationVisible_shouldReturnAvailable()141     public void getAvailabilityStatus_RoleVisibleAndApplicationVisible_shouldReturnAvailable() {
142         setRoleIsVisible(true);
143         setApplicationIsVisibleForRole(true);
144 
145         assertThat(mController.getAvailabilityStatus()).isEqualTo(
146                 DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
147     }
148 
setRoleIsVisible(boolean visible)149     private void setRoleIsVisible(boolean visible) {
150         final ArgumentCaptor<Consumer<Boolean>> callbackCaptor = ArgumentCaptor.forClass(
151                 Consumer.class);
152         verify(mRoleManager).isRoleVisible(eq(TEST_ROLE_NAME), any(Executor.class),
153                 callbackCaptor.capture());
154         final Consumer<Boolean> callback = callbackCaptor.getValue();
155         callback.accept(visible);
156     }
157 
setApplicationIsVisibleForRole(boolean visible)158     private void setApplicationIsVisibleForRole(boolean visible) {
159         final ArgumentCaptor<Consumer<Boolean>> callbackCaptor = ArgumentCaptor.forClass(
160                 Consumer.class);
161         verify(mRoleManager).isApplicationVisibleForRole(eq(TEST_ROLE_NAME), eq(
162                 TEST_PACKAGE_NAME), any(Executor.class), callbackCaptor.capture());
163         final Consumer<Boolean> callback = callbackCaptor.getValue();
164         callback.accept(visible);
165     }
166 
167     @Test
updateState_isRoleHolder_shouldSetSummaryToYes()168     public void updateState_isRoleHolder_shouldSetSummaryToYes() {
169         when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.singletonList(
170                 TEST_PACKAGE_NAME));
171         final CharSequence yesText = mActivity.getText(R.string.yes);
172         mController.updateState(mPreference);
173 
174         verify(mPreference).setSummary(yesText);
175     }
176 
177     @Test
updateState_notRoleHoler_shouldSetSummaryToNo()178     public void updateState_notRoleHoler_shouldSetSummaryToNo() {
179         when(mRoleManager.getRoleHolders(eq(TEST_ROLE_NAME))).thenReturn(Collections.emptyList());
180         final CharSequence noText = mActivity.getText(R.string.no);
181         mController.updateState(mPreference);
182 
183         verify(mPreference).setSummary(noText);
184     }
185 
186     @Test
handlePreferenceTreeClick_shouldStartManageDefaultAppIntent()187     public void handlePreferenceTreeClick_shouldStartManageDefaultAppIntent() {
188         final ShadowActivity shadowActivity = shadowOf(mActivity);
189         mController.handlePreferenceTreeClick(mPreference);
190         final Intent intent = shadowActivity.getNextStartedActivity();
191 
192         assertThat(intent).isNotNull();
193         assertThat(intent.getAction()).isEqualTo(Intent.ACTION_MANAGE_DEFAULT_APP);
194         assertThat(intent.getStringExtra(Intent.EXTRA_ROLE_NAME)).isEqualTo(TEST_ROLE_NAME);
195     }
196 
197     private class TestRolePreferenceController extends DefaultAppShortcutPreferenceControllerBase {
198 
TestRolePreferenceController(Context context)199         private TestRolePreferenceController(Context context) {
200             super(context, TEST_PREFERENCE_KEY, TEST_ROLE_NAME, TEST_PACKAGE_NAME);
201         }
202     }
203 }
204