Loading src/com/android/settings/wifi/slice/WifiSlice.java +37 −3 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ import android.app.PendingIntent; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; Loading @@ -49,8 +52,8 @@ import com.android.settings.network.WifiSwitchPreferenceController; import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.slices.SliceBuilderUtils; import com.android.settings.wifi.AppStateChangeWifiStateBridge; import com.android.settings.wifi.WifiDialogActivity; import com.android.settings.wifi.WifiSettings; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details.WifiNetworkDetailsFragment; import com.android.wifitrackerlib.WifiEntry; Loading @@ -67,6 +70,7 @@ public class WifiSlice implements CustomSliceable { @VisibleForTesting static final int DEFAULT_EXPANDED_ROW_COUNT = 3; private static final String TAG = "WifiSlice"; protected final Context mContext; protected final WifiManager mWifiManager; Loading @@ -83,6 +87,12 @@ public class WifiSlice implements CustomSliceable { @Override public Slice getSlice() { // If external calling package doesn't have Wi-Fi permission. if (!Utils.isSettingsIntelligence(mContext) && !isPermissionGranted(mContext)) { Log.i(TAG, "No wifi permissions to control wifi slice."); return null; } final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* wifiSliceItem */); if (!isWifiEnabled) { Loading Loading @@ -120,6 +130,30 @@ public class WifiSlice implements CustomSliceable { return listBuilder.build(); } private static boolean isPermissionGranted(Context settingsContext) { final int callingUid = Binder.getCallingUid(); final String callingPackage = settingsContext.getPackageManager() .getPackagesForUid(callingUid)[0]; Context packageContext; try { packageContext = settingsContext.createPackageContext(callingPackage, 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Cannot create Context for package: " + callingPackage); return false; } // If app doesn't have related Wi-Fi permission, they shouldn't show Wi-Fi slice. final boolean hasPermission = packageContext.checkPermission( android.Manifest.permission.CHANGE_WIFI_STATE, Binder.getCallingPid(), callingUid) == PackageManager.PERMISSION_GRANTED; AppStateChangeWifiStateBridge.WifiSettingsState state = new AppStateChangeWifiStateBridge(settingsContext, null, null) .getWifiSettingsInfo(callingPackage, callingUid); return hasPermission && state.isPermissible(); } protected boolean isApRowCollapsed() { return false; } Loading tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiSlice.java 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.testutils.shadow; import android.content.Context; import com.android.settings.wifi.slice.WifiSlice; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @Implements(WifiSlice.class) public class ShadowWifiSlice { private static boolean sIsWifiPermissible; @Implementation protected static boolean isPermissionGranted(Context settingsContext) { return sIsWifiPermissible; } public static void setWifiPermissible(boolean isWifiPermissible) { sIsWifiPermissible = isWifiPermissible; } } tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java +13 −1 Original line number Diff line number Diff line Loading @@ -24,9 +24,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.wifi.WifiInfo; Loading @@ -44,6 +46,7 @@ import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.SlicesFeatureProviderImpl; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowConnectivityManager; import com.android.settings.testutils.shadow.ShadowWifiSlice; import org.junit.Before; import org.junit.Test; Loading @@ -53,17 +56,20 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowBinder; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowConnectivityManager.class) @Config(shadows = {ShadowConnectivityManager.class, ShadowWifiSlice.class}) public class ContextualWifiSliceTest { private static final String SSID = "123"; @Mock private WifiManager mWifiManager; @Mock private PackageManager mPackageManager; @Mock private WifiInfo mWifiInfo; @Mock private Network mNetwork; Loading @@ -88,10 +94,16 @@ public class ContextualWifiSliceTest { doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo(); doReturn(SSID).when(mWifiInfo).getSSID(); doReturn(mNetwork).when(mWifiManager).getCurrentNetwork(); when(mContext.getPackageManager()).thenReturn(mPackageManager); // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); final String siPackageName = mContext.getString(R.string.config_settingsintelligence_package_name); ShadowBinder.setCallingUid(1); when(mPackageManager.getPackagesForUid(1)).thenReturn(new String[]{siPackageName}); ShadowWifiSlice.setWifiPermissible(true); mWifiSlice = new ContextualWifiSlice(mContext); } Loading tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +39 −13 Original line number Diff line number Diff line Loading @@ -31,21 +31,20 @@ import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.net.wifi.WifiManager; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceItem; import androidx.slice.SliceMetadata; import androidx.slice.SliceProvider; import androidx.slice.core.SliceAction; import androidx.slice.core.SliceQuery; import androidx.slice.widget.SliceLiveData; import com.android.settings.R; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.SliceTester; import com.android.settings.testutils.shadow.ShadowWifiSlice; import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiEntry.ConnectedState; Loading @@ -59,24 +58,32 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowBinder; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = WifiSliceTest.ShadowSliceBackgroundWorker.class) @Config(shadows = { WifiSliceTest.ShadowSliceBackgroundWorker.class, ShadowWifiSlice.class}) public class WifiSliceTest { private static final String AP1_NAME = "ap1"; private static final String AP2_NAME = "ap2"; private static final String AP3_NAME = "ap3"; private static final int USER_ID = 1; @Mock private WifiManager mWifiManager; @Mock private PackageManager mPackageManager; private Context mContext; private ContentResolver mResolver; private WifiSlice mWifiSlice; private String mSIPackageName; @Before public void setUp() { Loading @@ -86,27 +93,46 @@ public class WifiSliceTest { doReturn(mResolver).when(mContext).getContentResolver(); doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); doReturn(WifiManager.WIFI_STATE_ENABLED).when(mWifiManager).getWifiState(); when(mContext.getPackageManager()).thenReturn(mPackageManager); // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); mSIPackageName = mContext.getString(R.string.config_settingsintelligence_package_name); ShadowBinder.setCallingUid(USER_ID); when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{mSIPackageName}); ShadowWifiSlice.setWifiPermissible(true); mWifiSlice = new WifiSlice(mContext); } @Test public void getWifiSlice_shouldHaveTitleAndToggle() { public void getWifiSlice_fromSIPackage_shouldHaveTitleAndToggle() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{mSIPackageName}); ShadowWifiSlice.setWifiPermissible(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertThat(wifiSlice).isNotNull(); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_notFromSIPackageAndWithWifiPermission_shouldHaveTitleAndToggle() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{"com.test"}); ShadowWifiSlice.setWifiPermissible(true); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNotNull(); } @Test public void getWifiSlice_notFromSIPackageAndWithoutWifiPermission_shouldNoSlice() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{"com.test"}); ShadowWifiSlice.setWifiPermissible(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); assertThat(wifiSlice).isNull(); } @Test Loading Loading
src/com/android/settings/wifi/slice/WifiSlice.java +37 −3 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ import android.app.PendingIntent; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.Binder; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; Loading @@ -49,8 +52,8 @@ import com.android.settings.network.WifiSwitchPreferenceController; import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.slices.SliceBuilderUtils; import com.android.settings.wifi.AppStateChangeWifiStateBridge; import com.android.settings.wifi.WifiDialogActivity; import com.android.settings.wifi.WifiSettings; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details.WifiNetworkDetailsFragment; import com.android.wifitrackerlib.WifiEntry; Loading @@ -67,6 +70,7 @@ public class WifiSlice implements CustomSliceable { @VisibleForTesting static final int DEFAULT_EXPANDED_ROW_COUNT = 3; private static final String TAG = "WifiSlice"; protected final Context mContext; protected final WifiManager mWifiManager; Loading @@ -83,6 +87,12 @@ public class WifiSlice implements CustomSliceable { @Override public Slice getSlice() { // If external calling package doesn't have Wi-Fi permission. if (!Utils.isSettingsIntelligence(mContext) && !isPermissionGranted(mContext)) { Log.i(TAG, "No wifi permissions to control wifi slice."); return null; } final boolean isWifiEnabled = isWifiEnabled(); ListBuilder listBuilder = getListBuilder(isWifiEnabled, null /* wifiSliceItem */); if (!isWifiEnabled) { Loading Loading @@ -120,6 +130,30 @@ public class WifiSlice implements CustomSliceable { return listBuilder.build(); } private static boolean isPermissionGranted(Context settingsContext) { final int callingUid = Binder.getCallingUid(); final String callingPackage = settingsContext.getPackageManager() .getPackagesForUid(callingUid)[0]; Context packageContext; try { packageContext = settingsContext.createPackageContext(callingPackage, 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Cannot create Context for package: " + callingPackage); return false; } // If app doesn't have related Wi-Fi permission, they shouldn't show Wi-Fi slice. final boolean hasPermission = packageContext.checkPermission( android.Manifest.permission.CHANGE_WIFI_STATE, Binder.getCallingPid(), callingUid) == PackageManager.PERMISSION_GRANTED; AppStateChangeWifiStateBridge.WifiSettingsState state = new AppStateChangeWifiStateBridge(settingsContext, null, null) .getWifiSettingsInfo(callingPackage, callingUid); return hasPermission && state.isPermissible(); } protected boolean isApRowCollapsed() { return false; } Loading
tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiSlice.java 0 → 100644 +39 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.testutils.shadow; import android.content.Context; import com.android.settings.wifi.slice.WifiSlice; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @Implements(WifiSlice.class) public class ShadowWifiSlice { private static boolean sIsWifiPermissible; @Implementation protected static boolean isPermissionGranted(Context settingsContext) { return sIsWifiPermissible; } public static void setWifiPermissible(boolean isWifiPermissible) { sIsWifiPermissible = isWifiPermissible; } }
tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java +13 −1 Original line number Diff line number Diff line Loading @@ -24,9 +24,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.wifi.WifiInfo; Loading @@ -44,6 +46,7 @@ import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.SlicesFeatureProviderImpl; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowConnectivityManager; import com.android.settings.testutils.shadow.ShadowWifiSlice; import org.junit.Before; import org.junit.Test; Loading @@ -53,17 +56,20 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowBinder; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowConnectivityManager.class) @Config(shadows = {ShadowConnectivityManager.class, ShadowWifiSlice.class}) public class ContextualWifiSliceTest { private static final String SSID = "123"; @Mock private WifiManager mWifiManager; @Mock private PackageManager mPackageManager; @Mock private WifiInfo mWifiInfo; @Mock private Network mNetwork; Loading @@ -88,10 +94,16 @@ public class ContextualWifiSliceTest { doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo(); doReturn(SSID).when(mWifiInfo).getSSID(); doReturn(mNetwork).when(mWifiManager).getCurrentNetwork(); when(mContext.getPackageManager()).thenReturn(mPackageManager); // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); final String siPackageName = mContext.getString(R.string.config_settingsintelligence_package_name); ShadowBinder.setCallingUid(1); when(mPackageManager.getPackagesForUid(1)).thenReturn(new String[]{siPackageName}); ShadowWifiSlice.setWifiPermissible(true); mWifiSlice = new ContextualWifiSlice(mContext); } Loading
tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +39 −13 Original line number Diff line number Diff line Loading @@ -31,21 +31,20 @@ import static org.mockito.Mockito.when; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.net.wifi.WifiManager; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceItem; import androidx.slice.SliceMetadata; import androidx.slice.SliceProvider; import androidx.slice.core.SliceAction; import androidx.slice.core.SliceQuery; import androidx.slice.widget.SliceLiveData; import com.android.settings.R; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.SliceTester; import com.android.settings.testutils.shadow.ShadowWifiSlice; import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiEntry.ConnectedState; Loading @@ -59,24 +58,32 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadows.ShadowBinder; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = WifiSliceTest.ShadowSliceBackgroundWorker.class) @Config(shadows = { WifiSliceTest.ShadowSliceBackgroundWorker.class, ShadowWifiSlice.class}) public class WifiSliceTest { private static final String AP1_NAME = "ap1"; private static final String AP2_NAME = "ap2"; private static final String AP3_NAME = "ap3"; private static final int USER_ID = 1; @Mock private WifiManager mWifiManager; @Mock private PackageManager mPackageManager; private Context mContext; private ContentResolver mResolver; private WifiSlice mWifiSlice; private String mSIPackageName; @Before public void setUp() { Loading @@ -86,27 +93,46 @@ public class WifiSliceTest { doReturn(mResolver).when(mContext).getContentResolver(); doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); doReturn(WifiManager.WIFI_STATE_ENABLED).when(mWifiManager).getWifiState(); when(mContext.getPackageManager()).thenReturn(mPackageManager); // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); mSIPackageName = mContext.getString(R.string.config_settingsintelligence_package_name); ShadowBinder.setCallingUid(USER_ID); when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{mSIPackageName}); ShadowWifiSlice.setWifiPermissible(true); mWifiSlice = new WifiSlice(mContext); } @Test public void getWifiSlice_shouldHaveTitleAndToggle() { public void getWifiSlice_fromSIPackage_shouldHaveTitleAndToggle() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{mSIPackageName}); ShadowWifiSlice.setWifiPermissible(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice); assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings)); assertThat(wifiSlice).isNotNull(); } final List<SliceAction> toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); @Test public void getWifiSlice_notFromSIPackageAndWithWifiPermission_shouldHaveTitleAndToggle() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{"com.test"}); ShadowWifiSlice.setWifiPermissible(true); final Slice wifiSlice = mWifiSlice.getSlice(); assertThat(wifiSlice).isNotNull(); } @Test public void getWifiSlice_notFromSIPackageAndWithoutWifiPermission_shouldNoSlice() { when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{"com.test"}); ShadowWifiSlice.setWifiPermissible(false); final Slice wifiSlice = mWifiSlice.getSlice(); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_wireless); assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString()); assertThat(wifiSlice).isNull(); } @Test Loading