1 /* 2 * Copyright (C) 2024 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.datetime; 18 19 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 20 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 21 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.spy; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.Activity; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.pm.ActivityInfo; 36 import android.content.pm.ApplicationInfo; 37 import android.content.pm.PackageManager; 38 import android.content.pm.ResolveInfo; 39 import android.platform.test.annotations.DisableFlags; 40 import android.platform.test.annotations.EnableFlags; 41 import android.platform.test.flag.junit.SetFlagsRule; 42 43 import androidx.preference.Preference; 44 45 import com.android.settings.flags.Flags; 46 47 import org.junit.Before; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.ArgumentCaptor; 52 import org.mockito.Mock; 53 import org.mockito.junit.MockitoJUnit; 54 import org.mockito.junit.MockitoRule; 55 import org.robolectric.Robolectric; 56 import org.robolectric.RobolectricTestRunner; 57 58 @RunWith(RobolectricTestRunner.class) 59 public class TimeFeedbackPreferenceControllerTest { 60 61 private static final String PACKAGE = "com.android.settings.test"; 62 private static final String TEST_INTENT_URI = 63 "intent:#Intent;" 64 + "action=com.android.settings.test.LAUNCH_USER_FEEDBACK;" 65 + "package=com.android.settings.test.target;" 66 + "end"; 67 68 @Rule 69 public final MockitoRule mMockitoRule = MockitoJUnit.rule(); 70 71 @Rule 72 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 73 @Mock 74 private PackageManager mMockPackageManager; 75 private Context mContext; 76 77 @Before setUp()78 public void setUp() { 79 mContext = spy(Robolectric.setupActivity(Activity.class)); 80 } 81 82 @Test 83 @EnableFlags({Flags.FLAG_DATETIME_FEEDBACK}) emptyIntentUri_controllerNotAvailable()84 public void emptyIntentUri_controllerNotAvailable() { 85 String emptyIntentUri = ""; 86 TimeFeedbackPreferenceController controller = 87 new TimeFeedbackPreferenceController(mContext, mContext.getPackageManager(), 88 "test_key", emptyIntentUri); 89 assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); 90 } 91 92 @Test 93 @DisableFlags({Flags.FLAG_DATETIME_FEEDBACK}) datetimeFeedbackDisabled_controllerNotAvailable()94 public void datetimeFeedbackDisabled_controllerNotAvailable() { 95 TimeFeedbackPreferenceController controller = 96 new TimeFeedbackPreferenceController( 97 mContext, mContext.getPackageManager(), "test_key", TEST_INTENT_URI); 98 assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); 99 } 100 101 @Test 102 @EnableFlags({Flags.FLAG_DATETIME_FEEDBACK}) validIntentUri_targetHandlerNotFound_returnsConditionallyUnavailable()103 public void validIntentUri_targetHandlerNotFound_returnsConditionallyUnavailable() { 104 when(mMockPackageManager.resolveActivity(any(), anyInt())).thenReturn(null); 105 106 TimeFeedbackPreferenceController controller = 107 new TimeFeedbackPreferenceController(mContext, mMockPackageManager, "test_key", 108 TEST_INTENT_URI); 109 110 assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 111 } 112 113 @Test 114 @EnableFlags({Flags.FLAG_DATETIME_FEEDBACK}) validIntentUri_targetHandlerAvailable_returnsAvailable()115 public void validIntentUri_targetHandlerAvailable_returnsAvailable() { 116 when(mMockPackageManager.resolveActivity(any(), anyInt())).thenReturn( 117 createDummyResolveInfo()); 118 119 TimeFeedbackPreferenceController controller = 120 new TimeFeedbackPreferenceController(mContext, mMockPackageManager, "test_key", 121 TEST_INTENT_URI); 122 123 assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); 124 } 125 126 @Test 127 @EnableFlags({Flags.FLAG_DATETIME_FEEDBACK}) clickPreference()128 public void clickPreference() { 129 Preference preference = new Preference(mContext); 130 131 TimeFeedbackPreferenceController controller = 132 new TimeFeedbackPreferenceController(mContext, mContext.getPackageManager(), 133 "test_key", TEST_INTENT_URI); 134 135 // Click a preference that's not controlled by this controller. 136 preference.setKey("fake_key"); 137 assertThat(controller.handlePreferenceTreeClick(preference)).isFalse(); 138 139 // Check for startActivity() call. 140 verify(mContext, never()).startActivity(any()); 141 142 // Click a preference controlled by this controller. 143 preference.setKey(controller.getPreferenceKey()); 144 assertThat(controller.handlePreferenceTreeClick(preference)).isTrue(); 145 146 // Check for startActivity() call. 147 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 148 verify(mContext).startActivity(intentCaptor.capture()); 149 Intent actualIntent = intentCaptor.getValue(); 150 assertThat(actualIntent.getAction()).isEqualTo( 151 "com.android.settings.test.LAUNCH_USER_FEEDBACK"); 152 assertThat(actualIntent.getPackage()).isEqualTo("com.android.settings.test.target"); 153 } 154 createDummyResolveInfo()155 private static ResolveInfo createDummyResolveInfo() { 156 ApplicationInfo applicationInfo = new ApplicationInfo(); 157 applicationInfo.packageName = PACKAGE; 158 ActivityInfo activityInfo = new ActivityInfo(); 159 activityInfo.applicationInfo = applicationInfo; 160 activityInfo.name = "TestActivity"; 161 162 ResolveInfo resolveInfo = new ResolveInfo(); 163 resolveInfo.activityInfo = activityInfo; 164 return resolveInfo; 165 } 166 } 167