Merge "Correct name of PRIMARY_SUBSCRIPTION_LIST_CHANGED."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 95fe918..51f6681 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -620,8 +620,7 @@
<activity
android:name="Settings$ManageAssistActivity"
- android:label="@string/assist_and_voice_input_title"
- android:parentActivityName="Settings">
+ android:label="@string/assist_and_voice_input_title">
<intent-filter android:priority="1">
<action android:name="android.settings.VOICE_INPUT_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -795,7 +794,8 @@
<activity android:name="Settings$WallpaperSettingsActivity"
android:label="@string/wallpaper_settings_fragment_title"
- android:icon="@drawable/ic_wallpaper">
+ android:icon="@drawable/ic_wallpaper"
+ android:exported="true">
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.wallpaper.WallpaperTypeSettings" />
</activity>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4a65bc9..034e4a3 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -346,6 +346,7 @@
<dimen name="homepage_card_icon_padding_start">14dp</dimen>
<dimen name="homepage_card_text_padding_start">16dp</dimen>
<dimen name="homepage_card_padding_end">16dp</dimen>
+ <dimen name="homepage_card_corner_radius">@*android:dimen/config_dialogCornerRadius</dimen>
<dimen name="homepage_full_card_padding_end">12dp</dimen>
<dimen name="homepage_half_card_padding_top">12dp</dimen>
<dimen name="homepage_half_card_padding_bottom">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d8aec22..6da9260 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2284,6 +2284,8 @@
</plurals>
<!-- Wi-Fi settings screen, advanced, settings section. This is a header shown above advanced wifi settings. [CHAR LIMIT=30] -->
<string name="wifi_advanced_titlebar">Advanced Wi\u2011Fi</string>
+ <!-- Wi-Fi settings screen, advanced, title of the item to show the Wi-Fi device's SSID. [CHAR LIMIT=20] -->
+ <string name="wifi_advanced_ssid_title">SSID</string>
<!-- Wi-Fi settings screen, advanced, title of the item to show the Wi-Fi device's MAC address. -->
<string name="wifi_advanced_mac_address_title">MAC address</string>
<!-- Title of the screen to adjust IP settings -->
@@ -8832,7 +8834,7 @@
<string name="app_usage_preference">App usage preferences</string>
<!-- Link title to show stats about how much time user spent in an app [CHAR LIMIT=45] -->
- <string name="time_spent_in_app_pref_title">Time spent in app</string>
+ <string name="time_spent_in_app_pref_title">Screen time</string>
<!-- Description of the usage access setting [CHAR LIMIT=NONE] -->
<string name="usage_access_description">Usage access allows an app to track what other apps you\u2019re using and how often, as well as your carrier, language settings, and other details.</string>
@@ -11013,11 +11015,11 @@
<!-- Message for forget passpoint dialog [CHAR LIMIT=none] -->
<string name="forget_passpoint_dialog_message">You may lose access to any remaining time or data. Check with your provider before removing.</string>
- <!-- Keywords for Content Capture feature [CHAR_LIMIT=32] -->
- <string name="keywords_content_capture">content capture</string>
+ <!-- Keywords for Content Capture / Smart Suggestions feature [CHAR_LIMIT=none] -->
+ <string name="keywords_content_capture">content capture, smart suggestions</string>
<!-- Title of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=none]-->
- <string name="content_capture">Content Capture</string>
- <!-- Description of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
+ <string name="content_capture">Smart Suggestions</string>
+ <!-- Description of the 'Content Capture / Smart Suggestions' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
<string name="content_capture_summary">Allow Android to save information seen on your screen or heard in video or audio content. Android makes helpful suggestions based on your device activity.</string>
<!-- Title for the button to initiate a heap dump for the system server. [CHAR LIMIT=NONE] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 02db995..8cd22fe 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -418,7 +418,7 @@
<item name="android:layout_marginStart">@dimen/homepage_card_side_margin</item>
<item name="android:layout_marginEnd">@dimen/homepage_card_side_margin</item>
<item name="cardBackgroundColor">@color/contextual_card_background</item>
- <item name="cardCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
+ <item name="cardCornerRadius">@dimen/homepage_card_corner_radius</item>
<item name="cardElevation">0dp</item>
<item name="strokeColor">@color/homepage_card_stroke_color</item>
<item name="strokeWidth">1dp</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index a8ae506..d777fd0 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -103,6 +103,7 @@
<item name="android:trackTint">@color/switchbar_switch_track_tint</item>
<item name="android:thumbTint">@color/switchbar_switch_thumb_tint</item>
<item name="android:minHeight">@dimen/min_tap_target_size</item>
+ <item name="android:minWidth">@dimen/min_tap_target_size</item>
</style>
<style name="Theme.CryptKeeper" parent="@android:style/Theme.Material.NoActionBar">
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 1efe2c2..0e417c9 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -58,12 +58,10 @@
android:title="@string/screen_zoom_title"
settings:searchable="false"/>
- <ListPreference
+ <Preference
android:key="dark_ui_mode_accessibility"
+ android:fragment="com.android.settings.display.DarkUISettings"
android:title="@string/dark_ui_mode"
- android:dialogTitle="@string/dark_ui_mode_title"
- android:entries="@array/dark_ui_mode_entries"
- android:entryValues="@array/dark_ui_mode_values"
settings:searchable="false" />
<Preference
diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml
index 2996afa..fd3725a 100644
--- a/res/xml/app_and_notification.xml
+++ b/res/xml/app_and_notification.xml
@@ -20,7 +20,7 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="apps_and_notification_screen"
android:title="@string/app_and_notification_dashboard_title"
- settings:initialExpandedChildrenCount="8">
+ settings:initialExpandedChildrenCount="3">
<!-- the initial count should include the dynamic tiles -->
<Preference
diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml
index 3158819..14e0366 100644
--- a/res/xml/channel_notification_settings.xml
+++ b/res/xml/channel_notification_settings.xml
@@ -63,8 +63,7 @@
android:dialogTitle="@string/notification_channel_sound_title"
android:order="11"
android:showSilent="true"
- android:showDefault="true"
- android:ringtoneType="notification" />
+ android:showDefault="true"/>
<!-- Vibration -->
<com.android.settingslib.RestrictedSwitchPreference
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index 94ead86..88f88f1 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -26,13 +26,11 @@
android:title="@string/summary_placeholder"
android:selectable="false"
android:layout="@layout/battery_header"
- settings:allowDividerBelow="true"
settings:controller="com.android.settings.fuelgauge.BatteryHeaderPreferenceController" />
<com.android.settings.widget.CardPreference
android:key="battery_tip"
android:title="@string/summary_placeholder"
- settings:allowDividerAbove="true"
settings:controller="com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController" />
<Preference
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index f39880c..45b9d19 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -62,26 +62,6 @@
android:summary="@string/summary_placeholder"
settings:searchable="false"/>
- <!-- Content Capture -->
-
- <!-- NOTE: content capture has a different preference, depending whether or not the
- ContentCaptureService implementations defines a custom settings activitiy on its manifest.
- Hence, we show both here, but the controller itself will decide if it's available or not.
- -->
-
- <SwitchPreference
- android:key="content_capture"
- android:title="@string/content_capture"
- android:summary="@string/content_capture_summary"
- settings:controller="com.android.settings.privacy.EnableContentCapturePreferenceController"/>
-
- <com.android.settings.widget.MasterSwitchPreference
- android:key="content_capture_custom_settings"
- android:title="@string/content_capture"
- android:summary="@string/content_capture_summary"
- settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController">
- </com.android.settings.widget.MasterSwitchPreference>
-
<!-- Privacy Service -->
<PreferenceCategory
android:key="privacy_services"/>
@@ -105,4 +85,24 @@
settings:searchable="false"/>
</PreferenceCategory>
+ <!-- Content Capture -->
+
+ <!-- NOTE: content capture has a different preference, depending whether or not the
+ ContentCaptureService implementations defines a custom settings activitiy on its manifest.
+ Hence, we show both here, but the controller itself will decide if it's available or not.
+ -->
+
+ <SwitchPreference
+ android:key="content_capture"
+ android:title="@string/content_capture"
+ android:summary="@string/content_capture_summary"
+ settings:controller="com.android.settings.privacy.EnableContentCapturePreferenceController"/>
+
+ <com.android.settings.widget.MasterSwitchPreference
+ android:key="content_capture_custom_settings"
+ android:title="@string/content_capture"
+ android:summary="@string/content_capture_summary"
+ settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController">
+ </com.android.settings.widget.MasterSwitchPreference>
+
</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml
index 782a7cf..8fb19cb 100644
--- a/res/xml/wifi_network_details_fragment.xml
+++ b/res/xml/wifi_network_details_fragment.xml
@@ -85,6 +85,11 @@
android:key="ip_details_category"
android:title="@string/wifi_setup_detail">
<Preference
+ android:key="ssid"
+ android:title="@string/wifi_advanced_ssid_title"
+ android:selectable="false"
+ settings:enableCopying="true"/>
+ <Preference
android:key="mac_address"
android:title="@string/wifi_advanced_mac_address_title"
android:selectable="false"
diff --git a/src/com/android/settings/SetupWizardUtils.java b/src/com/android/settings/SetupWizardUtils.java
index 70ee2ca..166e065 100644
--- a/src/com/android/settings/SetupWizardUtils.java
+++ b/src/com/android/settings/SetupWizardUtils.java
@@ -67,9 +67,6 @@
}
public static void copySetupExtras(Intent fromIntent, Intent toIntent) {
- toIntent.putExtra(WizardManagerHelper.EXTRA_THEME,
- fromIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME));
- toIntent.putExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE,
- fromIntent.getBooleanExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, false));
+ WizardManagerHelper.copyWizardManagerExtras(fromIntent, toIntent);
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 4ba605f..efa14f6 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -244,7 +244,7 @@
private SwitchPreference mToggleInversionPreference;
private ColorInversionPreferenceController mInversionPreferenceController;
private AccessibilityHearingAidPreferenceController mHearingAidPreferenceController;
- private ListPreference mDarkUIModePreference;
+ private Preference mDarkUIModePreference;
private DarkUIPreferenceController mDarkUIPreferenceController;
private LiveCaptionPreferenceController mLiveCaptionPreferenceController;
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
index 796df46..57bae45 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
@@ -20,6 +20,8 @@
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.text.TextUtils;
+import com.android.settingslib.fuelgauge.BatterySaverUtils;
/**
* Responds to user actions in the Settings > Battery > Set a Schedule Screen
@@ -66,24 +68,34 @@
public boolean setDefaultKey(String key) {
final ContentResolver resolver = mContext.getContentResolver();
- switch(key) {
- case KEY_NO_SCHEDULE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
- PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
- Settings.Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
- break;
- case KEY_PERCENTAGE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
- PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
- Settings.Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
- break;
- case KEY_ROUTINE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
- PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
- break;
- default:
- throw new IllegalStateException(
- "Not a valid key for " + this.getClass().getSimpleName());
+
+ int mode = PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE;
+ int triggerLevel = 0;
+ if (!TextUtils.equals(key, KEY_NO_SCHEDULE)
+ && BatterySaverUtils.maybeShowBatterySaverConfirmation(
+ mContext, true /* confirmOnly */)) {
+ return true;
+ } else {
+ switch (key) {
+ case KEY_NO_SCHEDULE:
+ break;
+ case KEY_PERCENTAGE:
+ triggerLevel = 5;
+ break;
+ case KEY_ROUTINE:
+ mode = PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC;
+ break;
+ default:
+ throw new IllegalStateException(
+ "Not a valid key for " + this.getClass().getSimpleName());
+ }
+ }
+
+ // Trigger level is intentionally left alone when going between dynamic and percentage modes
+ // so that a users percentage based schedule is preserved when they toggle between the two.
+ Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE, mode);
+ if (mode != PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC) {
+ Settings.Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, triggerLevel);
}
mSeekBarController.updateSeekBar();
return true;
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index 7b8a0c3..ede12fb 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -71,6 +71,7 @@
private final Drawable mIconDrawable;
@LayoutRes
private final int mViewType;
+ private final boolean mIsPendingDismiss;
public String getName() {
return mName;
@@ -156,6 +157,10 @@
return mViewType;
}
+ public boolean isPendingDismiss() {
+ return mIsPendingDismiss;
+ }
+
public Builder mutate() {
return mBuilder;
}
@@ -181,6 +186,7 @@
mIconDrawable = builder.mIconDrawable;
mIsLargeCard = builder.mIsLargeCard;
mViewType = builder.mViewType;
+ mIsPendingDismiss = builder.mIsPendingDismiss;
}
ContextualCard(Cursor c) {
@@ -226,6 +232,8 @@
mBuilder.setIconDrawable(mIconDrawable);
mViewType = getViewTypeByCardType(mCardType);
mBuilder.setViewType(mViewType);
+ mIsPendingDismiss = false;
+ mBuilder.setIsPendingDismiss(mIsPendingDismiss);
}
@Override
@@ -277,6 +285,7 @@
private boolean mIsLargeCard;
@LayoutRes
private int mViewType;
+ private boolean mIsPendingDismiss;
public Builder setName(String name) {
mName = name;
@@ -373,6 +382,11 @@
return this;
}
+ public Builder setIsPendingDismiss(boolean isPendingDismiss) {
+ mIsPendingDismiss = isPendingDismiss;
+ return this;
+ }
+
public ContextualCard build() {
return new ContextualCard(this);
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
index b1e9d33..c296c7a 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProvider.java
@@ -32,5 +32,5 @@
List<ContextualCard> hiddenCards);
/** When user clicks toggle/title area of a contextual card. */
- void logContextualCardClick(ContextualCard card, int row, int tapTarget);
+ void logContextualCardClick(ContextualCard card, int sliceRow, int tapTarget, int uiPosition);
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
index ce7777a..793134f 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardFeatureProviderImpl.java
@@ -63,6 +63,9 @@
// contextual card tap target
private static final String EXTRA_CONTEXTUALCARD_TAP_TARGET = "target";
+ // contextual card ui position
+ private static final String EXTRA_CONTEXTUALCARD_UI_POSTITION = "ui_position";
+
// contextual homepage display latency
private static final String EXTRA_LATENCY = "latency";
@@ -122,7 +125,7 @@
@Override
public void logContextualCardClick(ContextualCard card, int row,
- int actionType) {
+ int actionType, int uiPosition) {
final Intent intent = new Intent();
intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_CLICK);
intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
@@ -130,6 +133,7 @@
intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
intent.putExtra(EXTRA_CONTEXTUALCARD_ROW, row);
intent.putExtra(EXTRA_CONTEXTUALCARD_TAP_TARGET, actionTypeToTapTarget(actionType));
+ intent.putExtra(EXTRA_CONTEXTUALCARD_UI_POSTITION, uiPosition);
sendBroadcast(intent);
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
index d6df380..7be0e8e 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java
@@ -28,7 +28,7 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
-import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate.DismissalItemTouchHelperListener;
+import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import java.util.ArrayList;
@@ -36,7 +36,7 @@
import java.util.Map;
public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
- implements ContextualCardUpdateListener, DismissalItemTouchHelperListener {
+ implements ContextualCardUpdateListener, SwipeDismissalDelegate.Listener {
static final int SPAN_COUNT = 2;
private static final String TAG = "ContextualCardsAdapter";
@@ -140,6 +140,9 @@
@Override
public void onSwiped(int position) {
-
+ final ContextualCard card = mContextualCards.get(position).mutate()
+ .setIsPendingDismiss(true).build();
+ mContextualCards.set(position, card);
+ notifyItemChanged(position);
}
}
diff --git a/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java
index 341e061..61b24df 100644
--- a/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java
+++ b/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionController.java
@@ -22,21 +22,27 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.hardware.display.ColorDisplayManager;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard;
import java.net.URISyntaxException;
+import java.util.List;
import java.util.Objects;
public class GrayscaleConditionController implements ConditionalCardController {
static final int ID = Objects.hash("GrayscaleConditionController");
+ @VisibleForTesting
+ static final String ACTION_GRAYSCALE_CHANGED = "android.settings.action.GRAYSCALE_CHANGED";
+
private static final String TAG = "GrayscaleCondition";
- private static final String ACTION_GRAYSCALE_CHANGED =
- "android.settings.action.GRAYSCALE_CHANGED";
private static final IntentFilter GRAYSCALE_CHANGED_FILTER = new IntentFilter(
ACTION_GRAYSCALE_CHANGED);
@@ -113,9 +119,13 @@
}
private void sendBroadcast() {
- final Intent intent = new Intent();
- intent.setAction(ACTION_GRAYSCALE_CHANGED);
- mAppContext.sendBroadcast(intent, Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS);
+ final PackageManager pm = mAppContext.getPackageManager();
+ final Intent intent = new Intent(ACTION_GRAYSCALE_CHANGED);
+ final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(intent, 0 /* flags */);
+ for (ResolveInfo receiver : receivers) {
+ intent.setPackage(receiver.activityInfo.packageName);
+ mAppContext.sendBroadcast(intent);
+ }
}
public class Receiver extends BroadcastReceiver {
diff --git a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
index d174156..0278f90 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java
@@ -176,15 +176,10 @@
.setSubtitle(getSubTitle(mPackageName, mUid))
.setPrimaryAction(getPrimarySliceAction(icon, title, getIntent())));
- // Get rows by notification channel.
+ // Add notification channel rows.
final List<ListBuilder.RowBuilder> rows = getNotificationChannelRows(packageInfo, icon);
-
- // Get displayable notification channel count.
- final int channelCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT);
-
- // According to the displayable channel count to add rows.
- for (int i = 0; i < channelCount; i++) {
- listBuilder.addRow(rows.get(i));
+ for (ListBuilder.RowBuilder rowBuilder : rows) {
+ listBuilder.addRow(rowBuilder);
}
return listBuilder.build();
@@ -279,10 +274,9 @@
private List<ListBuilder.RowBuilder> getNotificationChannelRows(PackageInfo packageInfo,
IconCompat icon) {
final List<ListBuilder.RowBuilder> notificationChannelRows = new ArrayList<>();
- final List<NotificationChannel> enabledChannels = getEnabledChannels(mPackageName, mUid,
- mAppRow);
+ final List<NotificationChannel> displayableChannels = getDisplayableChannels(mAppRow);
- for (NotificationChannel channel : enabledChannels) {
+ for (NotificationChannel channel : displayableChannels) {
notificationChannelRows.add(new ListBuilder.RowBuilder()
.setTitle(channel.getName())
.setSubtitle(NotificationBackend.getSentSummary(
@@ -356,10 +350,9 @@
title);
}
- private List<NotificationChannel> getEnabledChannels(String packageName, int uid,
- NotificationBackend.AppRow appRow) {
+ private List<NotificationChannel> getDisplayableChannels(NotificationBackend.AppRow appRow) {
final List<NotificationChannelGroup> channelGroupList =
- mNotificationBackend.getGroups(packageName, uid).getList();
+ mNotificationBackend.getGroups(appRow.pkg, appRow.uid).getList();
final List<NotificationChannel> channels = channelGroupList.stream()
.flatMap(group -> group.getChannels().stream().filter(
channel -> isChannelEnabled(group, channel, appRow)))
@@ -376,8 +369,11 @@
}
// Sort the notification channels with notification sent count by descending.
- return channelStates.stream().sorted(CHANNEL_STATE_COMPARATOR).map(
- state -> state.getNotificationChannel()).collect(Collectors.toList());
+ return channelStates.stream()
+ .sorted(CHANNEL_STATE_COMPARATOR)
+ .map(state -> state.getNotificationChannel())
+ .limit(DEFAULT_EXPANDED_ROW_COUNT)
+ .collect(Collectors.toList());
}
private PackageInfo getMaxSentNotificationsPackage(List<PackageInfo> packageInfoList) {
@@ -391,10 +387,14 @@
for (PackageInfo packageInfo : packageInfoList) {
final NotificationBackend.AppRow appRow = mNotificationBackend.loadAppRow(mContext,
mContext.getPackageManager(), packageInfo);
+ // Ignore packages which are banned notifications or block all displayable channels.
+ if (appRow.banned || isAllChannelsBlocked(getDisplayableChannels(appRow))) {
+ continue;
+ }
+
// Get sent notification count from app.
final int sentCount = appRow.sentByApp.sentCount;
- if (!appRow.banned && sentCount >= MIN_NOTIFICATION_SENT_COUNT
- && sentCount > maxSentCount) {
+ if (sentCount >= MIN_NOTIFICATION_SENT_COUNT && sentCount > maxSentCount) {
maxSentCount = sentCount;
maxSentCountPackage = packageInfo;
mAppRow = appRow;
@@ -404,6 +404,15 @@
return maxSentCountPackage;
}
+ private boolean isAllChannelsBlocked(List<NotificationChannel> channels) {
+ for (NotificationChannel channel : channels) {
+ if (channel.getImportance() != IMPORTANCE_NONE) {
+ return false;
+ }
+ }
+ return true;
+ }
+
protected CharSequence getSubTitle(String packageName, int uid) {
final int channelCount = mNotificationBackend.getChannelCount(packageName, uid);
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 006734f..590afd2 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -64,7 +64,6 @@
private final Context mContext;
private final LifecycleOwner mLifecycleOwner;
private final ControllerRendererPool mControllerRendererPool;
- private final Set<ContextualCard> mCardSet;
private final SliceDeferredSetupCardRendererHelper mDeferredSetupCardHelper;
private final SliceFullCardRendererHelper mFullCardHelper;
private final SliceHalfCardRendererHelper mHalfCardHelper;
@@ -75,7 +74,6 @@
mLifecycleOwner = lifecycleOwner;
mSliceLiveDataMap = new ArrayMap<>();
mControllerRendererPool = controllerRendererPool;
- mCardSet = new ArraySet<>();
mFlippedCardSet = new ArraySet<>();
mLifecycleOwner.getLifecycle().addObserver(this);
mFullCardHelper = new SliceFullCardRendererHelper(context);
@@ -110,7 +108,6 @@
sliceLiveData = SliceLiveData.fromUri(mContext, uri);
mSliceLiveDataMap.put(uri, sliceLiveData);
}
- mCardSet.add(card);
sliceLiveData.removeObservers(mLifecycleOwner);
sliceLiveData.observe(mLifecycleOwner, slice -> {
@@ -129,7 +126,7 @@
mHalfCardHelper.bindView(holder, card, slice);
break;
default:
- mFullCardHelper.bindView(holder, card, slice, mCardSet);
+ mFullCardHelper.bindView(holder, card, slice);
}
});
@@ -138,23 +135,19 @@
// Deferred setup is never dismissible.
break;
case VIEW_TYPE_HALF_WIDTH:
- initDismissalActions(holder, card, R.id.content);
+ initDismissalActions(holder, card);
break;
default:
- initDismissalActions(holder, card, R.id.slice_view);
+ initDismissalActions(holder, card);
+ }
+
+ if (card.isPendingDismiss()) {
+ flipCardToDismissalView(holder);
+ mFlippedCardSet.add(holder);
}
}
- private void initDismissalActions(RecyclerView.ViewHolder holder, ContextualCard card,
- int initialViewId) {
- // initialView is the first view in the ViewFlipper.
- final View initialView = holder.itemView.findViewById(initialViewId);
- initialView.setOnLongClickListener(v -> {
- flipCardToDismissalView(holder);
- mFlippedCardSet.add(holder);
- return true;
- });
-
+ private void initDismissalActions(RecyclerView.ViewHolder holder, ContextualCard card) {
final Button btnKeep = holder.itemView.findViewById(R.id.keep);
btnKeep.setOnClickListener(v -> {
mFlippedCardSet.remove(holder);
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceDeferredSetupCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceDeferredSetupCardRendererHelper.java
index d0d51e7..630839c 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceDeferredSetupCardRendererHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceDeferredSetupCardRendererHelper.java
@@ -68,7 +68,7 @@
final ContextualCardFeatureProvider contextualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
contextualCardFeatureProvider.logContextualCardClick(card, 0 /* row */,
- EventInfo.ACTION_TYPE_CONTENT);
+ EventInfo.ACTION_TYPE_CONTENT, view.getAdapterPosition());
});
}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
index ef0a67d..1e1bde4 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java
@@ -17,6 +17,7 @@
package com.android.settings.homepage.contextualcards.slices;
import android.content.Context;
+import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
@@ -36,13 +37,11 @@
/**
* Card renderer helper for {@link ContextualCard} built as slice full card.
*/
-class SliceFullCardRendererHelper implements SliceView.OnSliceActionListener {
+class SliceFullCardRendererHelper {
private static final String TAG = "SliceFCRendererHelper";
private final Context mContext;
- private Set<ContextualCard> mCardSet;
-
SliceFullCardRendererHelper(Context context) {
mContext = context;
}
@@ -51,17 +50,22 @@
return new SliceViewHolder(view);
}
- void bindView(RecyclerView.ViewHolder holder, ContextualCard card, Slice slice,
- Set<ContextualCard> cardSet) {
+ void bindView(RecyclerView.ViewHolder holder, ContextualCard card, Slice slice) {
final SliceViewHolder cardHolder = (SliceViewHolder) holder;
cardHolder.sliceView.setScrollable(false);
cardHolder.sliceView.setTag(card.getSliceUri());
//TODO(b/114009676): We will soon have a field to decide what slice mode we should set.
cardHolder.sliceView.setMode(SliceView.MODE_LARGE);
cardHolder.sliceView.setSlice(slice);
- mCardSet = cardSet;
// Set this listener so we can log the interaction users make on the slice
- cardHolder.sliceView.setOnSliceActionListener(this);
+ cardHolder.sliceView.setOnSliceActionListener(
+ (eventInfo, sliceItem) -> {
+ final ContextualCardFeatureProvider contextualCardFeatureProvider =
+ FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(
+ mContext);
+ contextualCardFeatureProvider.logContextualCardClick(card, eventInfo.rowIndex,
+ eventInfo.actionType, cardHolder.getAdapterPosition());
+ });
// Customize slice view for Settings
cardHolder.sliceView.showTitleItems(true);
@@ -71,23 +75,6 @@
}
}
- @Override
- public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
- // sliceItem.getSlice().getUri() is like
- // content://android.settings.slices/action/wifi/_gen/0/_gen/0
- // contextualCard.getSliceUri() is prefix of sliceItem.getSlice().getUri()
- final ContextualCardFeatureProvider contextualCardFeatureProvider =
- FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
- for (ContextualCard card : mCardSet) {
- if (sliceItem.getSlice().getUri().toString().startsWith(
- card.getSliceUri().toString())) {
- contextualCardFeatureProvider.logContextualCardClick(card, eventInfo.rowIndex,
- eventInfo.actionType);
- break;
- }
- }
- }
-
static class SliceViewHolder extends RecyclerView.ViewHolder {
public final SliceView sliceView;
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelper.java
index 24d654d..6bb2208 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelper.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceHalfCardRendererHelper.java
@@ -66,7 +66,7 @@
final ContextualCardFeatureProvider contextualCardFeatureProvider =
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext);
contextualCardFeatureProvider.logContextualCardClick(card, 0 /* row */,
- EventInfo.ACTION_TYPE_CONTENT);
+ EventInfo.ACTION_TYPE_CONTENT, view.getAdapterPosition());
});
}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java b/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
index a4186b0..3564189 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegate.java
@@ -18,31 +18,74 @@
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.ViewFlipper;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
+
public class SwipeDismissalDelegate extends ItemTouchHelper.Callback {
- private static final String TAG = "DismissItemTouchHelper";
+ private static final String TAG = "SwipeDismissalDelegate";
- public interface DismissalItemTouchHelperListener {
+ public interface Listener {
void onSwiped(int position);
}
private final Context mContext;
- private final DismissalItemTouchHelperListener mListener;
+ private final SwipeDismissalDelegate.Listener mListener;
+ private final Drawable mIconDelete;
+ private final Paint mBgPaint;
+ private final int mBgCornerRadius;
- public SwipeDismissalDelegate(Context context, DismissalItemTouchHelperListener listener) {
+ public SwipeDismissalDelegate(Context context, SwipeDismissalDelegate.Listener listener) {
mContext = context;
mListener = listener;
+ mIconDelete = mContext.getDrawable(R.drawable.ic_delete);
+ mBgPaint = new Paint();
+ mBgPaint.setColor(mContext.getColor(R.color.homepage_card_dismissal_background));
+ mBgCornerRadius = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.homepage_card_corner_radius);
}
+ /**
+ * Determine whether the ability to drag or swipe should be enabled or not.
+ *
+ * Only allow swipe on {@link ContextualCard} built with view type
+ * {@link SliceContextualCardRenderer#VIEW_TYPE_FULL_WIDTH} or
+ * {@link SliceContextualCardRenderer#VIEW_TYPE_HALF_WIDTH}.
+ *
+ * When the dismissal view is displayed, the swipe will also be disabled.
+ */
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder) {
- return 0;
+ switch (viewHolder.getItemViewType()) {
+ case SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH:
+ case SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH:
+ //TODO(b/129438972): Convert this to a regular view.
+ final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.view_flipper);
+
+ // As we are using ViewFlipper to switch between the initial view and
+ // dismissal view, here we are making sure the current displayed view is the
+ // initial view of either slice full card or half card, and only allow swipe on
+ // these two types.
+ if (viewFlipper.getCurrentView().getId() != getInitialViewId(viewHolder)) {
+ // Disable swiping when we are in the dismissal view
+ return 0;
+ }
+ return makeMovementFlags(0 /*dragFlags*/,
+ ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT /*swipeFlags*/);
+ default:
+ return 0;
+ }
}
@Override
@@ -62,5 +105,36 @@
@NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+
+ final View itemView = viewHolder.itemView;
+ final int iconMargin = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.homepage_card_dismissal_side_margin);
+ final int iconTop =
+ itemView.getTop() + (itemView.getHeight() - mIconDelete.getIntrinsicHeight()) / 2;
+ final int iconBottom = iconTop + mIconDelete.getIntrinsicHeight();
+
+ if (dX > 0) { //swipe to the right
+ final int iconLeft = itemView.getLeft() + iconMargin;
+ final int iconRight = iconLeft + mIconDelete.getIntrinsicWidth();
+ final RectF rect = new RectF(itemView.getLeft(), itemView.getTop(),
+ itemView.getLeft() + ((int) dX) + mBgCornerRadius, itemView.getBottom());
+ mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
+ c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
+ } else if (dX < 0) {
+ final int iconRight = itemView.getRight() - iconMargin;
+ final int iconLeft = iconRight - mIconDelete.getIntrinsicWidth();
+ final RectF rect = new RectF(itemView.getRight() + ((int) dX), itemView.getTop(),
+ itemView.getRight(), itemView.getBottom());
+ mIconDelete.setBounds(iconLeft, iconTop, iconRight, iconBottom);
+ c.drawRoundRect(rect, mBgCornerRadius, mBgCornerRadius, mBgPaint);
+ }
+ mIconDelete.draw(c);
+ }
+
+ private int getInitialViewId(RecyclerView.ViewHolder viewHolder) {
+ if (viewHolder.getItemViewType() == SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH) {
+ return R.id.content;
+ }
+ return R.id.slice_view;
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
index eb0c81f..0023e3f 100644
--- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java
+++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
@@ -20,35 +20,51 @@
import android.annotation.ColorInt;
import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.util.Log;
-import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;
+import com.android.internal.util.CollectionUtils;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceable;
-import com.android.settings.slices.SliceBackgroundWorker;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.media.MediaOutputSliceConstants;
+import java.util.ArrayList;
+import java.util.List;
+
public class MediaOutputIndicatorSlice implements CustomSliceable {
+ private static final String TAG = "MediaOutputIndicatorSlice";
+
private Context mContext;
- @VisibleForTesting
- MediaOutputIndicatorWorker mWorker;
+ private LocalBluetoothManager mLocalBluetoothManager;
+ private LocalBluetoothProfileManager mProfileManager;
public MediaOutputIndicatorSlice(Context context) {
mContext = context;
+ mLocalBluetoothManager = com.android.settings.bluetooth.Utils.getLocalBtManager(context);
+ if (mLocalBluetoothManager == null) {
+ Log.e(TAG, "Bluetooth is not supported on this device");
+ return;
+ }
+ mProfileManager = mLocalBluetoothManager.getProfileManager();
}
@Override
public Slice getSlice() {
- if (!getWorker().isVisible()) {
+ if (!isVisible()) {
return null;
}
final IconCompat icon = IconCompat.createWithResource(mContext,
@@ -66,18 +82,11 @@
.setAccentColor(color)
.addRow(new ListBuilder.RowBuilder()
.setTitle(title)
- .setSubtitle(getWorker().findActiveDeviceName())
+ .setSubtitle(findActiveDeviceName())
.setPrimaryAction(primarySliceAction));
return listBuilder.build();
}
- private MediaOutputIndicatorWorker getWorker() {
- if (mWorker == null) {
- mWorker = (MediaOutputIndicatorWorker) SliceBackgroundWorker.getInstance(getUri());
- }
- return mWorker;
- }
-
private Intent getMediaOutputSliceIntent() {
final Intent intent = new Intent()
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
@@ -101,4 +110,65 @@
public Class getBackgroundWorkerClass() {
return MediaOutputIndicatorWorker.class;
}
+
+ private boolean isVisible() {
+ // To decide Slice's visibility.
+ // return true if device is connected or previously connected, false for other cases.
+ return !CollectionUtils.isEmpty(getConnectableA2dpDevices())
+ || !CollectionUtils.isEmpty(getConnectableHearingAidDevices());
+ }
+
+ private List<BluetoothDevice> getConnectableA2dpDevices() {
+ // Get A2dp devices on all states
+ // (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile == null) {
+ return new ArrayList<>();
+ }
+ return a2dpProfile.getConnectableDevices();
+ }
+
+ private List<BluetoothDevice> getConnectableHearingAidDevices() {
+ // Get hearing aid profile devices on all states
+ // (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ if (hapProfile == null) {
+ return new ArrayList<>();
+ }
+
+ return hapProfile.getConnectableDevices();
+ }
+
+ private CharSequence findActiveDeviceName() {
+ // Return Hearing Aid device name if it is active
+ BluetoothDevice activeDevice = findActiveHearingAidDevice();
+ if (activeDevice != null) {
+ return activeDevice.getAliasName();
+ }
+ // Return A2DP device name if it is active
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile != null) {
+ activeDevice = a2dpProfile.getActiveDevice();
+ if (activeDevice != null) {
+ return activeDevice.getAliasName();
+ }
+ }
+ // No active device, return default summary
+ return mContext.getText(R.string.media_output_default_summary);
+ }
+
+ private BluetoothDevice findActiveHearingAidDevice() {
+ final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
+ if (hearingAidProfile == null) {
+ return null;
+ }
+
+ final List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
+ for (BluetoothDevice btDevice : activeDevices) {
+ if (btDevice != null) {
+ return btDevice;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/com/android/settings/media/MediaOutputIndicatorWorker.java b/src/com/android/settings/media/MediaOutputIndicatorWorker.java
index adee055..2d10fd3 100644
--- a/src/com/android/settings/media/MediaOutputIndicatorWorker.java
+++ b/src/com/android/settings/media/MediaOutputIndicatorWorker.java
@@ -16,26 +16,18 @@
package com.android.settings.media;
-import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
-import com.android.internal.util.CollectionUtils;
-import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.slices.SliceBackgroundWorker;
-import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
-import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
/**
* Listener for background change from {@code BluetoothCallback} to update media output indicator.
@@ -45,7 +37,6 @@
private static final String TAG = "MediaOutputIndicatorWorker";
private LocalBluetoothManager mLocalBluetoothManager;
- private LocalBluetoothProfileManager mProfileManager;
public MediaOutputIndicatorWorker(Context context, Uri uri) {
super(context, uri);
@@ -53,12 +44,11 @@
@Override
protected void onSlicePinned() {
- LocalBluetoothManager mLocalBluetoothManager = Utils.getLocalBtManager(getContext());
+ mLocalBluetoothManager = Utils.getLocalBtManager(getContext());
if (mLocalBluetoothManager == null) {
Log.e(TAG, "Bluetooth is not supported on this device");
return;
}
- mProfileManager = mLocalBluetoothManager.getProfileManager();
mLocalBluetoothManager.getEventManager().registerCallback(this);
}
@@ -74,7 +64,6 @@
@Override
public void close() throws IOException {
mLocalBluetoothManager = null;
- mProfileManager = null;
}
@Override
@@ -89,73 +78,4 @@
notifySliceChange();
}
}
-
- /**
- * To decide Slice's visibility.
- *
- * @return true if device is connected or previously connected, false for other cases.
- */
- public boolean isVisible() {
- return !CollectionUtils.isEmpty(getConnectableA2dpDevices())
- || !CollectionUtils.isEmpty(getConnectableHearingAidDevices());
- }
-
- private List<BluetoothDevice> getConnectableA2dpDevices() {
- // get A2dp devices on all states
- // (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
- final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
- if (a2dpProfile == null) {
- return new ArrayList<>();
- }
- return a2dpProfile.getConnectableDevices();
- }
-
- private List<BluetoothDevice> getConnectableHearingAidDevices() {
- // get hearing aid profile devices on all states
- // (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
- final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
- if (hapProfile == null) {
- return new ArrayList<>();
- }
-
- return hapProfile.getConnectableDevices();
- }
-
- /**
- * Get active devices name.
- *
- * @return active Bluetooth device alias, or default summary if no active device.
- */
- public CharSequence findActiveDeviceName() {
- // Return Hearing Aid device name if it is active
- BluetoothDevice activeDevice = findActiveHearingAidDevice();
- if (activeDevice != null) {
- return activeDevice.getAliasName();
- }
- // Return A2DP device name if it is active
- final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
- if (a2dpProfile != null) {
- activeDevice = a2dpProfile.getActiveDevice();
- if (activeDevice != null) {
- return activeDevice.getAliasName();
- }
- }
- // No active device, return default summary
- return getContext().getText(R.string.media_output_default_summary);
- }
-
- private BluetoothDevice findActiveHearingAidDevice() {
- final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
- if (hearingAidProfile == null) {
- return null;
- }
-
- final List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
- for (BluetoothDevice btDevice : activeDevices) {
- if (btDevice != null) {
- return btDevice;
- }
- }
- return null;
- }
}
diff --git a/src/com/android/settings/notification/SoundPreferenceController.java b/src/com/android/settings/notification/SoundPreferenceController.java
index e53a560..73cbad3 100644
--- a/src/com/android/settings/notification/SoundPreferenceController.java
+++ b/src/com/android/settings/notification/SoundPreferenceController.java
@@ -16,10 +16,14 @@
package com.android.settings.notification;
+import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
+
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.PreferenceManager;
@@ -91,6 +95,16 @@
public boolean handlePreferenceTreeClick(Preference preference) {
if (KEY_SOUND.equals(preference.getKey()) && mFragment != null) {
NotificationSoundPreference pref = (NotificationSoundPreference) preference;
+ if (mChannel != null && mChannel.getAudioAttributes() != null) {
+ if (USAGE_ALARM == mChannel.getAudioAttributes().getUsage()) {
+ pref.setRingtoneType(RingtoneManager.TYPE_ALARM);
+ } else if (USAGE_NOTIFICATION_RINGTONE
+ == mChannel.getAudioAttributes().getUsage()) {
+ pref.setRingtoneType(RingtoneManager.TYPE_RINGTONE);
+ } else {
+ pref.setRingtoneType(RingtoneManager.TYPE_NOTIFICATION);
+ }
+ }
pref.onPrepareRingtonePickerIntent(pref.getIntent());
mFragment.startActivityForResult(preference.getIntent(), CODE);
return true;
diff --git a/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java b/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
index cbf909f..b043cb1 100644
--- a/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
+++ b/src/com/android/settings/notification/VibrateWhenRingPreferenceController.java
@@ -39,6 +39,8 @@
public class VibrateWhenRingPreferenceController extends TogglePreferenceController
implements LifecycleObserver, OnResume, OnPause {
+ /** Flag for whether or not to apply ramping ringer on incoming phone calls. */
+ private static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
private final int DEFAULT_VALUE = 0;
private final int NOTIFICATION_VIBRATE_WHEN_RINGING = 1;
@@ -130,8 +132,8 @@
}
private boolean isRampingRingerEnabled() {
- return DeviceConfig.getBoolean(DeviceConfig.Telephony.NAMESPACE,
- DeviceConfig.Telephony.RAMPING_RINGER_ENABLED, false);
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false);
}
}
diff --git a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
index b47ad9c..9358392 100644
--- a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
+++ b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
@@ -16,6 +16,10 @@
package com.android.settings.privacy;
+import static android.Manifest.permission_group.CAMERA;
+import static android.Manifest.permission_group.LOCATION;
+import static android.Manifest.permission_group.MICROPHONE;
+
import static com.android.settingslib.widget.BarChartPreference.MAXIMUM_BAR_VIEWS;
import static java.util.concurrent.TimeUnit.DAYS;
@@ -131,8 +135,28 @@
@Override
public void onPermissionUsageResult(@NonNull List<RuntimePermissionUsageInfo> usageInfos) {
- usageInfos.sort(Comparator.comparingInt(
- RuntimePermissionUsageInfo::getAppAccessCount).reversed());
+ usageInfos.sort((x, y) -> {
+ int usageDiff = y.getAppAccessCount() - x.getAppAccessCount();
+ if (usageDiff != 0) {
+ return usageDiff;
+ }
+ String xName = x.getName();
+ String yName = y.getName();
+ if (xName.equals(LOCATION)) {
+ return -1;
+ } else if (yName.equals(LOCATION)) {
+ return 1;
+ } else if (xName.equals(MICROPHONE)) {
+ return -1;
+ } else if (yName.equals(MICROPHONE)) {
+ return 1;
+ } else if (xName.equals(CAMERA)) {
+ return -1;
+ } else if (yName.equals(CAMERA)) {
+ return 1;
+ }
+ return x.getName().compareTo(y.getName());
+ });
// If the result is different, we need to update bar views.
if (!areSamePermissionGroups(usageInfos)) {
@@ -176,6 +200,7 @@
barViewInfos[index].setClickListener((View v) -> {
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permissionGroupInfo.getName());
+ intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
mContext.startActivity(intent);
});
}
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 13148c8..487dace 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -254,7 +254,7 @@
builder.setTitle(R.string.select_sim_for_calls);
break;
case SMS_PICK:
- builder.setTitle(R.string.sim_card_select_title);
+ builder.setTitle(R.string.select_sim_for_sms);
break;
default:
throw new IllegalArgumentException("Invalid dialog type "
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index 07e957d..9f2176c 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -143,6 +143,7 @@
}
mMppe.setChecked(mProfile.mppe);
mL2tpSecret.setText(mProfile.l2tpSecret);
+ mL2tpSecret.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_Medium);
mIpsecIdentifier.setText(mProfile.ipsecIdentifier);
mIpsecSecret.setText(mProfile.ipsecSecret);
loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 0, mProfile.ipsecUserCert);
@@ -152,6 +153,7 @@
R.string.vpn_no_server_cert, mProfile.ipsecServerCert);
mSaveLogin.setChecked(mProfile.saveLogin);
mAlwaysOnVpn.setChecked(mProfile.key.equals(VpnUtils.getLockdownVpn()));
+ mPassword.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_Medium);
// Hide lockdown VPN on devices that require IMS authentication
if (SystemProperties.getBoolean("persist.radio.imsregrequired", false)) {
diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
index 14564b1..0713872 100644
--- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
+++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
@@ -28,10 +28,18 @@
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
+import com.android.settingslib.search.SearchIndexable;
import com.google.android.setupcompat.util.WizardManagerHelper;
-public class WallpaperSuggestionActivity extends Activity {
+import java.util.ArrayList;
+import java.util.List;
+
+@SearchIndexable
+public class WallpaperSuggestionActivity extends Activity implements Indexable {
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -79,4 +87,30 @@
return context.getResources().getBoolean(
com.android.internal.R.bool.config_enableWallpaperService);
}
+
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ private static final String SUPPORT_SEARCH_INDEX_KEY = "wallpaper_type";
+
+ @Override
+ public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+ boolean enabled) {
+
+ final List<SearchIndexableRaw> result = new ArrayList<>();
+
+ SearchIndexableRaw data = new SearchIndexableRaw(context);
+ data.title = context.getString(R.string.wallpaper_settings_fragment_title);
+ data.screenTitle = context.getString(
+ R.string.wallpaper_settings_fragment_title);
+ data.intentTargetPackage = context.getString(
+ R.string.config_wallpaper_picker_package);
+ data.intentTargetClass = context.getString(
+ R.string.config_wallpaper_picker_class);
+ data.intentAction = Intent.ACTION_MAIN;
+ data.key = SUPPORT_SEARCH_INDEX_KEY;
+ result.add(data);
+
+ return result;
+ }
+ };
}
diff --git a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
index 0e0f8df..2d4a16f 100644
--- a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
+++ b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
@@ -17,21 +17,11 @@
package com.android.settings.wallpaper;
import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settingslib.search.SearchIndexable;
-import java.util.ArrayList;
-import java.util.List;
-@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class WallpaperTypeSettings extends DashboardFragment {
private static final String TAG = "WallpaperTypeSettings";
@@ -54,42 +44,4 @@
protected int getPreferenceScreenResId() {
return R.xml.wallpaper_settings;
}
-
- public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
- @Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
- final List<SearchIndexableRaw> result = new ArrayList<>();
-
- final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
- final PackageManager pm = context.getPackageManager();
- final List<ResolveInfo> rList = pm.queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY);
-
- // Add indexable data for package that is in config_wallpaper_picker_package
- final String wallpaperPickerPackage =
- context.getString(R.string.config_wallpaper_picker_package);
- for (ResolveInfo info : rList) {
- if (!wallpaperPickerPackage.equals(info.activityInfo.packageName)) {
- continue;
- }
- CharSequence label = info.loadLabel(pm);
- if (label == null) {
- label = info.activityInfo.packageName;
- }
- final SearchIndexableRaw data = new SearchIndexableRaw(context);
- data.title = label.toString();
- data.key = "wallpaper_type_settings";
- data.screenTitle = context.getResources().getString(
- R.string.wallpaper_settings_fragment_title);
- data.intentAction = Intent.ACTION_SET_WALLPAPER;
- data.intentTargetPackage = info.activityInfo.packageName;
- data.intentTargetClass = info.activityInfo.name;
- data.keywords = context.getString(R.string.keywords_wallpaper);
- result.add(data);
- }
-
- return result;
- }
- };
}
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 955525d..f880a19 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -115,6 +115,8 @@
@VisibleForTesting
static final String KEY_SECURITY_PREF = "security";
@VisibleForTesting
+ static final String KEY_SSID_PREF = "ssid";
+ @VisibleForTesting
static final String KEY_MAC_ADDRESS_PREF = "mac_address";
@VisibleForTesting
static final String KEY_IP_ADDRESS_PREF = "ip_address";
@@ -170,6 +172,7 @@
private Preference mRxLinkSpeedPref;
private Preference mFrequencyPref;
private Preference mSecurityPref;
+ private Preference mSsidPref;
private Preference mMacAddressPref;
private Preference mIpAddressPref;
private Preference mGatewayPref;
@@ -399,6 +402,7 @@
mFrequencyPref = screen.findPreference(KEY_FREQUENCY_PREF);
mSecurityPref = screen.findPreference(KEY_SECURITY_PREF);
+ mSsidPref = screen.findPreference(KEY_SSID_PREF);
mMacAddressPref = screen.findPreference(KEY_MAC_ADDRESS_PREF);
mIpAddressPref = screen.findPreference(KEY_IP_ADDRESS_PREF);
mGatewayPref = screen.findPreference(KEY_GATEWAY_PREF);
@@ -497,6 +501,8 @@
refreshRxSpeed();
// IP related information
refreshIpLayerInfo();
+ // SSID Pref
+ refreshSsid();
// MAC Address Pref
refreshMacAddress();
}
@@ -645,6 +651,15 @@
R.string.rx_link_speed, mWifiInfo.getRxLinkSpeedMbps()));
}
+ private void refreshSsid() {
+ if (mAccessPoint.isPasspoint() || mAccessPoint.isOsuProvider()) {
+ mSsidPref.setVisible(true);
+ mSsidPref.setSummary(mAccessPoint.getSsidStr());
+ } else {
+ mSsidPref.setVisible(false);
+ }
+ }
+
private void refreshMacAddress() {
String macAddress = getMacAddress();
if (macAddress == null) {
@@ -663,7 +678,8 @@
}
// return randomized MAC address
- if (mWifiConfig.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT) {
+ if (mWifiConfig != null &&
+ mWifiConfig.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT) {
return mWifiConfig.getRandomizedMacAddress().toString();
}
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index ee4cc29..10d1d48 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -140,6 +140,8 @@
context);
privacyController.setWifiConfiguration(mAccessPoint.getConfig());
privacyController.setIsEphemeral(mAccessPoint.isEphemeral());
+ privacyController.setIsPasspoint(
+ mAccessPoint.isPasspoint() || mAccessPoint.isPasspointConfig());
controllers.add(privacyController);
return controllers;
diff --git a/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java b/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
index a549e21..7bec411 100644
--- a/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiPrivacyPreferenceController.java
@@ -41,6 +41,7 @@
private WifiConfiguration mWifiConfiguration;
private WifiManager mWifiManager;
private boolean mIsEphemeral = false;
+ private boolean mIsPasspoint = false;
public WifiPrivacyPreferenceController(Context context) {
super(context, KEY_WIFI_PRIVACY);
@@ -56,6 +57,10 @@
mIsEphemeral = isEphemeral;
}
+ public void setIsPasspoint(boolean isPasspoint) {
+ mIsPasspoint = isPasspoint;
+ }
+
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
@@ -71,7 +76,7 @@
updateSummary(dropDownPreference, randomizationLevel);
// Makes preference not selectable, when this is a ephemeral network.
- if (mIsEphemeral) {
+ if (mIsEphemeral || mIsPasspoint) {
preference.setSelectable(false);
dropDownPreference.setSummary(R.string.wifi_privacy_settings_ephemeral_summary);
}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index 8ca65ff..d7e5585 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -75,6 +75,7 @@
com.android.settings.users.UserDetailsSettings
com.android.settings.vpn2.AppManagementFragment
com.android.settings.vpn2.VpnSettings
+com.android.settings.wallpaper.WallpaperTypeSettings
com.android.settings.wifi.calling.WifiCallingSettingsForSub
com.android.settings.wifi.ChangeWifiStateDetails
com.android.settings.wifi.details.WifiNetworkDetailsFragment
diff --git a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
index f718a67..4fe8fa8a 100644
--- a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java
@@ -36,12 +36,12 @@
Intent fromIntent = new Intent();
final String theme = "TEST_THEME";
fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme);
- fromIntent.putExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, true);
+ fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true);
Intent toIntent = new Intent();
SetupWizardUtils.copySetupExtras(fromIntent, toIntent);
assertThat(theme).isEqualTo(toIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME));
- assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, false))
+ assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, false))
.isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index 8c53019..0cc9dc4 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -156,7 +156,7 @@
@Test
public void testDarkUIModePreferenceSummary_shouldUpdateSummary() {
- final ListPreference darkUIModePreference = new ListPreference(mContext);
+ final Preference darkUIModePreference = new Preference(mContext);
final DarkUIPreferenceController mController;
doReturn(darkUIModePreference).when(mSettings).findPreference(
DARK_UI_MODE_PREFERENCE);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
index 6012dbb..8654a4e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
@@ -7,6 +7,7 @@
import android.os.PowerManager;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -54,4 +55,13 @@
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE);
}
+
+ @Test
+ public void setDefaultKey_any_defaultsToNoScheduleIfWarningNotSeen() {
+ Secure.putString(
+ mContext.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+ mController.setDefaultKey(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE);
+ assertThat(mController.getDefaultKey())
+ .isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java
index 2fe4697..11e76b5 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java
@@ -25,6 +25,8 @@
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ResolveInfo;
import android.hardware.display.ColorDisplayManager;
import org.junit.Before;
@@ -34,7 +36,9 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
public class GrayscaleConditionControllerTest {
@@ -45,6 +49,7 @@
private ColorDisplayManager mColorDisplayManager;
private Context mContext;
private GrayscaleConditionController mController;
+ private ShadowPackageManager mPackageManager;
@Before
public void setUp() {
@@ -53,6 +58,7 @@
mColorDisplayManager = spy(mContext.getSystemService(ColorDisplayManager.class));
doReturn(mColorDisplayManager).when(mContext).getSystemService(ColorDisplayManager.class);
mController = new GrayscaleConditionController(mContext, mConditionManager);
+ mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
}
@Test
@@ -85,8 +91,13 @@
@Test
public void onActionClick_shouldSendBroadcast() {
+ final Intent intent = new Intent(GrayscaleConditionController.ACTION_GRAYSCALE_CHANGED);
+ final ResolveInfo info = new ResolveInfo();
+ info.activityInfo = new ActivityInfo();
+ mPackageManager.addResolveInfoForIntent(intent, info);
+
mController.onActionClick();
- verify(mContext).sendBroadcast(any(Intent.class), any(String.class));
+ verify(mContext).sendBroadcast(any(Intent.class));
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
index a744e68..12513f6 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java
@@ -16,6 +16,7 @@
package com.android.settings.homepage.contextualcards.slices;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.slice.Slice.HINT_LIST_ITEM;
import static android.app.slice.SliceItem.FORMAT_SLICE;
@@ -116,7 +117,8 @@
public void getSlice_hasSuggestedApp_shouldHaveNotificationChannelTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -130,7 +132,8 @@
public void getSlice_hasSuggestedApp_shouldSortByNotificationSentCount() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -157,7 +160,8 @@
public void getSlice_noRecentlyInstalledApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(false /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -169,7 +173,8 @@
public void getSlice_noMultiChannelApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -178,10 +183,12 @@
}
@Test
+ @Config(shadows = ShadowRestrictedLockUtilsInternal.class)
public void getSlice_insufficientNotificationSentCount_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -192,7 +199,8 @@
@Test
public void getSlice_isSystemApp_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_SYSTEM);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -204,7 +212,8 @@
public void getSlice_isNotificationBanned_shouldHaveNoSuggestedAppTitle() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -218,7 +227,7 @@
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
mockNotificationBackend(NotificationChannelSlice.DEFAULT_EXPANDED_ROW_COUNT * 2,
- NOTIFICATION_COUNT, false /* banned */);
+ NOTIFICATION_COUNT, false /* banned */, false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -234,7 +243,8 @@
public void getSlice_channelCountIsLessThanDefaultRows_subTitleShouldNotHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -249,7 +259,8 @@
public void getSlice_channelCountIsEqualToDefaultRows_subTitleShouldNotHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -263,7 +274,8 @@
public void getSlice_channelCountIsMoreThanDefaultRows_subTitleShouldHaveTapToManagerAll() {
addMockPackageToPackageManager(true /* isRecentlyInstalled */,
ApplicationInfo.FLAG_INSTALLED);
- mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */);
+ mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */,
+ false /* isChannelBlocked */);
final Slice slice = mNotificationChannelSlice.getSlice();
@@ -273,6 +285,20 @@
CHANNEL_COUNT + 1));
}
+ @Test
+ @Config(shadows = ShadowRestrictedLockUtilsInternal.class)
+ public void getSlice_isAllDisplayableChannelBlocked_shouldHaveNoSuggestedAppTitle() {
+ addMockPackageToPackageManager(true /* isRecentlyInstalled */,
+ ApplicationInfo.FLAG_INSTALLED);
+ mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */,
+ true /* isChannelBlocked */);
+
+ final Slice slice = mNotificationChannelSlice.getSlice();
+
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app));
+ }
+
private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) {
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.name = APP_LABEL;
@@ -294,8 +320,10 @@
return System.currentTimeMillis();
}
- private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned) {
- final List<NotificationChannel> channels = buildNotificationChannel(channelCount);
+ private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned,
+ boolean isChannelBlocked) {
+ final List<NotificationChannel> channels = buildNotificationChannel(channelCount,
+ isChannelBlocked);
final AppRow appRow = buildAppRow(channelCount, notificationCount, banned);
doReturn(buildNotificationChannelGroups(channels)).when(mNotificationBackend).getGroups(
@@ -308,6 +336,8 @@
private AppRow buildAppRow(int channelCount, int sentCount, boolean banned) {
final AppRow appRow = new AppRow();
+ appRow.pkg = PACKAGE_NAME;
+ appRow.uid = UID;
appRow.banned = banned;
appRow.channelCount = channelCount;
appRow.sentByApp = new NotificationsSentState();
@@ -317,11 +347,12 @@
return appRow;
}
- private List<NotificationChannel> buildNotificationChannel(int channelCount) {
+ private List<NotificationChannel> buildNotificationChannel(int channelCount,
+ boolean isChannelBlock) {
final List<NotificationChannel> channels = new ArrayList<>();
for (int i = 0; i < channelCount; i++) {
channels.add(new NotificationChannel(CHANNEL_NAME_PREFIX + i, CHANNEL_NAME_PREFIX + i,
- IMPORTANCE_NONE));
+ isChannelBlock ? IMPORTANCE_NONE : IMPORTANCE_LOW));
}
return channels;
@@ -369,4 +400,4 @@
// Index 0: title; Index 1: summary.
return rowSliceItems.get(1).getText();
}
-}
\ No newline at end of file
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index e08d845..a53ade2 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -16,13 +16,11 @@
package com.android.settings.homepage.contextualcards.slices;
-import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Activity;
@@ -118,34 +116,25 @@
}
@Test
- public void longClick_shouldFlipCard() {
+ public void bindView_isPendingDismiss_shouldFlipToDismissalView() {
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- final View card = viewHolder.itemView.findViewById(R.id.slice_view);
final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.view_flipper);
final View dismissalView = viewHolder.itemView.findViewById(R.id.dismissal_view);
- mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+ final ContextualCard card = buildContextualCard(
+ TEST_SLICE_URI).mutate().setIsPendingDismiss(true).build();
- card.performLongClick();
+ mRenderer.bindView(viewHolder, card);
assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView);
}
@Test
- public void longClick_deferredSetupCard_shouldNotBeClickable() {
- final RecyclerView.ViewHolder viewHolder = getDeferredSetupViewHolder();
- final View contentView = viewHolder.itemView.findViewById(R.id.content);
- mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
-
- assertThat(contentView.isLongClickable()).isFalse();
- }
-
- @Test
- public void longClick_shouldAddViewHolderToSet() {
+ public void bindView_isPendingDismiss_shouldAddViewHolderToSet() {
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- final View card = viewHolder.itemView.findViewById(R.id.slice_view);
- mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+ final ContextualCard card = buildContextualCard(
+ TEST_SLICE_URI).mutate().setIsPendingDismiss(true).build();
- card.performLongClick();
+ mRenderer.bindView(viewHolder, card);
assertThat(mRenderer.mFlippedCardSet).contains(viewHolder);
}
@@ -232,18 +221,6 @@
return mRenderer.createViewHolder(view, VIEW_TYPE_FULL_WIDTH);
}
- private RecyclerView.ViewHolder getDeferredSetupViewHolder() {
- final RecyclerView recyclerView = new RecyclerView(mActivity);
- recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
- final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_DEFERRED_SETUP,
- recyclerView, false);
- final RecyclerView.ViewHolder viewHolder = spy(
- mRenderer.createViewHolder(view, VIEW_TYPE_DEFERRED_SETUP));
- doReturn(VIEW_TYPE_DEFERRED_SETUP).when(viewHolder).getItemViewType();
-
- return viewHolder;
- }
-
private ContextualCard buildContextualCard(Uri sliceUri) {
return new ContextualCard.Builder()
.setName("test_name")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
index 8882009..395748b 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java
@@ -78,7 +78,7 @@
public void bindView_shouldSetScrollableToFalse() {
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet());
+ mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
assertThat(((SliceViewHolder) viewHolder).sliceView.isScrollable()).isFalse();
}
@@ -88,7 +88,7 @@
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
final ContextualCard card = buildContextualCard();
- mHelper.bindView(viewHolder, card, buildSlice(), Collections.emptySet());
+ mHelper.bindView(viewHolder, card, buildSlice());
assertThat(((SliceViewHolder) viewHolder).sliceView.getTag()).isEqualTo(card.getSliceUri());
}
@@ -97,7 +97,7 @@
public void bindView_shouldSetModeToLarge() {
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet());
+ mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
assertThat(((SliceViewHolder) viewHolder).sliceView.getMode()).isEqualTo(
SliceView.MODE_LARGE);
@@ -107,7 +107,7 @@
public void bindView_shouldSetSlice() {
final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
- mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet());
+ mHelper.bindView(viewHolder, buildContextualCard(), buildSlice());
assertThat(((SliceViewHolder) viewHolder).sliceView.getSlice().getUri()).isEqualTo(
TEST_SLICE_URI);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java
new file mode 100644
index 0000000..00b7815
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.homepage.contextualcards.slices;
+
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ViewFlipper;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
+import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer.ConditionalCardHolder;
+import com.android.settings.homepage.contextualcards.slices.SliceDeferredSetupCardRendererHelper.DeferredSetupCardViewHolder;
+import com.android.settings.homepage.contextualcards.slices.SliceFullCardRendererHelper.SliceViewHolder;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(RobolectricTestRunner.class)
+public class SwipeDismissalDelegateTest {
+
+ @Mock
+ private SwipeDismissalDelegate.Listener mDismissalDelegateListener;
+
+ private Activity mActivity;
+ private RecyclerView mRecyclerView;
+ private SwipeDismissalDelegate mDismissalDelegate;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ final ActivityController<Activity> activityController = Robolectric.buildActivity(
+ Activity.class);
+ mActivity = activityController.get();
+ mActivity.setTheme(R.style.Theme_Settings_Home);
+ activityController.create();
+ mRecyclerView = new RecyclerView(mActivity);
+ mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ mDismissalDelegate = new SwipeDismissalDelegate(mActivity, mDismissalDelegateListener);
+ }
+
+ @Test
+ public void getMovementFlags_conditionalViewHolder_shouldDisableSwipe() {
+ assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getConditionalViewHolder()))
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void getMovementFlags_deferredSetupViewHolder_shouldDisableSwipe() {
+ assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getDeferredSetupViewHolder()))
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void getMovementFlags_dismissalView_shouldDisableSwipe() {
+ final RecyclerView.ViewHolder holder = getSliceViewHolder();
+ final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
+ viewFlipper.showNext();
+ final View dismissalView = holder.itemView.findViewById(R.id.dismissal_view);
+
+ assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView);
+ assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, holder)).isEqualTo(0);
+ }
+
+ @Test
+ public void getMovementFlags_SliceViewHolder_shouldEnableSwipe() {
+ final RecyclerView.ViewHolder holder = getSliceViewHolder();
+ final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper);
+ viewFlipper.setDisplayedChild(0);
+ final View sliceView = holder.itemView.findViewById(R.id.slice_view);
+
+ assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceView);
+ assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getSliceViewHolder()))
+ .isNotEqualTo(0);
+ }
+
+ @Test
+ public void onSwipe_shouldNotifyListener() {
+ mDismissalDelegate.onSwiped(getSliceViewHolder(), 1);
+
+ verify(mDismissalDelegateListener).onSwiped(anyInt());
+ }
+
+ private RecyclerView.ViewHolder getSliceViewHolder() {
+ final View view = LayoutInflater.from(mActivity)
+ .inflate(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH, mRecyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = spy(new SliceViewHolder(view));
+ doReturn(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH).when(
+ viewHolder).getItemViewType();
+
+ return viewHolder;
+ }
+
+ private RecyclerView.ViewHolder getConditionalViewHolder() {
+ final View view = LayoutInflater.from(mActivity)
+ .inflate(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH, mRecyclerView,
+ false);
+ final RecyclerView.ViewHolder viewHolder = spy(new ConditionalCardHolder(view));
+ doReturn(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH).when(
+ viewHolder).getItemViewType();
+
+ return viewHolder;
+ }
+
+ private RecyclerView.ViewHolder getDeferredSetupViewHolder() {
+ final View view = LayoutInflater.from(mActivity)
+ .inflate(VIEW_TYPE_DEFERRED_SETUP, mRecyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = spy(new DeferredSetupCardViewHolder(view));
+ doReturn(VIEW_TYPE_DEFERRED_SETUP).when(viewHolder).getItemViewType();
+
+ return viewHolder;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
index c551960..b39f77e 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
@@ -17,35 +17,29 @@
package com.android.settings.media;
-import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
-
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
import android.content.Context;
-import android.content.Intent;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
-import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
-import com.android.settingslib.media.LocalMediaManager;
-import com.android.settingslib.media.MediaDevice;
-import com.android.settingslib.media.MediaOutputSliceConstants;
+import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -53,59 +47,108 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList;
import java.util.List;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowBluetoothAdapter.class})
-@Ignore("b/129292771")
+@Config(shadows = {ShadowBluetoothUtils.class})
public class MediaOutputIndicatorSliceTest {
- private static final String TEST_DEVICE_NAME = "test_device_name";
- private static final int TEST_DEVICE_1_ICON =
- com.android.internal.R.drawable.ic_bt_headphones_a2dp;
+ private static final String TEST_A2DP_DEVICE_NAME = "Test_A2DP_BT_Device_NAME";
+ private static final String TEST_HAP_DEVICE_NAME = "Test_HAP_BT_Device_NAME";
+ private static final String TEST_A2DP_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
+ private static final String TEST_HAP_DEVICE_ADDRESS = "00:B2:B2:B2:B2:B2";
@Mock
- private LocalMediaManager mLocalMediaManager;
+ private A2dpProfile mA2dpProfile;
+ @Mock
+ private HearingAidProfile mHearingAidProfile;
+ @Mock
+ private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
- private final List<MediaDevice> mDevices = new ArrayList<>();
-
+ private BluetoothAdapter mBluetoothAdapter;
+ private BluetoothDevice mA2dpDevice;
+ private BluetoothDevice mHapDevice;
+ private BluetoothManager mBluetoothManager;
private Context mContext;
+ private List<BluetoothDevice> mDevicesList;
private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice;
- private MediaOutputIndicatorWorker mMediaOutputIndicatorWorker;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
-
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ // Setup Bluetooth environment
+ ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
+ mBluetoothManager = new BluetoothManager(mContext);
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
+ when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+
+ // Setup A2dp device
+ mA2dpDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_A2DP_DEVICE_ADDRESS));
+ when(mA2dpDevice.getName()).thenReturn(TEST_A2DP_DEVICE_NAME);
+ when(mA2dpDevice.isConnected()).thenReturn(true);
+ // Setup HearingAid device
+ mHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_HAP_DEVICE_ADDRESS));
+ when(mHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME);
+ when(mHapDevice.isConnected()).thenReturn(true);
+
mMediaOutputIndicatorSlice = new MediaOutputIndicatorSlice(mContext);
- mMediaOutputIndicatorWorker = spy(new MediaOutputIndicatorWorker(
- mContext, MEDIA_OUTPUT_INDICATOR_SLICE_URI));
- mMediaOutputIndicatorSlice.mWorker = mMediaOutputIndicatorWorker;
+ mDevicesList = new ArrayList<>();
}
@Test
- public void getSlice_invisible_returnNull() {
- when(mMediaOutputIndicatorWorker.isVisible()).thenReturn(false);
+ public void getSlice_noConnectableDevice_returnNull() {
+ mDevicesList.clear();
+ when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList);
assertThat(mMediaOutputIndicatorSlice.getSlice()).isNull();
}
@Test
- public void getSlice_withActiveDevice_checkContent() {
- when(mMediaOutputIndicatorWorker.isVisible()).thenReturn(true);
- when(mMediaOutputIndicatorWorker.findActiveDeviceName()).thenReturn(TEST_DEVICE_NAME);
+ public void getSlice_noActiveDevice_verifyDefaultName() {
+ mDevicesList.add(mA2dpDevice);
+ when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(null);
+
+ // Verify slice title and subtitle
final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice();
final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
- // Verify slice title and subtitle
assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title));
- assertThat(metadata.getSubtitle()).isEqualTo(TEST_DEVICE_NAME);
+ assertThat(metadata.getSubtitle()).isEqualTo(mContext.getText(
+ R.string.media_output_default_summary));
+ }
+
+ @Test
+ public void getSlice_A2dpDeviceActive_verifyName() {
+ mDevicesList.add(mA2dpDevice);
+ when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList);
+ when(mA2dpProfile.getActiveDevice()).thenReturn(mA2dpDevice);
+
+ final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title));
+ assertThat(metadata.getSubtitle()).isEqualTo(TEST_A2DP_DEVICE_NAME);
+ }
+
+ @Test
+ public void getSlice_HADeviceActive_verifyName() {
+ mDevicesList.add(mHapDevice);
+ when(mHearingAidProfile.getConnectableDevices()).thenReturn(mDevicesList);
+ when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList);
+
+ // Verify slice title and subtitle
+ final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title));
+ assertThat(metadata.getSubtitle()).isEqualTo(TEST_HAP_DEVICE_NAME);
}
}
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java
index ed93258..3671d81 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java
@@ -16,28 +16,18 @@
package com.android.settings.media;
-import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.net.Uri;
-import com.android.settings.R;
-import com.android.settings.bluetooth.Utils;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
-import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.BluetoothEventManager;
-import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -45,119 +35,38 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowBluetoothDevice;
-
-import java.util.ArrayList;
-import java.util.List;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowBluetoothUtils.class,
- ShadowBluetoothDevice.class})
-@Ignore("b/129292771")
+@Config(shadows = {ShadowBluetoothUtils.class})
public class MediaOutputIndicatorWorkerTest {
-
- private static final String TEST_A2DP_DEVICE_NAME = "Test_A2DP_BT_Device_NAME";
- private static final String TEST_HAP_DEVICE_NAME = "Test_HAP_BT_Device_NAME";
- private static final String TEST_A2DP_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
- private static final String TEST_HAP_DEVICE_ADDRESS = "00:B2:B2:B2:B2:B2";
private static final Uri URI = Uri.parse("content://com.android.settings.slices/test");
@Mock
- private A2dpProfile mA2dpProfile;
- @Mock
- private HearingAidProfile mHearingAidProfile;
- @Mock
- private LocalBluetoothManager mLocalManager;
- @Mock
private BluetoothEventManager mBluetoothEventManager;
@Mock
- private LocalBluetoothProfileManager mLocalBluetoothProfileManager;
-
- private BluetoothAdapter mBluetoothAdapter;
- private BluetoothDevice mA2dpDevice;
- private BluetoothDevice mHapDevice;
- private BluetoothManager mBluetoothManager;
- private Context mContext;
- private List<BluetoothDevice> mDevicesList;
private LocalBluetoothManager mLocalBluetoothManager;
+ private Context mContext;
private MediaOutputIndicatorWorker mMediaDeviceUpdateWorker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager;
- mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
+ ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
- when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
- when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
- when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
- mBluetoothManager = new BluetoothManager(mContext);
- mBluetoothAdapter = mBluetoothManager.getAdapter();
-
- // Setup A2dp device
- mA2dpDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_A2DP_DEVICE_ADDRESS));
- when(mA2dpDevice.getName()).thenReturn(TEST_A2DP_DEVICE_NAME);
- when(mA2dpDevice.isConnected()).thenReturn(true);
- // Setup HearingAid device
- mHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_HAP_DEVICE_ADDRESS));
- when(mHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME);
- when(mHapDevice.isConnected()).thenReturn(true);
-
mMediaDeviceUpdateWorker = new MediaOutputIndicatorWorker(mContext, URI);
- mDevicesList = new ArrayList<>();
}
@Test
- public void isVisible_noConnectableDevice_returnFalse() {
- mDevicesList.clear();
- when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList);
-
- assertThat(mMediaDeviceUpdateWorker.isVisible()).isFalse();
+ public void onSlicePinned_registerCallback() {
+ mMediaDeviceUpdateWorker.onSlicePinned();
+ verify(mBluetoothEventManager).registerCallback(mMediaDeviceUpdateWorker);
}
@Test
- public void isVisible_withConnectableA2dpDevice_returnTrue() {
- mDevicesList.clear();
- mDevicesList.add(mA2dpDevice);
- when(mHearingAidProfile.getConnectableDevices()).thenReturn(mDevicesList);
-
- assertThat(mMediaDeviceUpdateWorker.isVisible()).isTrue();
- }
-
- @Test
- public void isVisible_withConnectableHADevice_returnTrue() {
- mDevicesList.clear();
- mDevicesList.add(mHapDevice);
- when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList);
-
- assertThat(mMediaDeviceUpdateWorker.isVisible()).isTrue();
- }
-
- @Test
- public void findActiveDeviceName_A2dpDeviceActive_verifyName() {
- when(mA2dpProfile.getActiveDevice()).thenReturn(mA2dpDevice);
-
- assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName())
- .isEqualTo(mA2dpDevice.getAliasName());
- }
-
- @Test
- public void findActiveDeviceName_HADeviceActive_verifyName() {
- mDevicesList.add(mHapDevice);
- when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList);
-
- assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName())
- .isEqualTo(mHapDevice.getAliasName());
- }
-
- @Test
- public void findActiveDeviceName_noActiveDevice_verifyDefaultName() {
- when(mA2dpProfile.getActiveDevice()).thenReturn(null);
- mDevicesList.clear();
- when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList);
-
- assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName())
- .isEqualTo(mContext.getText(R.string.media_output_default_summary));
+ public void onSliceUnpinned_unRegisterCallback() {
+ mMediaDeviceUpdateWorker.onSlicePinned();
+ mMediaDeviceUpdateWorker.onSliceUnpinned();
+ verify(mBluetoothEventManager).unregisterCallback(mMediaDeviceUpdateWorker);
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java
index 1b4ede5..866f866 100644
--- a/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java
@@ -39,6 +39,8 @@
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
+import android.media.AudioAttributes;
+import android.media.RingtoneManager;
import android.net.Uri;
import android.os.UserManager;
import android.provider.Settings;
@@ -54,6 +56,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
@@ -231,6 +234,69 @@
}
@Test
+ public void testOnPreferenceTreeClick_alarmSound() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ channel.setSound(null, new AudioAttributes.Builder().setUsage(
+ AudioAttributes.USAGE_ALARM).build());
+ mController.onResume(appRow, channel, null, null);
+
+ AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
+ NotificationSoundPreference pref =
+ spy(new NotificationSoundPreference(mContext, attributeSet));
+ pref.setKey(mController.getPreferenceKey());
+ mController.handlePreferenceTreeClick(pref);
+
+ ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture());
+ assertEquals(RingtoneManager.TYPE_ALARM,
+ intentArgumentCaptor.getValue().getIntExtra(
+ RingtoneManager.EXTRA_RINGTONE_TYPE, 0));
+ }
+
+ @Test
+ public void testOnPreferenceTreeClick_ringtoneSound() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ channel.setSound(null, new AudioAttributes.Builder().setUsage(
+ AudioAttributes.USAGE_NOTIFICATION_RINGTONE).build());
+ mController.onResume(appRow, channel, null, null);
+
+ AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
+ NotificationSoundPreference pref =
+ spy(new NotificationSoundPreference(mContext, attributeSet));
+ pref.setKey(mController.getPreferenceKey());
+ mController.handlePreferenceTreeClick(pref);
+
+ ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture());
+ assertEquals(RingtoneManager.TYPE_RINGTONE,
+ intentArgumentCaptor.getValue().getIntExtra(
+ RingtoneManager.EXTRA_RINGTONE_TYPE, 0));
+ }
+
+ @Test
+ public void testOnPreferenceTreeClick_otherSound() {
+ NotificationBackend.AppRow appRow = new NotificationBackend.AppRow();
+ NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
+ channel.setSound(null, new AudioAttributes.Builder().setUsage(
+ AudioAttributes.USAGE_UNKNOWN).build());
+ mController.onResume(appRow, channel, null, null);
+
+ AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
+ NotificationSoundPreference pref =
+ spy(new NotificationSoundPreference(mContext, attributeSet));
+ pref.setKey(mController.getPreferenceKey());
+ mController.handlePreferenceTreeClick(pref);
+
+ ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture());
+ assertEquals(RingtoneManager.TYPE_NOTIFICATION,
+ intentArgumentCaptor.getValue().getIntExtra(
+ RingtoneManager.EXTRA_RINGTONE_TYPE, 0));
+ }
+
+ @Test
public void testOnActivityResult() {
NotificationSoundPreference pref = mock(NotificationSoundPreference.class);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(pref);
diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
index 332156e..9888168 100644
--- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
@@ -16,6 +16,14 @@
package com.android.settings.privacy;
+import static android.Manifest.permission_group.CALENDAR;
+import static android.Manifest.permission_group.CAMERA;
+import static android.Manifest.permission_group.CONTACTS;
+import static android.Manifest.permission_group.LOCATION;
+import static android.Manifest.permission_group.MICROPHONE;
+import static android.Manifest.permission_group.PHONE;
+import static android.Manifest.permission_group.SMS;
+
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
@@ -221,4 +229,27 @@
verify(mFragment).setLoadingEnabled(false /* enabled */);
verify(mPreference).updateLoadingState(false /* isLoading */);
}
+
+ @Test
+ public void onPermissionUsageResult_shouldBeSorted() {
+ final List<RuntimePermissionUsageInfo> infos = new ArrayList<>();
+ infos.add(new RuntimePermissionUsageInfo(PHONE, 10));
+ infos.add(new RuntimePermissionUsageInfo(LOCATION, 10));
+ infos.add(new RuntimePermissionUsageInfo(CAMERA, 10));
+ infos.add(new RuntimePermissionUsageInfo(SMS, 1));
+ infos.add(new RuntimePermissionUsageInfo(MICROPHONE, 10));
+ infos.add(new RuntimePermissionUsageInfo(CONTACTS, 42));
+ infos.add(new RuntimePermissionUsageInfo(CALENDAR, 10));
+ mController.displayPreference(mScreen);
+
+ mController.onPermissionUsageResult(infos);
+
+ assertThat(infos.get(0).getName()).isEqualTo(CONTACTS);
+ assertThat(infos.get(1).getName()).isEqualTo(LOCATION);
+ assertThat(infos.get(2).getName()).isEqualTo(MICROPHONE);
+ assertThat(infos.get(3).getName()).isEqualTo(CAMERA);
+ assertThat(infos.get(4).getName()).isEqualTo(CALENDAR);
+ assertThat(infos.get(5).getName()).isEqualTo(PHONE);
+ assertThat(infos.get(6).getName()).isEqualTo(SMS);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 0a565cd..f177b5e 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -105,6 +105,7 @@
private static final int RSSI = -55;
private static final int TX_LINK_SPEED = 123;
private static final int RX_LINK_SPEED = 54;
+ private static final String SSID = "ssid";
private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS;
private static final String SECURITY = "None";
@@ -154,6 +155,8 @@
@Mock
private Preference mockSecurityPref;
@Mock
+ private Preference mockSsidPref;
+ @Mock
private Preference mockMacAddressPref;
@Mock
private Preference mockIpAddressPref;
@@ -245,6 +248,7 @@
when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);
+ when(mockAccessPoint.getSsidStr()).thenReturn(SSID);
when(mockConnectivityManager.getNetworkInfo(any(Network.class)))
.thenReturn(mockNetworkInfo);
doNothing().when(mockConnectivityManager).registerNetworkCallback(
@@ -314,6 +318,8 @@
.thenReturn(mockFrequencyPref);
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF))
.thenReturn(mockSecurityPref);
+ when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SSID_PREF))
+ .thenReturn(mockSsidPref);
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF))
.thenReturn(mockMacAddressPref);
when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF))
@@ -463,6 +469,50 @@
}
@Test
+ public void ssidPref_shouldHaveDetailTextSet() {
+ when(mockAccessPoint.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.isOsuProvider()).thenReturn(false);
+
+ displayAndResume();
+
+ verify(mockSsidPref, times(1)).setSummary(SSID);
+
+ when(mockAccessPoint.isPasspoint()).thenReturn(false);
+ when(mockAccessPoint.isOsuProvider()).thenReturn(true);
+
+ displayAndResume();
+
+ verify(mockSsidPref, times(2)).setSummary(SSID);
+ }
+
+ @Test
+ public void ssidPref_shouldShowIfPasspointOrOsu() {
+ when(mockAccessPoint.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.isOsuProvider()).thenReturn(false);
+
+ displayAndResume();
+
+ verify(mockSsidPref, times(1)).setVisible(true);
+
+ when(mockAccessPoint.isPasspoint()).thenReturn(false);
+ when(mockAccessPoint.isOsuProvider()).thenReturn(true);
+
+ displayAndResume();
+
+ verify(mockSsidPref, times(2)).setVisible(true);
+ }
+
+ @Test
+ public void ssidPref_shouldNotShowIfNotPasspoint() {
+ when(mockAccessPoint.isPasspoint()).thenReturn(false);
+ when(mockAccessPoint.isOsuProvider()).thenReturn(false);
+
+ displayAndResume();
+
+ verify(mockSsidPref).setVisible(false);
+ }
+
+ @Test
public void macAddressPref_shouldHaveDetailTextSet() {
displayAndResume();
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
index a1af8bf..2e588b5 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
@@ -109,4 +109,20 @@
assertThat(mDropDownPreference.isSelectable()).isFalse();
}
+
+ @Test
+ public void testUpdateState_isNotPasspointNetwork_shouldBeSelectable() {
+ mPreferenceController.setIsPasspoint(false);
+ mPreferenceController.updateState(mDropDownPreference);
+
+ assertThat(mDropDownPreference.isSelectable()).isTrue();
+ }
+
+ @Test
+ public void testUpdateState_isPasspointNetwork_shouldNotSelectable() {
+ mPreferenceController.setIsPasspoint(true);
+ mPreferenceController.updateState(mDropDownPreference);
+
+ assertThat(mDropDownPreference.isSelectable()).isFalse();
+ }
}