1 /*
2  * Copyright 2018 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 package com.android.settings.connecteddevice;
17 
18 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
19 
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import static org.mockito.Mockito.spy;
23 
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.ActivityInfo;
28 import android.content.pm.ApplicationInfo;
29 import android.content.pm.ResolveInfo;
30 import android.nfc.NfcAdapter;
31 import android.provider.Settings;
32 
33 import androidx.test.core.content.pm.ApplicationInfoBuilder;
34 
35 import com.android.settings.R;
36 import com.android.settings.nfc.NfcPreferenceController;
37 
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.mockito.MockitoAnnotations;
42 import org.robolectric.RobolectricTestRunner;
43 import org.robolectric.RuntimeEnvironment;
44 import org.robolectric.Shadows;
45 import org.robolectric.annotation.Config;
46 import org.robolectric.shadows.ShadowNfcAdapter;
47 import org.robolectric.shadows.ShadowPackageManager;
48 import org.robolectric.util.ReflectionHelpers;
49 
50 @RunWith(RobolectricTestRunner.class)
51 @Config(shadows = ShadowNfcAdapter.class)
52 public class AdvancedConnectedDeviceControllerTest {
53 
54     private static final String KEY = "test_key";
55     private static final String DRIVING_MODE_SETTINGS_ENABLED =
56             "gearhead:driving_mode_settings_enabled";
57     private static final String ANDROID_AUTO_PACKAGE = "com.google.android.projection.gearhead";
58 
59     private Context mContext;
60     private NfcPreferenceController mNfcController;
61     private ShadowNfcAdapter mShadowNfcAdapter;
62     private ContentResolver mContentResolver;
63     private ShadowPackageManager mShadowPackageManager;
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68 
69         mContext = spy(RuntimeEnvironment.application);
70         mContentResolver = mContext.getContentResolver();
71         mNfcController = new NfcPreferenceController(mContext,
72                 NfcPreferenceController.KEY_TOGGLE_NFC);
73         mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext));
74         mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
75     }
76 
77     @Test
getAvailabilityStatus_returnStatusIsAvailable()78     public void getAvailabilityStatus_returnStatusIsAvailable() {
79         AdvancedConnectedDeviceController controller =
80                 new AdvancedConnectedDeviceController(mContext, KEY);
81 
82         assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
83     }
84 
85     @Test
isDrivingModeAvailable_returnTrue()86     public void isDrivingModeAvailable_returnTrue() {
87         Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1);
88 
89         assertThat(
90             AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue();
91     }
92 
93     @Test
isDrivingModeAvailable_returnFalse()94     public void isDrivingModeAvailable_returnFalse() {
95         Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0);
96 
97         assertThat(
98             AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse();
99     }
100 
101     @Test
isAndroidAutoSettingAvailable_returnTrue()102     public void isAndroidAutoSettingAvailable_returnTrue() {
103         final ApplicationInfo appInfo =
104                 ApplicationInfoBuilder.newBuilder().setPackageName(ANDROID_AUTO_PACKAGE).build();
105         final ActivityInfo activityInfo = new ActivityInfo();
106         activityInfo.packageName = ANDROID_AUTO_PACKAGE;
107         activityInfo.name = ANDROID_AUTO_PACKAGE;
108         activityInfo.applicationInfo = appInfo;
109         final ResolveInfo resolveInfo = new ResolveInfo();
110         resolveInfo.activityInfo = activityInfo;
111         mShadowPackageManager.addResolveInfoForIntent(
112                 buildAndroidAutoSettingsIntent(),
113                 resolveInfo);
114 
115         assertThat(
116             AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isTrue();
117     }
118 
119     @Test
isAndroidAutoSettingAvailable_returnFalse()120     public void isAndroidAutoSettingAvailable_returnFalse() {
121         // No ResolveInfo for Android Auto, expect false.
122         assertThat(
123             AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isFalse();
124     }
125 
126     @Test
getConnectedDevicesSummaryResourceId_NFCAndDrivingModeAvailable()127     public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeAvailable() {
128         // NFC available, driving mode available
129         mShadowNfcAdapter.setEnabled(true);
130         assertThat(AdvancedConnectedDeviceController
131                 .getConnectedDevicesSummaryResourceId(mNfcController, true, false))
132                 .isEqualTo(R.string.connected_devices_dashboard_summary);
133     }
134 
135     @Test
getConnectedDevicesSummaryResourceId_NFCAvailableAndDrivingModeNotAvailable()136     public void getConnectedDevicesSummaryResourceId_NFCAvailableAndDrivingModeNotAvailable() {
137         // NFC is available, driving mode not available
138         mShadowNfcAdapter.setEnabled(true);
139         assertThat(AdvancedConnectedDeviceController
140                 .getConnectedDevicesSummaryResourceId(mNfcController, false, false))
141                 .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary);
142     }
143 
144     @Test
getConnectedDevicesSummaryResourceId_NFCNotAvailableDrivingModeAvailable()145     public void getConnectedDevicesSummaryResourceId_NFCNotAvailableDrivingModeAvailable() {
146         // NFC not available, driving mode available
147         ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
148         assertThat(AdvancedConnectedDeviceController
149                 .getConnectedDevicesSummaryResourceId(mNfcController, true, false))
150                 .isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary);
151     }
152 
153     @Test
getConnectedDevicesSummaryResourceId_NFCAndDrivingModeNotAvailable()154     public void getConnectedDevicesSummaryResourceId_NFCAndDrivingModeNotAvailable() {
155         // NFC not available, driving mode not available
156         ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
157         assertThat(AdvancedConnectedDeviceController
158                 .getConnectedDevicesSummaryResourceId(mNfcController, false, false))
159                 .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary);
160     }
161 
162     @Test
getConnectedDevicesSummaryResourceId_Auto_NFC_DrivingMode_Available()163     public void getConnectedDevicesSummaryResourceId_Auto_NFC_DrivingMode_Available() {
164         // NFC available, driving mode available
165         mShadowNfcAdapter.setEnabled(true);
166         assertThat(AdvancedConnectedDeviceController
167                 .getConnectedDevicesSummaryResourceId(mNfcController, true, true))
168                 .isEqualTo(R.string.connected_devices_dashboard_android_auto_summary);
169     }
170 
171     @Test
getConnectedDevicesSummaryResourceId_Auto_NFC_Available()172     public void getConnectedDevicesSummaryResourceId_Auto_NFC_Available() {
173         // NFC is available, driving mode not available
174         mShadowNfcAdapter.setEnabled(true);
175         assertThat(AdvancedConnectedDeviceController
176                 .getConnectedDevicesSummaryResourceId(mNfcController, false, true))
177                 .isEqualTo(
178                     R.string.connected_devices_dashboard_android_auto_no_driving_mode_summary);
179     }
180 
181     @Test
getConnectedDevicesSummaryResourceId_Auto_DrivingMode_Available()182     public void getConnectedDevicesSummaryResourceId_Auto_DrivingMode_Available() {
183         // NFC not available, driving mode available
184         ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
185         assertThat(AdvancedConnectedDeviceController
186                 .getConnectedDevicesSummaryResourceId(mNfcController, true, true))
187                 .isEqualTo(R.string.connected_devices_dashboard_android_auto_no_nfc_summary);
188     }
189 
190     @Test
getConnectedDevicesSummaryResourceId_Auto_Available()191     public void getConnectedDevicesSummaryResourceId_Auto_Available() {
192         // NFC not available, driving mode not available
193         ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null);
194         assertThat(AdvancedConnectedDeviceController
195                 .getConnectedDevicesSummaryResourceId(mNfcController, false, true))
196                 .isEqualTo(
197                     R.string.connected_devices_dashboard_android_auto_no_nfc_no_driving_mode);
198     }
199 
buildAndroidAutoSettingsIntent()200     private Intent buildAndroidAutoSettingsIntent() {
201         final Intent intent = new Intent("com.android.settings.action.IA_SETTINGS");
202         intent.setPackage(ANDROID_AUTO_PACKAGE);
203         return intent;
204     }
205 }
206 
207