1 /* 2 * Copyright (C) 2020 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 android.settings.cts; 18 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 import static android.provider.Settings.Secure; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.junit.Assume.assumeFalse; 25 26 import android.app.slice.Slice; 27 import android.app.slice.SliceManager; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.pm.PackageManager; 32 import android.content.pm.PackageManager.NameNotFoundException; 33 import android.content.pm.ResolveInfo; 34 import android.net.Uri; 35 import android.net.wifi.WifiManager; 36 import android.os.Process; 37 import android.text.TextUtils; 38 import android.util.Log; 39 40 import androidx.slice.SliceConvert; 41 import androidx.slice.SliceMetadata; 42 import androidx.slice.core.SliceAction; 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.runner.AndroidJUnit4; 45 46 import org.junit.After; 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 51 import java.util.Collections; 52 import java.util.List; 53 54 @RunWith(AndroidJUnit4.class) 55 public class WifiSliceTest { 56 private static final String TAG = "WifiSliceTest"; 57 58 private static final Uri WIFI_SLICE_URI = 59 Uri.parse("content://android.settings.slices/action/wifi"); 60 61 private static final String ACTION_ASSIST = "android.intent.action.ASSIST"; 62 private static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; 63 private static final String CATEGORY_DEFAULT = "android.intent.category.DEFAULT"; 64 private static final String FEATURE_VOICE_RECOGNIZERS = "android.software.voice_recognizers"; 65 private static final String ASSISTANT = "assistant"; 66 67 private final Context mContext = InstrumentationRegistry.getContext(); 68 private final SliceManager mSliceManager = mContext.getSystemService(SliceManager.class); 69 private final boolean mHasVoiceRecognizersFeature = 70 mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS); 71 72 private Slice mWifiSlice; 73 private String mAssistant; 74 75 @Before setUp()76 public void setUp() throws Exception { 77 assumeFalse("Skipping test: Auto does not support provider android.settings.slices", isCar()); 78 assumeFalse("Skipping test: TV does not support provider android.settings.slices", isTv()); 79 assumeFalse( 80 "Skipping test: Watch does not support provider android.settings.slices", isWatch()); 81 mWifiSlice = mSliceManager.bindSlice(WIFI_SLICE_URI, Collections.emptySet()); 82 mAssistant = Secure.getString(mContext.getContentResolver(), ASSISTANT); 83 } 84 85 @After tearDown()86 public void tearDown() { 87 final String assistant = Secure.getString(mContext.getContentResolver(), ASSISTANT); 88 if (!TextUtils.equals(mAssistant, assistant)) { 89 Secure.putString(mContext.getContentResolver(), ASSISTANT, mAssistant); 90 } 91 } 92 93 @Test wifiSliceToggle_changeWifiState()94 public void wifiSliceToggle_changeWifiState() { 95 SliceMetadata mWifiSliceMetadata = 96 SliceMetadata.from(mContext, SliceConvert.wrap(mWifiSlice, mContext)); 97 List<SliceAction> wifiSliceActions = mWifiSliceMetadata.getToggles(); 98 if (wifiSliceActions.size() != 0) { 99 SliceAction toggleAction = wifiSliceActions.get(0); 100 101 toggleAction.setChecked(true); 102 assertThat(toggleAction.isChecked()).isEqualTo(isWifiEnabled()); 103 104 toggleAction.setChecked(false); 105 assertThat(toggleAction.isChecked()).isEqualTo(isWifiEnabled()); 106 } 107 } 108 109 @Test wifiSlice_hasCorrectUri()110 public void wifiSlice_hasCorrectUri() { 111 assertThat(mWifiSlice.getUri()).isEqualTo(WIFI_SLICE_URI); 112 } 113 114 @Test wifiSlice_grantedPermissionToDefaultAssistant()115 public void wifiSlice_grantedPermissionToDefaultAssistant() throws NameNotFoundException { 116 if (!mHasVoiceRecognizersFeature) { 117 Log.i(TAG, "The device doesn't support feature: " + FEATURE_VOICE_RECOGNIZERS); 118 return; 119 } 120 final PackageManager pm = mContext.getPackageManager(); 121 final Intent requestDefaultAssistant = 122 new Intent(ACTION_ASSIST).addCategory(CATEGORY_DEFAULT); 123 124 final List<ResolveInfo> infos = pm.queryIntentActivities(requestDefaultAssistant, 0); 125 126 if (!infos.isEmpty()) { 127 final String packageName; 128 if (!TextUtils.isEmpty(mAssistant)) { 129 packageName = ComponentName.unflattenFromString(mAssistant).getPackageName(); 130 Log.i(TAG, "Default assistant: " + packageName); 131 } else { 132 packageName = infos.get(0).activityInfo.packageName; 133 Log.i(TAG, "Set assistant: " + packageName); 134 Secure.putString(mContext.getContentResolver(), ASSISTANT, 135 new ComponentName(packageName, infos.get(0).activityInfo.name).flattenToString()); 136 } 137 final int testPid = Process.myPid(); 138 final int testUid = pm.getPackageUid(packageName, 0); 139 140 assertThat(mSliceManager.checkSlicePermission(WIFI_SLICE_URI, testPid, testUid)) 141 .isEqualTo(PERMISSION_GRANTED); 142 } 143 } 144 145 @Test wifiSlice_grantedPermissionToDefaultVoiceAssistant()146 public void wifiSlice_grantedPermissionToDefaultVoiceAssistant() throws NameNotFoundException { 147 if (!mHasVoiceRecognizersFeature) { 148 Log.i(TAG, "The device doesn't support feature: " + FEATURE_VOICE_RECOGNIZERS); 149 return; 150 } 151 final PackageManager pm = mContext.getPackageManager(); 152 final Intent requestDefaultAssistant = 153 new Intent(ACTION_VOICE_ASSIST).addCategory(CATEGORY_DEFAULT); 154 155 final ResolveInfo info = pm.resolveActivity(requestDefaultAssistant, 0); 156 157 if (info != null) { 158 final String packageName; 159 if (!TextUtils.isEmpty(mAssistant)) { 160 packageName = ComponentName.unflattenFromString(mAssistant).getPackageName(); 161 Log.i(TAG, "Default assistant: " + packageName); 162 } else { 163 packageName = info.activityInfo.packageName; 164 Log.i(TAG, "Set assistant: " + packageName); 165 Secure.putString(mContext.getContentResolver(), ASSISTANT, 166 new ComponentName(packageName, info.activityInfo.name).flattenToString()); 167 } 168 final int testPid = Process.myPid(); 169 final int testUid = pm.getPackageUid(packageName, 0); 170 171 assertThat(mSliceManager.checkSlicePermission(WIFI_SLICE_URI, testPid, testUid)) 172 .isEqualTo(PERMISSION_GRANTED); 173 } 174 } 175 isCar()176 private boolean isCar() { 177 PackageManager pm = mContext.getPackageManager(); 178 return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 179 } 180 isTv()181 private boolean isTv() { 182 PackageManager pm = mContext.getPackageManager(); 183 return pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION) 184 && pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK); 185 } 186 isWatch()187 private boolean isWatch() { 188 return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); 189 } 190 isWifiEnabled()191 private boolean isWifiEnabled() { 192 final WifiManager wifiManager = mContext.getSystemService(WifiManager.class); 193 return wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED 194 || wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLING; 195 } 196 197 } 198