diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 651ef48eb5b..c13068fb29c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1394,7 +1394,7 @@ + android:theme="@style/GlifV3Theme.Light"> diff --git a/res/drawable-hdpi/ic_sim_sd.png b/res/drawable-hdpi/ic_sim_sd.png deleted file mode 100644 index 50a16dbbbb8..00000000000 Binary files a/res/drawable-hdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_sim_sd.png b/res/drawable-mdpi/ic_sim_sd.png deleted file mode 100644 index 19266089bcc..00000000000 Binary files a/res/drawable-mdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xhdpi/ic_sim_sd.png b/res/drawable-xhdpi/ic_sim_sd.png deleted file mode 100644 index 1a0842b68f1..00000000000 Binary files a/res/drawable-xhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xxhdpi/ic_sim_sd.png b/res/drawable-xxhdpi/ic_sim_sd.png deleted file mode 100644 index e05e7adc254..00000000000 Binary files a/res/drawable-xxhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xxxhdpi/ic_sim_sd.png b/res/drawable-xxxhdpi/ic_sim_sd.png deleted file mode 100644 index b12e34efdfb..00000000000 Binary files a/res/drawable-xxxhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable/ic_sim_sd.xml b/res/drawable/ic_sim_sd.xml new file mode 100644 index 00000000000..d7e31a24809 --- /dev/null +++ b/res/drawable/ic_sim_sd.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/res/layout/settings_homepage.xml b/res/layout/settings_homepage.xml index 6e2b302541f..5710bace5eb 100644 --- a/res/layout/settings_homepage.xml +++ b/res/layout/settings_homepage.xml @@ -25,6 +25,7 @@ android:id="@+id/card_container" android:layout_width="match_parent" android:layout_height="match_parent" - android:layoutAnimation="@anim/layout_animation_fade_in"/> + android:layoutAnimation="@anim/layout_animation_fade_in" + android:importantForAccessibility="no"/> diff --git a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java index 56d53358aa5..7339f2132b2 100644 --- a/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppButtonsPreferenceController.java @@ -25,6 +25,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.om.OverlayManager; +import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -103,6 +105,7 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp private final int mRequestRemoveDeviceAdmin; private final DevicePolicyManager mDpm; private final UserManager mUserManager; + private final OverlayManager mOverlayManager; private final PackageManager mPm; private final SettingsActivity mActivity; private final InstrumentedPreferenceFragment mFragment; @@ -136,6 +139,7 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE); mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE); mPm = activity.getPackageManager(); + mOverlayManager = activity.getSystemService(OverlayManager.class); mPackageName = packageName; mActivity = activity; mFragment = fragment; @@ -435,6 +439,28 @@ public class AppButtonsPreferenceController extends BasePreferenceController imp enabled = false; } + // Resource overlays can be uninstalled iff they are public + // (installed on /data) and disabled. ("Enabled" means they + // are in use by resource management.) If they are + // system/vendor, they can never be uninstalled. :-( + if (mAppEntry.info.isResourceOverlay()) { + if (isBundled) { + enabled = false; + } else { + String pkgName = mAppEntry.info.packageName; + UserHandle user = UserHandle.getUserHandleForUid(mAppEntry.info.uid); + OverlayInfo overlayInfo = mOverlayManager.getOverlayInfo(pkgName, user); + if (overlayInfo != null && overlayInfo.isEnabled()) { + ApplicationsState.AppEntry targetEntry = + mState.getEntry(overlayInfo.targetPackageName, + UserHandle.getUserId(mAppEntry.info.uid)); + if (targetEntry != null) { + enabled = false; + } + } + } + } + mButtonsPref.setButton2Enabled(enabled); } diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 183d3843447..766fa50acc5 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -640,10 +640,18 @@ public class AppInfoDashboardFragment extends DashboardFragment final BroadcastReceiver mPackageRemovedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + if (mFinishing) { + return; + } + final String packageName = intent.getData().getSchemeSpecificPart(); - if (!mFinishing && (mAppEntry == null || mAppEntry.info == null - || TextUtils.equals(mAppEntry.info.packageName, packageName))) { + if (mAppEntry == null + || mAppEntry.info == null + || TextUtils.equals(mAppEntry.info.packageName, packageName)) { onPackageRemoved(); + } else if (mAppEntry.info.isResourceOverlay() + && TextUtils.equals(mPackageInfo.overlayTarget, packageName)) { + refreshUi(); } } }; diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java index 2e52e6b4642..a24f82b3535 100644 --- a/src/com/android/settings/deviceinfo/StorageSettings.java +++ b/src/com/android/settings/deviceinfo/StorageSettings.java @@ -23,8 +23,6 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.os.UserHandle; @@ -76,16 +74,6 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index private static final String TAG_DISK_INIT = "disk_init"; private static final int METRICS_CATEGORY = SettingsEnums.DEVICEINFO_STORAGE; - static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e"); - - static final int[] COLOR_PRIVATE = new int[]{ - Color.parseColor("#ff26a69a"), - Color.parseColor("#ffab47bc"), - Color.parseColor("#fff2a600"), - Color.parseColor("#ffec407a"), - Color.parseColor("#ffc0ca33"), - }; - private StorageManager mStorageManager; private PreferenceCategory mInternalCategory; @@ -176,13 +164,12 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index if (vol.getType() == VolumeInfo.TYPE_PRIVATE) { final long volumeTotalBytes = PrivateStorageInfo.getTotalSize(vol, sTotalInternalStorage); - final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length]; mInternalCategory.addPreference( - new StorageVolumePreference(context, vol, color, volumeTotalBytes)); + new StorageVolumePreference(context, vol, volumeTotalBytes)); } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC || vol.getType() == VolumeInfo.TYPE_STUB) { mExternalCategory.addPreference( - new StorageVolumePreference(context, vol, COLOR_PUBLIC, 0)); + new StorageVolumePreference(context, vol, 0)); } } @@ -192,15 +179,11 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index if (rec.getType() == VolumeInfo.TYPE_PRIVATE && mStorageManager.findVolumeByUuid(rec.getFsUuid()) == null) { // TODO: add actual storage type to record - final Drawable icon = context.getDrawable(R.drawable.ic_sim_sd); - icon.mutate(); - icon.setTint(COLOR_PUBLIC); - final Preference pref = new Preference(context); pref.setKey(rec.getFsUuid()); pref.setTitle(rec.getNickname()); pref.setSummary(com.android.internal.R.string.ext_media_status_missing); - pref.setIcon(icon); + pref.setIcon(R.drawable.ic_sim_sd); mInternalCategory.addPreference(pref); } } diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreference.java b/src/com/android/settings/deviceinfo/StorageVolumePreference.java index 14fd42e23d4..0734c0b66ad 100644 --- a/src/com/android/settings/deviceinfo/StorageVolumePreference.java +++ b/src/com/android/settings/deviceinfo/StorageVolumePreference.java @@ -50,16 +50,16 @@ public class StorageVolumePreference extends Preference { private final StorageManager mStorageManager; private final VolumeInfo mVolume; - private int mColor; private int mUsedPercent = -1; + private ColorStateList mColorTintList; // TODO: ideally, VolumeInfo should have a total physical size. - public StorageVolumePreference(Context context, VolumeInfo volume, int color, long totalBytes) { + public StorageVolumePreference(Context context, VolumeInfo volume, long totalBytes) { super(context); mStorageManager = context.getSystemService(StorageManager.class); mVolume = volume; - mColor = color; + mColorTintList = Utils.getColorAttr(context, android.R.attr.colorControlNormal); setLayoutResource(R.layout.storage_volume); @@ -107,8 +107,10 @@ public class StorageVolumePreference extends Preference { } if (freeBytes < mStorageManager.getStorageLowBytes(path)) { - mColor = Utils.getColorAttrDefaultColor(context, android.R.attr.colorError); + mColorTintList = Utils.getColorAttr(context, android.R.attr.colorError); icon = context.getDrawable(R.drawable.ic_warning_24dp); + icon.mutate(); + icon.setTintList(mColorTintList); } } else { @@ -116,8 +118,6 @@ public class StorageVolumePreference extends Preference { mUsedPercent = -1; } - icon.mutate(); - icon.setTint(mColor); setIcon(icon); if (volume.getType() == VolumeInfo.TYPE_PUBLIC @@ -138,7 +138,7 @@ public class StorageVolumePreference extends Preference { if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE && mUsedPercent != -1) { progress.setVisibility(View.VISIBLE); progress.setProgress(mUsedPercent); - progress.setProgressTintList(ColorStateList.valueOf(mColor)); + progress.setProgressTintList(mColorTintList); } else { progress.setVisibility(View.GONE); } diff --git a/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java index 341e0612568..c6466e8d697 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java @@ -113,8 +113,8 @@ public class GrayscaleConditionController implements ConditionalCardController { } private void sendBroadcast() { - final Intent intent = new Intent(); - intent.setAction(ACTION_GRAYSCALE_CHANGED); + final Intent intent = new Intent(ACTION_GRAYSCALE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); mAppContext.sendBroadcast(intent, Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS); } diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java index 0a846de317f..b5982243e2c 100644 --- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java +++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java @@ -41,21 +41,28 @@ import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS; import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS; import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS; import static android.provider.SearchIndexablesContract.SITE_MAP_COLUMNS; +import static android.provider.SearchIndexablesContract.SLICE_URI_PAIRS_COLUMNS; import static com.android.settings.dashboard.DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP; +import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.database.MatrixCursor; +import android.net.Uri; import android.provider.SearchIndexableResource; import android.provider.SearchIndexablesContract; import android.provider.SearchIndexablesProvider; +import android.provider.SettingsSlicesContract; import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; +import androidx.slice.SliceViewManager; + import com.android.settings.SettingsActivity; import com.android.settings.overlay.FeatureFactory; +import com.android.settings.slices.SettingsSliceProvider; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; @@ -184,6 +191,33 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { return cursor; } + @Override + public Cursor querySliceUriPairs() { + final SliceViewManager manager = SliceViewManager.getInstance(getContext()); + final MatrixCursor cursor = new MatrixCursor(SLICE_URI_PAIRS_COLUMNS); + final Uri baseUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .build(); + final Uri platformBaseUri = + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSlicesContract.AUTHORITY) + .build(); + + final Collection sliceUris = manager.getSliceDescendants(baseUri); + sliceUris.addAll(manager.getSliceDescendants(platformBaseUri)); + + for (Uri uri : sliceUris) { + cursor.newRow() + .add(SearchIndexablesContract.SliceUriPairColumns.KEY, uri.getLastPathSegment()) + .add(SearchIndexablesContract.SliceUriPairColumns.SLICE_URI, uri); + } + + return cursor; + } + private List getNonIndexableKeysFromProvider(Context context) { final Collection values = FeatureFactory.getFactory(context) .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues(); @@ -207,7 +241,7 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { if (System.getProperty(SYSPROP_CRASH_ON_ERROR) != null) { throw new RuntimeException(e); } - Log.e(TAG, "Error trying to get non-indexable keys from: " + clazz.getName() , e); + Log.e(TAG, "Error trying to get non-indexable keys from: " + clazz.getName(), e); continue; } diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 91672104e45..8e7b53a8388 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -564,7 +564,7 @@ public class WifiSettings extends RestrictedSettingsFragment */ switch (WifiUtils.getConnectingType(mSelectedAccessPoint)) { case WifiUtils.CONNECT_TYPE_OSU_PROVISION: - mSelectedAccessPoint.startOsuProvisioning(); + mSelectedAccessPoint.startOsuProvisioning(mConnectListener); mClickedConnect = true; break; diff --git a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java index 7b21b65a8e0..064037e2e5d 100644 --- a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java +++ b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java @@ -48,7 +48,7 @@ public class ConnectToWifiHandler extends Activity { void connect(AccessPoint accessPoint) { switch (WifiUtils.getConnectingType(accessPoint)) { case WifiUtils.CONNECT_TYPE_OSU_PROVISION: - accessPoint.startOsuProvisioning(); + accessPoint.startOsuProvisioning(null /* listener */); break; case WifiUtils.CONNECT_TYPE_OPEN_NETWORK: diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java new file mode 100644 index 00000000000..cf45d082f35 --- /dev/null +++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 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.wifi.slice; + +import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; + +import android.content.Context; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Bundle; + +import com.android.settings.slices.SliceBackgroundWorker; +import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.WifiTracker; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice. + */ +public class WifiScanWorker extends SliceBackgroundWorker + implements WifiTracker.WifiListener { + + private final Context mContext; + + private WifiTracker mWifiTracker; + + public WifiScanWorker(Context context, Uri uri) { + super(context, uri); + mContext = context; + } + + @Override + protected void onSlicePinned() { + if (mWifiTracker == null) { + mWifiTracker = new WifiTracker(mContext, this /* wifiListener */, + true /* includeSaved */, true /* includeScans */); + } + mWifiTracker.onStart(); + onAccessPointsChanged(); + } + + @Override + protected void onSliceUnpinned() { + mWifiTracker.onStop(); + } + + @Override + public void close() { + mWifiTracker.onDestroy(); + } + + @Override + public void onWifiStateChanged(int state) { + notifySliceChange(); + } + + @Override + public void onConnectedChanged() { + } + + @Override + public void onAccessPointsChanged() { + // in case state has changed + if (!mWifiTracker.getManager().isWifiEnabled()) { + updateResults(null); + return; + } + // AccessPoints are sorted by the WifiTracker + final List accessPoints = mWifiTracker.getAccessPoints(); + final List resultList = new ArrayList<>(); + for (AccessPoint ap : accessPoints) { + if (ap.isReachable()) { + resultList.add(clone(ap)); + if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { + break; + } + } + } + updateResults(resultList); + } + + private AccessPoint clone(AccessPoint accessPoint) { + final Bundle savedState = new Bundle(); + accessPoint.saveWifiState(savedState); + return new AccessPoint(mContext, savedState); + } + + @Override + protected boolean areListsTheSame(List a, List b) { + if (!a.equals(b)) { + return false; + } + + // compare access point states one by one + final int listSize = a.size(); + for (int i = 0; i < listSize; i++) { + if (getState(a.get(i)) != getState(b.get(i))) { + return false; + } + } + return true; + } + + private NetworkInfo.State getState(AccessPoint accessPoint) { + final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); + if (networkInfo != null) { + return networkInfo.getState(); + } + return null; + } +} \ No newline at end of file diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index f2c919b1733..d3df5fccb53 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -62,9 +62,7 @@ import com.android.settings.wifi.WifiSettings; import com.android.settings.wifi.WifiUtils; import com.android.settings.wifi.details.WifiNetworkDetailsFragment; import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.WifiTracker; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -362,97 +360,4 @@ public class WifiSlice implements CustomSliceable { public Class getBackgroundWorkerClass() { return WifiScanWorker.class; } - - public static class WifiScanWorker extends SliceBackgroundWorker - implements WifiTracker.WifiListener { - - private final Context mContext; - - private WifiTracker mWifiTracker; - - public WifiScanWorker(Context context, Uri uri) { - super(context, uri); - mContext = context; - } - - @Override - protected void onSlicePinned() { - if (mWifiTracker == null) { - mWifiTracker = new WifiTracker(mContext, this /* wifiListener */, - true /* includeSaved */, true /* includeScans */); - } - mWifiTracker.onStart(); - onAccessPointsChanged(); - } - - @Override - protected void onSliceUnpinned() { - mWifiTracker.onStop(); - } - - @Override - public void close() { - mWifiTracker.onDestroy(); - } - - @Override - public void onWifiStateChanged(int state) { - notifySliceChange(); - } - - @Override - public void onConnectedChanged() { - } - - @Override - public void onAccessPointsChanged() { - // in case state has changed - if (!mWifiTracker.getManager().isWifiEnabled()) { - updateResults(null); - return; - } - // AccessPoints are sorted by the WifiTracker - final List accessPoints = mWifiTracker.getAccessPoints(); - final List resultList = new ArrayList<>(); - for (AccessPoint ap : accessPoints) { - if (ap.isReachable()) { - resultList.add(clone(ap)); - if (resultList.size() >= DEFAULT_EXPANDED_ROW_COUNT) { - break; - } - } - } - updateResults(resultList); - } - - private AccessPoint clone(AccessPoint accessPoint) { - final Bundle savedState = new Bundle(); - accessPoint.saveWifiState(savedState); - return new AccessPoint(mContext, savedState); - } - - @Override - protected boolean areListsTheSame(List a, List b) { - if (!a.equals(b)) { - return false; - } - - // compare access point states one by one - final int listSize = a.size(); - for (int i = 0; i < listSize; i++) { - if (getState(a.get(i)) != getState(b.get(i))) { - return false; - } - } - return true; - } - - private State getState(AccessPoint accessPoint) { - final NetworkInfo networkInfo = accessPoint.getNetworkInfo(); - if (networkInfo != null) { - return networkInfo.getState(); - } - return null; - } - } } diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java index d6b12c35a32..a0a9de9c88a 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java @@ -39,6 +39,6 @@ public class AccessibilitySettingsForSetupWizardActivityTest { AccessibilitySettingsForSetupWizardActivity activity = Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class, intent).get(); - assertThat(activity.getThemeResId()).isEqualTo(R.style.GlifTheme_Light); + assertThat(activity.getThemeResId()).isEqualTo(R.style.GlifV3Theme_Light); } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java index 6d9430ccd26..ff33d26ea21 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java @@ -39,9 +39,12 @@ import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; +import android.content.om.OverlayManager; +import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.RemoteException; import android.os.UserManager; import android.view.View; @@ -70,11 +73,15 @@ import org.robolectric.util.ReflectionHelpers; public class AppButtonsPreferenceControllerTest { private static final String PACKAGE_NAME = "com.android.settings"; + private static final String RRO_PACKAGE_NAME = "com.android.settings.overlay"; private static final String RESOURCE_STRING = "string"; private static final boolean ALL_USERS = false; private static final boolean DISABLE_AFTER_INSTALL = true; private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; + private static final OverlayInfo OVERLAY_DISABLED = createFakeOverlay("overlay", false, 1); + private static final OverlayInfo OVERLAY_ENABLED = createFakeOverlay("overlay", true, 1); + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private SettingsActivity mSettingsActivity; @Mock @@ -88,6 +95,8 @@ public class AppButtonsPreferenceControllerTest { @Mock private ApplicationInfo mAppInfo; @Mock + private OverlayManager mOverlayManager; + @Mock private PackageManager mPackageManger; @Mock private DevicePolicyManager mDpm; @@ -113,6 +122,8 @@ public class AppButtonsPreferenceControllerTest { doReturn(mUserManager).when(mSettingsActivity).getSystemService(Context.USER_SERVICE); doReturn(mPackageManger).when(mSettingsActivity).getPackageManager(); doReturn(mAm).when(mSettingsActivity).getSystemService(Context.ACTIVITY_SERVICE); + doReturn(mOverlayManager).when(mSettingsActivity). + getSystemService(OverlayManager.class); doReturn(mAppEntry).when(mState).getEntry(anyString(), anyInt()); when(mSettingsActivity.getApplication()).thenReturn(mApplication); when(mSettingsActivity.getResources().getString(anyInt())).thenReturn(RESOURCE_STRING); @@ -276,6 +287,41 @@ public class AppButtonsPreferenceControllerTest { verify(mButtonPrefs).setButton2Enabled(false); } + @Test + public void updateUninstallButton_isSystemRro_setButtonDisable() { + mAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; + + when(mAppInfo.isResourceOverlay()).thenReturn(true); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(false); + } + + @Test + public void updateUninstallButton_isNonSystemRro_setButtonDisable() + throws RemoteException { + when(mAppInfo.isResourceOverlay()).thenReturn(true); + when(mOverlayManager.getOverlayInfo(anyString(), any())) + .thenReturn(OVERLAY_ENABLED); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(false); + } + + @Test + public void updateUninstallButton_isNonSystemRro_setButtonEnable() + throws RemoteException { + when(mAppInfo.isResourceOverlay()).thenReturn(true); + when(mOverlayManager.getOverlayInfo(anyString(), any())) + .thenReturn(OVERLAY_DISABLED); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(true); + } + @Test public void updateForceStopButton_HasActiveAdmins_setButtonDisable() { doReturn(true).when(mDpm).packageHasActiveAdmins(anyString()); @@ -418,4 +464,17 @@ public class AppButtonsPreferenceControllerTest { return pref; } + + private static OverlayInfo createFakeOverlay(String pkg, boolean enabled, int priority) { + final int state = (enabled) ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED; + return new OverlayInfo(pkg /* packageName */, + "target.package" /* targetPackageName */, + "theme" /* targetOverlayableName */, + "category", /* category */ + "package", /* baseCodePath */ + state, + 0 /* userId */, + priority, + false /* isStatic */); + } } diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 005ffbebc08..9f121306b8c 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -55,7 +55,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; -import com.android.settings.wifi.slice.WifiSlice; +import com.android.settings.wifi.slice.WifiScanWorker; import com.android.settingslib.wifi.WifiTracker; import org.junit.After; @@ -474,7 +474,7 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } - @Implements(WifiSlice.WifiScanWorker.class) + @Implements(WifiScanWorker.class) public static class ShadowWifiScanWorker { private static WifiTracker mWifiTracker; diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java index a7cf327a245..24b0b380434 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java @@ -78,7 +78,7 @@ public class ConnectToWifiHandlerTest { mHandler.connect(mAccessPoint); - verify(mAccessPoint).startOsuProvisioning(); + verify(mAccessPoint).startOsuProvisioning(null /* listener */); } diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java new file mode 100644 index 00000000000..7ddbce48a9f --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 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.wifi.slice; + +import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; + +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.verify; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.wifi.WifiManager; +import android.os.Bundle; + +import androidx.slice.SliceProvider; +import androidx.slice.widget.SliceLiveData; + +import com.android.settingslib.wifi.AccessPoint; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class WifiScanWorkerTest { + + private static final String AP_NAME = "ap"; + + private Context mContext; + private ContentResolver mResolver; + private WifiManager mWifiManager; + private WifiScanWorker mWifiScanWorker; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mResolver = mock(ContentResolver.class); + doReturn(mResolver).when(mContext).getContentResolver(); + mWifiManager = mContext.getSystemService(WifiManager.class); + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + mWifiManager.setWifiEnabled(true); + + mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); + } + + @Test + public void onWifiStateChanged_shouldNotifyChange() { + mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); + + verify(mResolver).notifyChange(WIFI_SLICE_URI, null); + } + + private AccessPoint createAccessPoint(String name, State state) { + final NetworkInfo info = mock(NetworkInfo.class); + doReturn(state).when(info).getState(); + + final Bundle savedState = new Bundle(); + savedState.putString("key_ssid", name); + savedState.putParcelable("key_networkinfo", info); + return new AccessPoint(mContext, savedState); + } + + @Test + public void SliceAccessPoint_sameState_shouldBeTheSame() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isTrue(); + } + + @Test + public void SliceAccessPoint_differentState_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTING); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isFalse(); + } + + @Test + public void SliceAccessPoint_differentLength_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + final List list = new ArrayList<>(); + list.add(ap1); + list.add(ap2); + + assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java index e9f35d8a31a..b2718fc0631 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java @@ -19,25 +19,20 @@ package com.android.settings.wifi.slice; import static android.app.slice.Slice.HINT_LIST_ITEM; import static android.app.slice.SliceItem.FORMAT_SLICE; -import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; -import static com.android.settings.wifi.slice.WifiSlice.WifiScanWorker; 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.verify; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.NetworkInfo; -import android.net.NetworkInfo.State; import android.net.Uri; import android.net.wifi.WifiManager; -import android.os.Bundle; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; @@ -53,6 +48,9 @@ import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.SliceTester; import com.android.settingslib.wifi.AccessPoint; +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -62,11 +60,8 @@ import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - @RunWith(RobolectricTestRunner.class) +@Config(shadows = WifiSliceTest.ShadowSliceBackgroundWorker.class) public class WifiSliceTest { private static final String AP1_NAME = "ap1"; @@ -76,7 +71,6 @@ public class WifiSliceTest { private ContentResolver mResolver; private WifiManager mWifiManager; private WifiSlice mWifiSlice; - private WifiScanWorker mWifiScanWorker; @Before public void setUp() { @@ -90,7 +84,6 @@ public class WifiSliceTest { mWifiManager.setWifiEnabled(true); mWifiSlice = new WifiSlice(mContext); - mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); } @Test @@ -160,13 +153,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_noReachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, false), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -177,11 +169,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveAp_shouldReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, true, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -191,13 +182,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveApAndOneUnreachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, true, true), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -208,11 +198,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneReachableAp_shouldNotReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -222,13 +211,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_allReachableAps_shouldNotReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, true), createAccessPoint(AP2_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -249,51 +237,6 @@ public class WifiSliceTest { assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED); } - @Test - public void onWifiStateChanged_shouldNotifyChange() { - mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); - - verify(mResolver).notifyChange(WIFI_SLICE_URI, null); - } - - private AccessPoint createAccessPoint(String name, State state) { - final NetworkInfo info = mock(NetworkInfo.class); - doReturn(state).when(info).getState(); - - final Bundle savedState = new Bundle(); - savedState.putString("key_ssid", name); - savedState.putParcelable("key_networkinfo", info); - return new AccessPoint(mContext, savedState); - } - - @Test - public void SliceAccessPoint_sameState_shouldBeTheSame() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isTrue(); - } - - @Test - public void SliceAccessPoint_differentState_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTING); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isFalse(); - } - @Test - public void SliceAccessPoint_differentLength_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - final List list = new ArrayList<>(); - list.add(ap1); - list.add(ap2); - - assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); - } - @Implements(SliceBackgroundWorker.class) public static class ShadowSliceBackgroundWorker { private static WifiScanWorker mWifiScanWorker = mock(WifiScanWorker.class);