diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c8d9afff9ef..71840b1ff09 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1128,12 +1128,12 @@ - - + diff --git a/res/values/strings.xml b/res/values/strings.xml index 2b37268a1a7..c99d7adb683 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8948,8 +8948,6 @@ Camera not allowed Screenshot not allowed - - Can’t turn off backups Can’t open this app @@ -9749,8 +9747,6 @@ %d attempt %d attempts - - This device\'s data is being backed up This device is managed by your organization. diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml index 0aa1415bc35..4fa50e7aae5 100644 --- a/res/xml/enterprise_privacy_settings.xml +++ b/res/xml/enterprise_privacy_settings.xml @@ -83,9 +83,6 @@ - candidates = new ArrayList<>(); // Resolve that intent and check that the handleAllWebDataURI boolean is set final List list = packageManager.queryIntentActivitiesAsUser( - BROWSE_PROBE, PackageManager.MATCH_ALL, userId); + BROWSE_PROBE, 0 /* flags */, userId); if (list != null) { final Set addedPackages = new ArraySet<>(); for (ResolveInfo info : list) { @@ -181,13 +181,12 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont * Whether or not the pkg is the default browser */ public boolean isBrowserDefault(String pkg, int userId) { - String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); + final String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId); if (defaultPackage != null) { return defaultPackage.equals(pkg); } - final List list = mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE, - PackageManager.MATCH_ALL, userId); + final List list = getCandidates(mPackageManager, userId); // There is only 1 app, it must be the default browser. return list != null && list.size() == 1; } diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java index 41703fb18b0..ac1939ceed0 100644 --- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -137,9 +137,6 @@ public class ActionDisabledByAdminDialogHelper { case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: titleView.setText(R.string.disabled_by_policy_title_screen_capture); break; - case DevicePolicyManager.POLICY_MANDATORY_BACKUPS: - titleView.setText(R.string.disabled_by_policy_title_turn_off_backups); - break; case DevicePolicyManager.POLICY_SUSPEND_PACKAGES: titleView.setText(R.string.disabled_by_policy_title_suspend_packages); break; diff --git a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java b/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java deleted file mode 100644 index b24f8dcc89a..00000000000 --- a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2018 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.enterprise; - -import android.content.Context; - -import com.android.settings.core.BasePreferenceController; -import com.android.settings.overlay.FeatureFactory; - -public class BackupsEnabledPreferenceController extends BasePreferenceController { - - private static final String KEY_BACKUPS_ENABLED = "backups_enabled"; - private final EnterprisePrivacyFeatureProvider mFeatureProvider; - - public BackupsEnabledPreferenceController(Context context) { - super(context, KEY_BACKUPS_ENABLED); - mFeatureProvider = FeatureFactory.getFactory(context) - .getEnterprisePrivacyFeatureProvider(context); - } - - @Override - public int getAvailabilityStatus() { - return mFeatureProvider.areBackupsMandatory() ? AVAILABLE : DISABLED_FOR_USER; - } -} - diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java index 51d125d5c2f..048782ea35c 100644 --- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java +++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java @@ -124,9 +124,4 @@ public interface EnterprisePrivacyFeatureProvider { * profile (if any). */ int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile(); - - /* - * Returns whether backups are mandatory. - */ - boolean areBackupsMandatory(); } diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java index 5505683f851..40859885b0d 100644 --- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java +++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java @@ -234,11 +234,6 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe return activeAdmins; } - @Override - public boolean areBackupsMandatory() { - return null != mDpm.getMandatoryBackupTransport(); - } - protected static class EnterprisePrivacySpan extends ClickableSpan { private final Context mContext; diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java index f04c421429b..dab13954873 100644 --- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java +++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java @@ -84,7 +84,6 @@ public class EnterprisePrivacySettings extends DashboardFragment { exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(context)); exposureChangesCategoryControllers.add(new CaCertsManagedProfilePreferenceController( context)); - exposureChangesCategoryControllers.add(new BackupsEnabledPreferenceController(context)); controllers.addAll(exposureChangesCategoryControllers); controllers.add(new PreferenceCategoryController(context, "exposure_changes_category") .setChildren(exposureChangesCategoryControllers)); diff --git a/src/com/android/settings/homepage/CardContentLoader.java b/src/com/android/settings/homepage/CardContentLoader.java index 2a2ebad6f58..9805ae3e409 100644 --- a/src/com/android/settings/homepage/CardContentLoader.java +++ b/src/com/android/settings/homepage/CardContentLoader.java @@ -19,7 +19,7 @@ package com.android.settings.homepage; import android.content.Context; import android.database.Cursor; -import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import com.android.settingslib.utils.AsyncLoaderCompat; @@ -45,28 +45,22 @@ public class CardContentLoader extends AsyncLoaderCompat> { } - @Nullable + @NonNull @Override public List loadInBackground() { - List result; - try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getAllContextualCards()) { + final List result = new ArrayList<>(); + try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) { if (cursor.getCount() == 0) { //TODO(b/113372471): Load Default static cards and return 3 static cards - return new ArrayList<>(); + return result; } - result = buildContextualCardList(cursor); - } - return result; - } - - private List buildContextualCardList(Cursor cursor) { - final List result = new ArrayList<>(); - for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - final ContextualCard card = new ContextualCard(cursor); - if (card.isCustomCard()) { - //TODO(b/114688391): Load and generate custom card,then add into list - } else { - result.add(card); + for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { + final ContextualCard card = new ContextualCard(cursor); + if (card.isCustomCard()) { + //TODO(b/114688391): Load and generate custom card,then add into list + } else { + result.add(card); + } } } return result; diff --git a/src/com/android/settings/homepage/CardDatabaseHelper.java b/src/com/android/settings/homepage/CardDatabaseHelper.java index f0a347187ae..b53479ec5f2 100644 --- a/src/com/android/settings/homepage/CardDatabaseHelper.java +++ b/src/com/android/settings/homepage/CardDatabaseHelper.java @@ -192,7 +192,7 @@ public class CardDatabaseHelper extends SQLiteOpenHelper { return sCardDatabaseHelper; } - Cursor getAllContextualCards() { + Cursor getContextualCards() { final SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(CARD_TABLE, null /* columns */, null /* selection */, null /* selectionArgs */, null /* groupBy */, null /* having */, diff --git a/src/com/android/settings/homepage/ContextualCard.java b/src/com/android/settings/homepage/ContextualCard.java index 174a4372078..5bd265b398d 100644 --- a/src/com/android/settings/homepage/ContextualCard.java +++ b/src/com/android/settings/homepage/ContextualCard.java @@ -33,10 +33,10 @@ public class ContextualCard { /** * Flags indicating the type of the ContextualCard. */ - @IntDef({CardType.INVALID, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL}) + @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL}) @Retention(RetentionPolicy.SOURCE) public @interface CardType { - int INVALID = -1; + int DEFAULT = 0; int SLICE = 1; int SUGGESTION = 2; int CONDITIONAL = 3; diff --git a/src/com/android/settings/homepage/ContextualCardController.java b/src/com/android/settings/homepage/ContextualCardController.java index 921d72bda8a..e47f70ce397 100644 --- a/src/com/android/settings/homepage/ContextualCardController.java +++ b/src/com/android/settings/homepage/ContextualCardController.java @@ -16,8 +16,6 @@ package com.android.settings.homepage; -import java.util.List; - /** * Data controller for {@link ContextualCard}. */ @@ -26,12 +24,6 @@ public interface ContextualCardController { @ContextualCard.CardType int getCardType(); - /** - * When data is updated or changed, the new data should be passed to ContextualCardManager for list - * updating. - */ - void onDataUpdated(List cardList); - void onPrimaryClick(ContextualCard card); void onActionClick(ContextualCard card); diff --git a/src/com/android/settings/homepage/ContextualCardManager.java b/src/com/android/settings/homepage/ContextualCardManager.java index df20a6c2a4a..87b048ea959 100644 --- a/src/com/android/settings/homepage/ContextualCardManager.java +++ b/src/com/android/settings/homepage/ContextualCardManager.java @@ -18,8 +18,12 @@ package com.android.settings.homepage; import static com.android.settings.homepage.CardContentLoader.CARD_CONTENT_LOADER_ID; +import static java.util.stream.Collectors.groupingBy; + import android.content.Context; import android.os.Bundle; +import android.util.ArrayMap; +import android.util.Log; import android.widget.BaseAdapter; import androidx.annotation.NonNull; @@ -32,6 +36,9 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * This is a centralized manager of multiple {@link ContextualCardController}. @@ -57,18 +64,23 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade private final ControllerRendererPool mControllerRendererPool; private final Lifecycle mLifecycle; private final List mContextualCards; + private final List mLifecycleObservers; private ContextualCardUpdateListener mListener; - - public ContextualCardManager(Context context, Lifecycle lifecycle) { + public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) { mContext = context; mLifecycle = lifecycle; mContextualCards = new ArrayList<>(); + mLifecycleObservers = new ArrayList<>(); mControllerRendererPool = new ControllerRendererPool(); + //for data provided by Settings + for (int cardType : SETTINGS_CARDS) { + setupController(cardType); + } } - void startCardContentLoading(PersonalSettingsFragment fragment) { + void loadContextualCards(PersonalSettingsFragment fragment) { final CardContentLoaderCallbacks cardContentLoaderCallbacks = new CardContentLoaderCallbacks(mContext); cardContentLoaderCallbacks.setListener(this); @@ -77,71 +89,64 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade } private void loadCardControllers() { - if (mContextualCards != null) { - for (ContextualCard card : mContextualCards) { - setupController(card.getCardType()); - } - } - - //for data provided by Settings - for (int cardType : SETTINGS_CARDS) { - setupController(cardType); + for (ContextualCard card : mContextualCards) { + setupController(card.getCardType()); } } private void setupController(int cardType) { final ContextualCardController controller = mControllerRendererPool.getController(mContext, cardType); - if (controller != null) { - controller.setCardUpdateListener(this); - if (controller instanceof LifecycleObserver) { - if (mLifecycle != null) { - mLifecycle.addObserver((LifecycleObserver) controller); - } - } + if (controller == null) { + Log.w(TAG, "Cannot find ContextualCardController for type " + cardType); + return; + } + controller.setCardUpdateListener(this); + if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) { + mLifecycleObservers.add((LifecycleObserver) controller); + mLifecycle.addObserver((LifecycleObserver) controller); } } //TODO(b/111822376): implement sorting mechanism. - private void sortCards() { + private void sortCards(List cards) { //take mContextualCards as the source and do the ranking based on the rule. } @Override - public void onContextualCardUpdated(int cardType, List updateList) { + public void onContextualCardUpdated(Map> updateList) { //TODO(b/112245748): Should implement a DiffCallback. //Keep the old list for comparison. final List prevCards = mContextualCards; - //Remove the existing data that matches the certain cardType so as to insert the new data. - for (int i = mContextualCards.size() - 1; i >= 0; i--) { - if (mContextualCards.get(i).getCardType() == cardType) { - mContextualCards.remove(i); - } - } + final Set cardTypes = updateList.keySet(); + //Remove the existing data that matches the certain cardType before inserting new data. + final List cardsToKeep = mContextualCards + .stream() + .filter(card -> !cardTypes.contains(card.getCardType())) + .collect(Collectors.toList()); + final List allCards = new ArrayList<>(); + allCards.addAll(cardsToKeep); + allCards.addAll( + updateList.values().stream().flatMap(List::stream).collect(Collectors.toList())); - //Append the new data - mContextualCards.addAll(updateList); + sortCards(allCards); + //replace with the new data + mContextualCards.clear(); + mContextualCards.addAll(allCards); - sortCards(); + loadCardControllers(); if (mListener != null) { - mListener.onContextualCardUpdated(ContextualCard.CardType.INVALID, mContextualCards); + final Map> cardsToUpdate = new ArrayMap<>(); + cardsToUpdate.put(ContextualCard.CardType.DEFAULT, mContextualCards); + mListener.onContextualCardUpdated(cardsToUpdate); } } @Override - public void onFinishCardLoading(List contextualCards) { - mContextualCards.clear(); - if (contextualCards != null) { - mContextualCards.addAll(contextualCards); - } - - //Force card sorting here in case CardControllers of custom view have nothing to update - // for the first launch. - sortCards(); - - loadCardControllers(); + public void onFinishCardLoading(List cards) { + onContextualCardUpdated(cards.stream().collect(groupingBy(ContextualCard::getCardType))); } void setListener(ContextualCardUpdateListener listener) { @@ -152,7 +157,6 @@ public class ContextualCardManager implements CardContentLoader.CardContentLoade return mControllerRendererPool; } - static class CardContentLoaderCallbacks implements LoaderManager.LoaderCallbacks> { diff --git a/src/com/android/settings/homepage/ContextualCardRenderer.java b/src/com/android/settings/homepage/ContextualCardRenderer.java index 94fdb438f9e..315c09d93ca 100644 --- a/src/com/android/settings/homepage/ContextualCardRenderer.java +++ b/src/com/android/settings/homepage/ContextualCardRenderer.java @@ -31,15 +31,15 @@ public interface ContextualCardRenderer { int getViewType(); /** - * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder(ViewGroup, - * int)}, this method will be called to retrieve the corresponding + * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder}, + * this method will be called to retrieve the corresponding * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}. */ RecyclerView.ViewHolder createViewHolder(View view); /** - * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder(RecyclerView - * .ViewHolder, int)}, this method will be called to bind data to the + * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder}, + * this method will be called to bind data to the * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}. */ void bindView(RecyclerView.ViewHolder holder, ContextualCard card); diff --git a/src/com/android/settings/homepage/ContextualCardUpdateListener.java b/src/com/android/settings/homepage/ContextualCardUpdateListener.java index d307a8f563b..60dd3a7147a 100644 --- a/src/com/android/settings/homepage/ContextualCardUpdateListener.java +++ b/src/com/android/settings/homepage/ContextualCardUpdateListener.java @@ -17,15 +17,19 @@ package com.android.settings.homepage; import java.util.List; +import java.util.Map; /** * When {@link ContextualCardController} detects changes, it will notify the listeners registered. - * In our case, {@link ContextualCardManager} gets noticed. - * - * After the list of {@link ContextualCard} gets updated in{@link ContextualCardManager}, - * {@link ContextualCardManager} will notify the listeners registered, {@link - * ContextualCardsAdapter} in this case. */ public interface ContextualCardUpdateListener { - void onContextualCardUpdated(int cardType, List updateList); + + /** + * Called when a set of cards are updated. + * + * @param cards A map of updates grouped by {@link ContextualCard.CardType}. Values can be + * null, which means all cards from corresponding {@link + * ContextualCard.CardType} are removed. + */ + void onContextualCardUpdated(Map> cards); } \ No newline at end of file diff --git a/src/com/android/settings/homepage/ContextualCardsAdapter.java b/src/com/android/settings/homepage/ContextualCardsAdapter.java index e985343cd59..9ab88936790 100644 --- a/src/com/android/settings/homepage/ContextualCardsAdapter.java +++ b/src/com/android/settings/homepage/ContextualCardsAdapter.java @@ -26,9 +26,10 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; +import java.util.Map; -public class ContextualCardsAdapter extends RecyclerView.Adapter implements - ContextualCardUpdateListener { +public class ContextualCardsAdapter extends RecyclerView.Adapter + implements ContextualCardUpdateListener { static final int SPAN_COUNT = 2; private static final String TAG = "ContextualCardsAdapter"; @@ -101,7 +102,8 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter contextualCards) { + public void onContextualCardUpdated(Map> cards) { + final List contextualCards = cards.get(ContextualCard.CardType.DEFAULT); //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged() // instead. if (contextualCards == null) { diff --git a/src/com/android/settings/homepage/PersonalSettingsFragment.java b/src/com/android/settings/homepage/PersonalSettingsFragment.java index da41cd72f68..4a0041ea19d 100644 --- a/src/com/android/settings/homepage/PersonalSettingsFragment.java +++ b/src/com/android/settings/homepage/PersonalSettingsFragment.java @@ -43,7 +43,7 @@ public class PersonalSettingsFragment extends InstrumentedFragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle()); - mContextualCardManager.startCardContentLoading(this); + mContextualCardManager.loadContextualCards(this); } @Override diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java index 6701cfd0196..fbbab14ca3e 100644 --- a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java +++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java @@ -17,6 +17,7 @@ package com.android.settings.homepage.conditional; import android.content.Context; +import android.util.ArrayMap; import com.android.settings.homepage.ContextualCard; import com.android.settings.homepage.ContextualCardController; @@ -27,6 +28,7 @@ import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * This controller triggers the loading of conditional cards and monitors state changes to @@ -56,11 +58,6 @@ public class ConditionContextualCardController implements ContextualCardControll return ContextualCard.CardType.CONDITIONAL; } - @Override - public void onDataUpdated(List cardList) { - mListener.onContextualCardUpdated(getCardType(), cardList); - } - @Override public void onStart() { mConditionManager.startMonitoringStateChange(); @@ -96,7 +93,6 @@ public class ConditionContextualCardController implements ContextualCardControll .setActionText(condition.getActionText()) .setName(mContext.getPackageName() + "/" + condition.getTitle().toString()) - .setCardType(ContextualCard.CardType.CONDITIONAL) .setTitleText(condition.getTitle().toString()) .setSummaryText(condition.getSummary().toString()) .setIconDrawable(condition.getIcon()) @@ -106,7 +102,9 @@ public class ConditionContextualCardController implements ContextualCardControll } if (mListener != null) { - onDataUpdated(conditionCards); + final Map> conditionalCards = new ArrayMap<>(); + conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards); + mListener.onContextualCardUpdated(conditionalCards); } } } diff --git a/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java index 62a4956efcd..828f90b76de 100644 --- a/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java +++ b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java @@ -16,6 +16,8 @@ package com.android.settings.homepage.conditional; +import androidx.annotation.VisibleForTesting; + import com.android.settings.homepage.ContextualCard; /** @@ -38,6 +40,11 @@ public class ConditionalContextualCard extends ContextualCard { mActionText = builder.mActionText; } + @Override + public int getCardType() { + return CardType.CONDITIONAL; + } + public long getConditionId() { return mConditionId; } @@ -50,7 +57,7 @@ public class ConditionalContextualCard extends ContextualCard { return mActionText; } - static class Builder extends ContextualCard.Builder { + public static class Builder extends ContextualCard.Builder { private long mConditionId; private int mMetricsConstant; @@ -71,6 +78,12 @@ public class ConditionalContextualCard extends ContextualCard { return this; } + @Override + public Builder setCardType(int cardType) { + throw new IllegalArgumentException( + "Cannot change card type for " + getClass().getName()); + } + public ConditionalContextualCard build() { return new ConditionalContextualCard(this); } diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index 01f12283773..03b4ec30264 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -78,6 +78,12 @@ public class NotificationBackend { return row; } + public boolean isBlockable(Context context, ApplicationInfo info) { + final boolean blocked = getNotificationsBanned(info.packageName, info.uid); + final boolean systemApp = isSystemApp(context, info); + return !systemApp || (systemApp && blocked); + } + public AppRow loadAppRow(Context context, PackageManager pm, PackageInfo app) { final AppRow row = loadAppRow(context, pm, app.applicationInfo); recordCanBeBlocked(context, pm, app, row); diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java index a027aec7e1c..bbc01f50104 100644 --- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java +++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java @@ -82,17 +82,6 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC private Preference mSeeAllPref; private Preference mDivider; - static { - SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList( - "android", - "com.android.phone", - "com.android.settings", - "com.android.systemui", - "com.android.providers.calendar", - "com.android.providers.media" - )); - } - public RecentNotifyingAppsPreferenceController(Context context, NotificationBackend backend, Application app, Fragment host) { this(context, backend, app == null ? null : ApplicationsState.getInstance(app), host); @@ -226,6 +215,7 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC .setSourceMetricsCategory( MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS) .toIntent()); + pref.setEnabled(mNotificationBackend.isBlockable(mContext, appEntry.info)); pref.setOnPreferenceChangeListener((preference, newValue) -> { boolean blocked = !(Boolean) newValue; mNotificationBackend.setNotificationsEnabledForPackage( @@ -272,10 +262,6 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC * Whether or not the app should be included in recent list. */ private boolean shouldIncludePkgInRecents(String pkgName) { - if (SKIP_SYSTEM_PACKAGES.contains(pkgName)) { - Log.d(TAG, "System package, skipping " + pkgName); - return false; - } final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER) .setPackage(pkgName); diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index de67c10baac..2e6611fc185 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -465,8 +465,7 @@ public class WifiConfigController implements TextWatcher, } else { enabled = ipAndProxyFieldsAreValid(); } - if (mEapCaCertSpinner != null - && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) { + if (mAccessPointSecurity == AccessPoint.SECURITY_EAP) { String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem(); if (caCertSelection.equals(mUnspecifiedCertString)) { // Disallow submit if the user has not selected a CA certificate for an EAP network @@ -482,10 +481,8 @@ public class WifiConfigController implements TextWatcher, enabled = false; } } - if (mEapUserCertSpinner != null - && mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE - && ((String) mEapUserCertSpinner.getSelectedItem()) - .equals(mUnspecifiedCertString)) { + if (mAccessPointSecurity == AccessPoint.SECURITY_EAP + && mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) { // Disallow submit if the user has not selected a user certificate for an EAP network // configuration. enabled = false; diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java index 0ef1cf35cf8..4a482d08d25 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java @@ -18,9 +18,9 @@ package com.android.settings.applications.defaultapps; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -133,8 +133,11 @@ public class DefaultBrowserPreferenceControllerTest { @Test public void isBrowserDefault_onlyApp_shouldReturnTrue() { when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null); + final List resolveInfos = new ArrayList<>(); + final String PACKAGE_ONE = "pkg"; + resolveInfos.add(createResolveInfo(PACKAGE_ONE)); when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt())) - .thenReturn(Collections.singletonList(new ResolveInfo())); + .thenReturn(resolveInfos); assertThat(mController.isBrowserDefault("pkg", 0)).isTrue(); } @@ -161,6 +164,15 @@ public class DefaultBrowserPreferenceControllerTest { assertThat(defaultBrowserInfo.size()).isEqualTo(2); } + @Test + public void getCandidates_shouldQueryActivityWithFlagsEquals0() { + + mController.getCandidates(mPackageManager, 0 /* userId */); + + verify(mPackageManager).queryIntentActivitiesAsUser( + any(Intent.class), eq(0) /* flags */, eq(0) /* userId */); + } + private ResolveInfo createResolveInfo(String packageName) { final ResolveInfo info = new ResolveInfo(); info.handleAllWebDataURI = true; diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index 5321c1000ea..9b138a657a3 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -124,10 +124,6 @@ public class ActionDisabledByAdminDialogHelperTest { assertEquals(Shadows.shadowOf(textView).innerText(), mActivity.getString(R.string.disabled_by_policy_title_screen_capture)); - mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_MANDATORY_BACKUPS); - assertEquals(Shadows.shadowOf(textView).innerText(), - mActivity.getString(R.string.disabled_by_policy_title_turn_off_backups)); - mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_SUSPEND_PACKAGES); assertEquals(Shadows.shadowOf(textView).innerText(), mActivity.getString(R.string.disabled_by_policy_title_suspend_packages)); diff --git a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java deleted file mode 100644 index 4e6db05cb87..00000000000 --- a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2018 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.enterprise; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.content.Context; - -import androidx.preference.Preference; - -import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RuntimeEnvironment; - -@RunWith(SettingsRobolectricTestRunner.class) -public class BackupsEnabledPreferenceControllerTest { - - private static final String KEY_BACKUPS_ENABLED = "backups_enabled"; - - private Context mContext; - private FakeFeatureFactory mFeatureFactory; - - private BackupsEnabledPreferenceController mController; - - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mFeatureFactory = FakeFeatureFactory.setupForTest(); - mController = new BackupsEnabledPreferenceController(mContext); - } - - @Test - public void testIsAvailable() { - when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory()) - .thenReturn(false); - assertThat(mController.isAvailable()).isFalse(); - - when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory()) - .thenReturn(true); - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void testHandlePreferenceTreeClick() { - assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0))) - .isFalse(); - } - - @Test - public void testGetPreferenceKey() { - assertThat(mController.getPreferenceKey()).isEqualTo(KEY_BACKUPS_ENABLED); - } -} diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java index a7bd3293ef4..92c420af960 100644 --- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java @@ -346,15 +346,6 @@ public class EnterprisePrivacyFeatureProviderImplTest { .isEqualTo(3); } - @Test - public void testAreBackupsMandatory() { - assertThat(mProvider.areBackupsMandatory()).isFalse(); - ComponentName transportComponent = new ComponentName("test", "test"); - when(mDevicePolicyManager.getMandatoryBackupTransport()) - .thenReturn(transportComponent); - assertThat(mProvider.areBackupsMandatory()).isTrue(); - } - private void resetAndInitializePackageManager() { reset(mPackageManager); when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java index d37738dfb15..f1d03c74cb8 100644 --- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java @@ -99,7 +99,7 @@ public class EnterprisePrivacySettingsTest { private void verifyPreferenceControllers(List controllers) { assertThat(controllers).isNotNull(); - assertThat(controllers.size()).isEqualTo(18); + assertThat(controllers.size()).isEqualTo(17); int position = 0; assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class); assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class); @@ -126,8 +126,6 @@ public class EnterprisePrivacySettingsTest { CaCertsCurrentUserPreferenceController.class); assertThat(controllers.get(position++)).isInstanceOf( CaCertsManagedProfilePreferenceController.class); - assertThat(controllers.get(position++)).isInstanceOf( - BackupsEnabledPreferenceController.class); assertThat(controllers.get(position++)).isInstanceOf( PreferenceCategoryController.class); assertThat(controllers.get(position++)).isInstanceOf( diff --git a/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java new file mode 100644 index 00000000000..ced8b0691a8 --- /dev/null +++ b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 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.homepage; + +import static com.google.common.truth.Truth.assertThat; + +import com.android.settings.homepage.conditional.ConditionalContextualCard; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(SettingsRobolectricTestRunner.class) +public class ConditionalContextualCardTest { + + @Test(expected = IllegalArgumentException.class) + public void newInstance_changeCardType_shouldCrash() { + new ConditionalContextualCard.Builder() + .setCardType(ContextualCard.CardType.SUGGESTION) + .build(); + } + + @Test + public void getCardType_shouldAlwaysBeConditional() { + assertThat(new ConditionalContextualCard.Builder().build().getCardType()) + .isEqualTo(ContextualCard.CardType.CONDITIONAL); + } +} diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java index ed45ce7480d..a59a3bc2462 100644 --- a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java @@ -82,7 +82,7 @@ public class ConditionContextualCardControllerTest { mController.onConditionsChanged(); - verify(mController).onDataUpdated(any()); + verify(mListener).onContextualCardUpdated(any()); } @Test @@ -94,7 +94,7 @@ public class ConditionContextualCardControllerTest { mController.onConditionsChanged(); - verify(mController, never()).onDataUpdated(any()); + verify(mListener, never()).onContextualCardUpdated(any()); } private class FakeConditionalCard implements ConditionalCard { diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java index 1ee052d20d2..dc56a7f16c0 100644 --- a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java +++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java @@ -101,7 +101,6 @@ public class ConditionContextualCardRendererTest { .setMetricsConstant(1) .setActionText("test_action") .setName("test_name") - .setCardType(ContextualCard.CardType.CONDITIONAL) .setTitleText("test_title") .setSummaryText("test_summary") .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp)) diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java index cbc51a99769..e222b20551c 100644 --- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java @@ -189,9 +189,8 @@ public class RecentNotifyingAppsPreferenceControllerTest { mController.displayPreference(mScreen); verify(mCategory).setTitle(R.string.recent_notifications); - // Only add app1. app2 is skipped because of the package name, app3 skipped because - // it's invalid app. - verify(mCategory, times(1)).addPreference(any(Preference.class)); + // Only add app1 & app2. app3 skipped because it's invalid app. + verify(mCategory, times(2)).addPreference(any(Preference.class)); verify(mSeeAllPref).setSummary(null); verify(mSeeAllPref).setIcon(R.drawable.ic_chevron_right_24dp); @@ -246,35 +245,6 @@ public class RecentNotifyingAppsPreferenceControllerTest { assertThat(prefs.get(0).getKey()).isEqualTo(app2.getPackage()); } - @Test - public void display_hasRecentButNoneDisplayable_showAppInfo() { - final List apps = new ArrayList<>(); - final NotifyingApp app1 = new NotifyingApp() - .setPackage("com.android.phone") - .setLastNotified(System.currentTimeMillis()); - final NotifyingApp app2 = new NotifyingApp() - .setPackage("com.android.settings") - .setLastNotified(System.currentTimeMillis()); - apps.add(app1); - apps.add(app2); - - // app1, app2 are not displayable - when(mAppState.getEntry(app1.getPackage(), UserHandle.myUserId())) - .thenReturn(mock(ApplicationsState.AppEntry.class)); - when(mAppState.getEntry(app2.getPackage(), UserHandle.myUserId())) - .thenReturn(mock(ApplicationsState.AppEntry.class)); - when(mPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn( - new ResolveInfo()); - when(mBackend.getRecentApps()).thenReturn(apps); - - mController.displayPreference(mScreen); - - verify(mCategory, never()).addPreference(any(Preference.class)); - verify(mCategory).setTitle(null); - verify(mSeeAllPref).setTitle(R.string.notifications_title); - verify(mSeeAllPref).setIcon(null); - } - @Test public void display_showRecents_formatSummary() { final List apps = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java index 5e8dd28ba1f..54be773d75e 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java @@ -183,6 +183,22 @@ public class WifiConfigControllerTest { mController.isSubmittable(); } + @Test + public void isSubmittable_EapToPskWithValidPassword_shouldReturnTrue() { + final TextView password = mView.findViewById(R.id.password); + final Spinner securitySpinner = mView.findViewById(R.id.security); + assertThat(password).isNotNull(); + assertThat(securitySpinner).isNotNull(); + when(mAccessPoint.isSaved()).thenReturn(true); + + // Change it from EAP to PSK + mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_EAP, 0); + mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_PSK, 0); + password.setText(GOOD_PSK); + + assertThat(mController.isSubmittable()).isTrue(); + } + @Test public void getSignalString_notReachable_shouldHaveNoSignalString() { when(mAccessPoint.isReachable()).thenReturn(false);