diff --git a/res/layout/notification_history.xml b/res/layout/notification_history.xml index 1fc07006106..b397eef6540 100644 --- a/res/layout/notification_history.xml +++ b/res/layout/notification_history.xml @@ -16,7 +16,6 @@ @@ -43,6 +42,7 @@ android:layout_gravity="center_horizontal" android:contentDescription="@string/notification_history" android:scaleType="fitCenter" + android:focusable="false" android:tint="?android:attr/colorControlNormal" android:src="@drawable/ic_history" /> @@ -55,6 +55,7 @@ android:layout_marginStart="48dp" android:layout_marginEnd="48dp" android:layout_gravity="center_horizontal" + android:focusable="true" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/notification_history_off_title_extended" /> @@ -68,6 +69,7 @@ android:layout_marginTop="16dp" android:layout_gravity="center_horizontal" android:textAlignment="center" + android:focusable="true" android:textAppearance="?android:attr/textAppearanceSmall" android:text="@string/notification_history_off_summary" /> @@ -106,11 +108,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="true" - settings:fastScrollEnabled="true" - settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable" - settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable" - settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable" - settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/> + android:scrollbars="none"/> @@ -141,11 +139,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="true" - settings:fastScrollEnabled="true" - settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable" - settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable" - settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable" - settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/> + android:scrollbars="none"/> diff --git a/res/layout/notification_history_app_layout.xml b/res/layout/notification_history_app_layout.xml index 5d8ff3fb0df..a8757fe707e 100644 --- a/res/layout/notification_history_app_layout.xml +++ b/res/layout/notification_history_app_layout.xml @@ -16,7 +16,6 @@ @@ -79,16 +78,12 @@ android:layout_width="match_parent" android:clipChildren="true" android:layout_height="wrap_content"> - + android:scrollbars="none"/> diff --git a/res/layout/notification_sbn_log_row.xml b/res/layout/notification_sbn_log_row.xml index 40c81fa6afd..5fa1b5d8c20 100644 --- a/res/layout/notification_sbn_log_row.xml +++ b/res/layout/notification_sbn_log_row.xml @@ -79,6 +79,7 @@ android:layout_marginEnd="6dp" android:paddingTop="1dp" android:scaleType="fitCenter" + android:contentDescription="@*android:string/notification_work_profile_content_description" android:layout_toStartOf="@id/timestamp" /> diff --git a/res/values/strings.xml b/res/values/strings.xml index fd869d425e4..450eb1301a1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8093,6 +8093,9 @@ view notification settings + + open notification + Allow notification snoozing @@ -9229,9 +9232,9 @@ %1$s used in %2$s - Internal storage + internal storage - External storage + external storage %1$s used since %2$s diff --git a/res/xml/channel_notification_settings.xml b/res/xml/channel_notification_settings.xml index 1117921f9de..ff1427b7d7b 100644 --- a/res/xml/channel_notification_settings.xml +++ b/res/xml/channel_notification_settings.xml @@ -108,12 +108,6 @@ settings:useAdditionalSummary="true" settings:restrictedSwitchSummary="@string/enabled_by_admin"/> - - (mControllers); } diff --git a/src/com/android/settings/notification/app/ConversationPromotePreferenceController.java b/src/com/android/settings/notification/app/ConversationPromotePreferenceController.java index 766e4aafc42..5a6fa51b2c8 100644 --- a/src/com/android/settings/notification/app/ConversationPromotePreferenceController.java +++ b/src/com/android/settings/notification/app/ConversationPromotePreferenceController.java @@ -66,6 +66,7 @@ public class ConversationPromotePreferenceController extends NotificationPrefere return false; } mChannel.setDemoted(false); + mChannel.setBypassDnd(false); saveChannel(); if (mHostFragment != null) { diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java index ff68c219672..21aecdbab39 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java +++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java @@ -101,14 +101,12 @@ public class NotificationHistoryActivity extends Activity { count.setText(getResources().getQuantityString(R.plurals.notification_history_count, nhp.notifications.size(), nhp.notifications.size())); - RecyclerView rv = viewForPackage.findViewById(R.id.notification_list); - LinearLayoutManager lm = new LinearLayoutManager(this); - rv.setLayoutManager(lm); - rv.setAdapter(new NotificationHistoryAdapter()); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( - rv.getContext(), lm.getOrientation()); - rv.addItemDecoration(dividerItemDecoration); - ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(nhp.notifications); + NotificationHistoryRecyclerView rv = + viewForPackage.findViewById(R.id.notification_list); + rv.setAdapter(new NotificationHistoryAdapter(mNm, rv)); + ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete( + new ArrayList<>(nhp.notifications)); + mTodayView.addView(viewForPackage); } }; diff --git a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java index 4448dee3f6c..a06939ac4d1 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java +++ b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java @@ -16,11 +16,10 @@ package com.android.settings.notification.history; -import android.app.NotificationHistory; +import android.app.INotificationManager; import android.app.NotificationHistory.HistoricalNotification; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.os.UserHandle; +import android.os.RemoteException; +import android.util.Slog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -29,24 +28,25 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; -import com.android.settings.notification.NotificationBackend; -import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.TreeMap; public class NotificationHistoryAdapter extends - RecyclerView.Adapter { + RecyclerView.Adapter implements + NotificationHistoryRecyclerView.OnItemSwipeDeleteListener { + private static String TAG = "NotiHistoryAdapter"; + + private INotificationManager mNm; private List mValues; - public NotificationHistoryAdapter() { + public NotificationHistoryAdapter(INotificationManager nm, + NotificationHistoryRecyclerView listView) { mValues = new ArrayList<>(); setHasStableIds(true); + listView.setOnItemSwipeDeleteListener(this); + mNm = nm; } @Override @@ -77,4 +77,18 @@ public class NotificationHistoryAdapter extends mValues.sort((o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs())); notifyDataSetChanged(); } + + @Override + public void onItemSwipeDeleted(int position) { + HistoricalNotification hn = mValues.remove(position); + if (hn != null) { + try { + mNm.deleteNotificationHistoryItem( + hn.getPackage(), hn.getUid(), hn.getPostedTimeMs()); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to delete item", e); + } + } + notifyItemRemoved(position); + } } diff --git a/src/com/android/settings/notification/history/NotificationHistoryPackage.java b/src/com/android/settings/notification/history/NotificationHistoryPackage.java index 5170b75d7fd..92920442d9b 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryPackage.java +++ b/src/com/android/settings/notification/history/NotificationHistoryPackage.java @@ -20,27 +20,31 @@ import android.app.NotificationHistory; import android.graphics.drawable.Drawable; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; public class NotificationHistoryPackage { String pkgName; int uid; - List notifications; + TreeSet notifications; CharSequence label; Drawable icon; public NotificationHistoryPackage(String pkgName, int uid) { this.pkgName = pkgName; this.uid = uid; - notifications = new ArrayList<>(); + notifications = new TreeSet<>( + (o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs())); } public long getMostRecent() { if (notifications.isEmpty()) { return 0; } - return notifications.get(0).getPostedTimeMs(); + return notifications.first().getPostedTimeMs(); } @Override diff --git a/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java b/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java new file mode 100644 index 00000000000..eaaa7c99edf --- /dev/null +++ b/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java @@ -0,0 +1,66 @@ +package com.android.settings.notification.history; + +import android.annotation.Nullable; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.View; + +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +public class NotificationHistoryRecyclerView extends RecyclerView { + + private static final String TAG = "HistoryRecyclerView"; + + private OnItemSwipeDeleteListener listener; + + public NotificationHistoryRecyclerView(Context context) { + this(context, null); + } + + public NotificationHistoryRecyclerView(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public NotificationHistoryRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + setLayoutManager(new LinearLayoutManager(getContext())); + addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL)); + ItemTouchHelper touchHelper = new ItemTouchHelper( + new DismissTouchHelper(0, ItemTouchHelper.START | ItemTouchHelper.END)); + touchHelper.attachToRecyclerView(this); + } + + public void setOnItemSwipeDeleteListener(OnItemSwipeDeleteListener listener) { + this.listener = listener; + } + + private class DismissTouchHelper extends ItemTouchHelper.SimpleCallback { + + public DismissTouchHelper(int dragDirs, int swipeDirs) { + super(dragDirs, swipeDirs); + } + + @Override + public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) { + // Do nothing. + return false; + } + + @Override + public void onSwiped(ViewHolder viewHolder, int direction) { + if (listener != null) { + listener.onItemSwipeDeleted(viewHolder.getAdapterPosition()); + } + } + } + + public interface OnItemSwipeDeleteListener { + void onItemSwipeDeleted(int position); + } +} \ No newline at end of file diff --git a/src/com/android/settings/notification/history/NotificationSbnAdapter.java b/src/com/android/settings/notification/history/NotificationSbnAdapter.java index ca2bfcbc5ed..c7f68abac14 100644 --- a/src/com/android/settings/notification/history/NotificationSbnAdapter.java +++ b/src/com/android/settings/notification/history/NotificationSbnAdapter.java @@ -20,7 +20,6 @@ import static android.app.Notification.COLOR_DEFAULT; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.NameNotFoundException; import static android.os.UserHandle.USER_ALL; -import static android.os.UserHandle.USER_CURRENT; import android.annotation.ColorInt; import android.annotation.UserIdInt; @@ -48,7 +47,6 @@ import com.android.internal.util.ContrastColorUtil; import com.android.settings.R; import java.util.ArrayList; -import java.util.Currency; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -92,7 +90,7 @@ public class NotificationSbnAdapter extends final StatusBarNotification sbn = mValues.get(position); if (sbn != null) { holder.setIcon(loadIcon(sbn)); - holder.setPackageName(loadPackageName(sbn.getPackageName()).toString()); + holder.setPackageLabel(loadPackageLabel(sbn.getPackageName()).toString()); holder.setTitle(getTitleString(sbn.getNotification())); holder.setSummary(getTextString(mContext, sbn.getNotification())); holder.setPostedTime(sbn.getPostTime()); @@ -103,6 +101,8 @@ public class NotificationSbnAdapter extends mUserBadgeCache.put(userId, profile); } holder.setProfileBadge(mUserBadgeCache.get(userId)); + holder.addOnClick(sbn.getPackageName(), sbn.getUserId(), + sbn.getNotification().contentIntent); } else { Slog.w(TAG, "null entry in list at position " + position); } @@ -133,7 +133,7 @@ public class NotificationSbnAdapter extends notifyDataSetChanged(); } - private @NonNull CharSequence loadPackageName(String pkg) { + private @NonNull CharSequence loadPackageLabel(String pkg) { try { ApplicationInfo info = mPm.getApplicationInfo(pkg, MATCH_ANY_USER); diff --git a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java index 79cda7fe267..27b4b73d09c 100644 --- a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java +++ b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java @@ -16,19 +16,26 @@ package com.android.settings.notification.history; +import android.app.PendingIntent; +import android.content.Intent; import android.graphics.drawable.Drawable; -import android.graphics.drawable.Icon; +import android.os.UserHandle; import android.text.TextUtils; +import android.util.Slog; import android.view.View; import android.widget.DateTimeView; import android.widget.ImageView; import android.widget.TextView; +import androidx.core.view.AccessibilityDelegateCompat; +import androidx.core.view.ViewCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { + private static final String TAG = "SbnViewHolder"; private final TextView mPkgName; private final ImageView mIcon; @@ -63,7 +70,7 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { mIcon.setImageDrawable(icon); } - void setPackageName(String pkg) { + void setPackageLabel(String pkg) { mPkgName.setText(pkg); } @@ -74,4 +81,34 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { void setProfileBadge(Drawable badge) { mProfileBadge.setImageDrawable(badge); } + + void addOnClick(String pkg, int userId, PendingIntent pi) { + itemView.setOnClickListener(v -> { + if (pi != null) { + try { + pi.send(); + } catch (PendingIntent.CanceledException e) { + Slog.e(TAG, "Could not launch", e); + } + } else { + Intent appIntent = new Intent(Intent.ACTION_MAIN) + .setPackage(pkg); + appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + itemView.getContext().startActivityAsUser(appIntent, UserHandle.of(userId)); + } + }); + ViewCompat.setAccessibilityDelegate(itemView, new AccessibilityDelegateCompat() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, + AccessibilityNodeInfoCompat info) { + super.onInitializeAccessibilityNodeInfo(host, info); + CharSequence description = host.getResources().getText( + R.string.notification_history_open_notification); + AccessibilityNodeInfoCompat.AccessibilityActionCompat customClick = + new AccessibilityNodeInfoCompat.AccessibilityActionCompat( + AccessibilityNodeInfoCompat.ACTION_CLICK, description); + info.addAction(customClick); + } + }); + } } diff --git a/src/com/android/settings/notification/zen/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeButtonPreferenceController.java index a53b4fa334c..8c1f3ec033c 100644 --- a/src/com/android/settings/notification/zen/ZenModeButtonPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModeButtonPreferenceController.java @@ -39,6 +39,9 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference private static final String TAG = "EnableZenModeButton"; private final FragmentManager mFragment; + + // DND can also be toggled from QS. If DND wasn't toggled by this preference, don't requestFocus + private boolean mButtonTriggered = false; private Button mZenButtonOn; private Button mZenButtonOff; @@ -65,7 +68,6 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference if (null == mZenButtonOn) { mZenButtonOn = ((LayoutPreference) preference) .findViewById(R.id.zen_mode_settings_turn_on_button); - mZenButtonOn.setFocusableInTouchMode(true); updateZenButtonOnClickListener(preference); } @@ -73,6 +75,7 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference mZenButtonOff = ((LayoutPreference) preference) .findViewById(R.id.zen_mode_settings_turn_off_button); mZenButtonOff.setOnClickListener(v -> { + mButtonTriggered = true; writeMetrics(preference, false); mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF); }); @@ -88,38 +91,39 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: mZenButtonOff.setVisibility(View.VISIBLE); mZenButtonOn.setVisibility(View.GONE); - mZenButtonOff.requestFocus(); + if (mButtonTriggered) { + mButtonTriggered = false; + mZenButtonOff.requestFocus(); + } break; case Settings.Global.ZEN_MODE_OFF: default: mZenButtonOff.setVisibility(View.GONE); updateZenButtonOnClickListener(preference); mZenButtonOn.setVisibility(View.VISIBLE); - mZenButtonOn.requestFocus(); + if (mButtonTriggered) { + mButtonTriggered = false; + mZenButtonOn.requestFocus(); + } } } private void updateZenButtonOnClickListener(Preference preference) { - int zenDuration = getZenDuration(); - switch (zenDuration) { - case Settings.Secure.ZEN_DURATION_PROMPT: - mZenButtonOn.setOnClickListener(v -> { - writeMetrics(preference, true); + mZenButtonOn.setOnClickListener(v -> { + mButtonTriggered = true; + writeMetrics(preference, true); + int zenDuration = getZenDuration(); + switch (zenDuration) { + case Settings.Secure.ZEN_DURATION_PROMPT: new SettingsEnableZenModeDialog().show(mFragment, TAG); - }); - break; - case Settings.Secure.ZEN_DURATION_FOREVER: - mZenButtonOn.setOnClickListener(v -> { - writeMetrics(preference, true); + break; + case Settings.Secure.ZEN_DURATION_FOREVER: mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); - }); - break; - default: - mZenButtonOn.setOnClickListener(v -> { - writeMetrics(preference, true); + break; + default: mBackend.setZenModeForDuration(zenDuration); - }); - } + } + }); } private void writeMetrics(Preference preference, boolean buttonOn) { diff --git a/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java b/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java index 6b1f46ca9b1..d088c0a4291 100644 --- a/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java +++ b/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceController.java @@ -109,7 +109,7 @@ public class ZenModeBypassingAppsPreferenceController extends AbstractZenModePre String pkg = entry.info.packageName; for (NotificationChannel channel : mNotificationBackend .getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) { - if (!TextUtils.isEmpty(channel.getConversationId())) { + if (!TextUtils.isEmpty(channel.getConversationId()) && !channel.isDemoted()) { // conversation channels that bypass dnd will be shown on the People page continue; } diff --git a/src/com/android/settings/panel/MediaOutputPanel.java b/src/com/android/settings/panel/MediaOutputPanel.java index 31ae31b503c..f528cea4f5a 100644 --- a/src/com/android/settings/panel/MediaOutputPanel.java +++ b/src/com/android/settings/panel/MediaOutputPanel.java @@ -220,6 +220,7 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC if (TextUtils.equals(controller.getPackageName(), mPackageName)) { mMediaController = controller; mMediaController.registerCallback(mCb); + mCallback.onHeaderChanged(); break; } } diff --git a/src/com/android/settings/search/CustomSiteMapRegistry.java b/src/com/android/settings/search/CustomSiteMapRegistry.java new file mode 100644 index 00000000000..300cf17211d --- /dev/null +++ b/src/com/android/settings/search/CustomSiteMapRegistry.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 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.search; + +import android.util.ArrayMap; + +import com.android.settings.DisplaySettings; +import com.android.settings.network.NetworkDashboardFragment; +import com.android.settings.security.SecuritySettings; +import com.android.settings.security.screenlock.ScreenLockSettings; +import com.android.settings.wallpaper.WallpaperSuggestionActivity; +import com.android.settings.wifi.WifiSettings2; + +import java.util.Map; + +/** + * A registry of custom site map. + */ +public class CustomSiteMapRegistry { + + /** + * Map from child class to parent class. + */ + public static final Map CUSTOM_SITE_MAP; + + static { + CUSTOM_SITE_MAP = new ArrayMap<>(); + CUSTOM_SITE_MAP.put(ScreenLockSettings.class.getName(), SecuritySettings.class.getName()); + CUSTOM_SITE_MAP.put( + WallpaperSuggestionActivity.class.getName(), DisplaySettings.class.getName()); + CUSTOM_SITE_MAP.put( + WifiSettings2.class.getName(), NetworkDashboardFragment.class.getName()); + } +} diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java index bb3c76264e9..736a27016fb 100644 --- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java +++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java @@ -211,6 +211,14 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { .add(SearchIndexablesContract.SiteMapColumns.CHILD_TITLE, childTitle); } } + + // Loop through custom site map registry to build additional SiteMapPairs + for (String childClass : CustomSiteMapRegistry.CUSTOM_SITE_MAP.keySet()) { + final String parentClass = CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(childClass); + cursor.newRow() + .add(SearchIndexablesContract.SiteMapColumns.PARENT_CLASS, parentClass) + .add(SearchIndexablesContract.SiteMapColumns.CHILD_CLASS, childClass); + } // Done. return cursor; } diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java index a00bb2324d4..96aae0ea4bb 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java @@ -419,7 +419,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment updateBody(); - if (mImsManager.isWfcEnabledByPlatform()) { + if (queryImsState(mSubId).isWifiCallingSupported()) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); mSwitchBar.addOnSwitchChangeListener(this); diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceControllerTest.java index 5fc3f2a1645..df4678e9e1a 100644 --- a/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceControllerTest.java @@ -93,6 +93,7 @@ public class FaceSettingsLockscreenBypassPreferenceControllerTest { boolean state = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0; + assertThat(mController.isChecked()).isFalse(); assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue(); boolean newState = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0) != 0; diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java index 086beedc1f3..8717b6f357e 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java @@ -42,6 +42,7 @@ import androidx.slice.SliceProvider; import androidx.slice.widget.SliceLiveData; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -202,6 +203,8 @@ public class MediaOutputIndicatorSliceTest { assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra( MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); + assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue() + .getPackage())).isTrue(); assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable( MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue(); } @@ -217,6 +220,8 @@ public class MediaOutputIndicatorSliceTest { assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra( MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); + assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue() + .getPackage())).isTrue(); assertThat(intentCaptor.getValue().getExtras().getParcelable( MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue(); } diff --git a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java index 3daf6cb0f1e..0949f1c0262 100644 --- a/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java +++ b/tests/robotests/src/com/android/settings/network/ims/MockVtQueryImsState.java @@ -19,15 +19,13 @@ package com.android.settings.network.ims; import android.content.Context; import android.telephony.ims.ImsException; -import com.android.ims.ImsManager; - - /** * Controller class for mock VT status */ public class MockVtQueryImsState extends VtQueryImsState { private Boolean mIsTtyOnVolteEnabled; + private Boolean mIsEnabledOnPlatform; private Boolean mIsProvisionedOnDevice; private Boolean mIsEnabledByUser; private Boolean mIsServiceStateReady; @@ -42,10 +40,6 @@ public class MockVtQueryImsState extends VtQueryImsState { super(context, subId); } - public ImsManager getImsManager(int subId) { - return super.getImsManager(subId); - } - public void setIsTtyOnVolteEnabled(boolean enabled) { mIsTtyOnVolteEnabled = enabled; } @@ -58,6 +52,19 @@ public class MockVtQueryImsState extends VtQueryImsState { return super.isTtyOnVolteEnabled(subId); } + public void setIsEnabledByPlatform(boolean isEnabled) { + mIsEnabledOnPlatform = isEnabled; + } + + @Override + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsEnabledOnPlatform != null) { + return mIsEnabledOnPlatform; + } + return super.isEnabledByPlatform(subId); + } + public void setIsProvisionedOnDevice(boolean isProvisioned) { mIsProvisionedOnDevice = isProvisioned; } diff --git a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java index 8123c935b1a..af1031da07f 100644 --- a/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java +++ b/tests/robotests/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java @@ -17,6 +17,7 @@ package com.android.settings.network.ims; import android.content.Context; +import android.telephony.ims.ImsException; import com.android.ims.ImsManager; @@ -27,6 +28,7 @@ import com.android.ims.ImsManager; public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState { private Boolean mIsTtyOnVolteEnabled; + private Boolean mIsEnabledOnPlatform; private Boolean mIsProvisionedOnDevice; private Boolean mIsEnabledByUser; @@ -56,6 +58,20 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState { return super.isTtyOnVolteEnabled(subId); } + + public void setIsEnabledByPlatform(boolean isEnabled) { + mIsEnabledOnPlatform = isEnabled; + } + + @Override + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsEnabledOnPlatform != null) { + return mIsEnabledOnPlatform; + } + return super.isEnabledByPlatform(subId); + } + public void setIsProvisionedOnDevice(boolean isProvisioned) { mIsProvisionedOnDevice = isProvisioned; } diff --git a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java index 04fc4b94889..0aaf0d25069 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/VideoCallingPreferenceControllerTest.java @@ -31,9 +31,8 @@ import android.telephony.ims.ProvisioningManager; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; -import com.android.ims.ImsManager; +import com.android.settings.network.ims.MockVolteQueryImsState; import com.android.settings.network.ims.MockVtQueryImsState; -import com.android.settings.network.ims.VolteQueryImsState; import org.junit.Before; import org.junit.Test; @@ -50,8 +49,6 @@ public class VideoCallingPreferenceControllerTest { @Mock private TelephonyManager mTelephonyManager; @Mock - private ImsManager mImsManager; - @Mock private ProvisioningManager mProvisioningManager; @Mock private CarrierConfigManager mCarrierConfigManager; @@ -59,7 +56,7 @@ public class VideoCallingPreferenceControllerTest { private PreferenceScreen mPreferenceScreen; private MockVtQueryImsState mQueryImsState; - private VolteQueryImsState mQueryVoLteState; + private MockVolteQueryImsState mQueryVoLteState; private VideoCallingPreferenceController mController; private PersistableBundle mCarrierConfig; @@ -81,12 +78,11 @@ public class VideoCallingPreferenceControllerTest { CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true); doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID); - mQueryImsState = spy(new MockVtQueryImsState(mContext, SUB_ID)); - doReturn(true).when(mQueryImsState).isEnabledByUser(); - doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt()); + mQueryImsState = new MockVtQueryImsState(mContext, SUB_ID); + mQueryImsState.setIsEnabledByUser(true); - mQueryVoLteState = spy(new VolteQueryImsState(mContext, SUB_ID)); - doReturn(true).when(mQueryVoLteState).isEnabledByUser(); + mQueryVoLteState = new MockVolteQueryImsState(mContext, SUB_ID); + mQueryVoLteState.setIsEnabledByUser(true); mPreference = new SwitchPreference(mContext); mController = spy(new VideoCallingPreferenceController(mContext, "wifi_calling")); @@ -95,7 +91,7 @@ public class VideoCallingPreferenceControllerTest { doReturn(mQueryVoLteState).when(mController).queryVoLteState(anyInt()); mPreference.setKey(mController.getPreferenceKey()); - doReturn(true).when(mImsManager).isVtEnabledByPlatform(); + mQueryImsState.setIsEnabledByPlatform(true); mQueryImsState.setIsProvisionedOnDevice(true); mQueryImsState.setServiceStateReady(true); doReturn(true).when(mTelephonyManager).isDataEnabled(); @@ -111,7 +107,7 @@ public class VideoCallingPreferenceControllerTest { @Test public void isVideoCallEnabled_disabledByPlatform_returnFalse() { mQueryImsState.setIsProvisionedOnDevice(false); - doReturn(false).when(mImsManager).isVtEnabledByPlatform(); + mQueryImsState.setIsEnabledByPlatform(false); assertThat(mController.isVideoCallEnabled(SUB_ID)).isFalse(); } @@ -127,8 +123,8 @@ public class VideoCallingPreferenceControllerTest { @Test public void updateState_4gLteOff_disabled() { - doReturn(false).when(mQueryImsState).isEnabledByUser(); - doReturn(false).when(mQueryVoLteState).isEnabledByUser(); + mQueryImsState.setIsEnabledByUser(false); + mQueryVoLteState.setIsEnabledByUser(false); mController.updateState(mPreference); @@ -138,9 +134,9 @@ public class VideoCallingPreferenceControllerTest { @Test public void updateState_4gLteOnWithoutCall_checked() { - doReturn(true).when(mQueryImsState).isEnabledByUser(); - doReturn(true).when(mQueryVoLteState).isEnabledByUser(); - doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled(); + mQueryImsState.setIsEnabledByUser(true); + mQueryVoLteState.setIsEnabledByUser(true); + mQueryImsState.setIsTtyOnVolteEnabled(true); mController.mCallState = TelephonyManager.CALL_STATE_IDLE; mController.updateState(mPreference); @@ -152,7 +148,7 @@ public class VideoCallingPreferenceControllerTest { @Test public void displayPreference_notAvailable_setPreferenceInvisible() { - doReturn(false).when(mImsManager).isVtEnabledByPlatform(); + mQueryImsState.setIsEnabledByPlatform(false); mController.displayPreference(mPreferenceScreen); diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationPromotePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationPromotePreferenceControllerTest.java index 9b60c97805c..80e2dd5d103 100644 --- a/tests/robotests/src/com/android/settings/notification/app/ConversationPromotePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/ConversationPromotePreferenceControllerTest.java @@ -110,6 +110,7 @@ public class ConversationPromotePreferenceControllerTest { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT); channel.setConversationId("a", "a"); channel.setDemoted(true); + channel.setBypassDnd(true); mController.onResume(appRow, channel, null, null, null, null); Preference pref = mock(Preference.class); @@ -121,6 +122,7 @@ public class ConversationPromotePreferenceControllerTest { verify(mBackend).updateChannel(eq(null), anyInt(), captor.capture()); assertFalse(captor.getValue().isDemoted()); + assertFalse(captor.getValue().canBypassDnd()); verify(mFragment).getActivity(); } diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java index a6efaaf883c..a9b82ebcba7 100644 --- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeBypassingAppsPreferenceControllerTest.java @@ -135,7 +135,9 @@ public class ZenModeBypassingAppsPreferenceControllerTest { appEntries.add(entry2); List channelsBypassing = new ArrayList<>(); - channelsBypassing.add(mock(NotificationChannel.class)); + NotificationChannel mockChannel = mock(NotificationChannel.class); + when(mockChannel.getConversationId()).thenReturn(null); // not a conversation + channelsBypassing.add(mockChannel); when(mBackend.getNotificationChannelsBypassingDnd(entry1.info.packageName, entry1.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing)); @@ -151,6 +153,73 @@ public class ZenModeBypassingAppsPreferenceControllerTest { assertThat(mController.getSummary().contains(entry2.label)).isTrue(); } + @Test + public void testUpdateBypassingApps_conversation() { + // GIVEN DND is off + Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, + Settings.Global.ZEN_MODE_OFF); + + // mock app list + ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class); + entry.info = new ApplicationInfo(); + entry.info.packageName = "test"; + entry.label = "test"; + entry.info.uid = 0; + + List appEntries = new ArrayList<>(); + appEntries.add(entry); + + List channelsBypassing = new ArrayList<>(); + NotificationChannel conversation = mock(NotificationChannel.class); + when(conversation.getConversationId()).thenReturn("conversation!"); + channelsBypassing.add(conversation); + + when(mBackend.getNotificationChannelsBypassingDnd(entry.info.packageName, + entry.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing)); + + // WHEN a single app is passed to the controller with a conversation notif channel + mController.updateAppsBypassingDndSummaryText(appEntries); + + // THEN the preference is enabled and the summary doesn't contain any apps because the + // only channel bypassing DND is a conversation (which will be showed on the + // conversations page instead of the apps page) + assertThat(mController.mPreference.isEnabled()).isTrue(); + assertThat(mController.getSummary().contains("No apps")).isTrue(); + } + + @Test + public void testUpdateBypassingApps_demotedConversation() { + // GIVEN DND is off + Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, + Settings.Global.ZEN_MODE_OFF); + + // mock app list + ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class); + entry.info = new ApplicationInfo(); + entry.info.packageName = "test"; + entry.label = "test"; + entry.info.uid = 0; + + List appEntries = new ArrayList<>(); + appEntries.add(entry); + + List channelsBypassing = new ArrayList<>(); + NotificationChannel demotedConversation = mock(NotificationChannel.class); + when(demotedConversation.getConversationId()).thenReturn("conversationId"); + when(demotedConversation.isDemoted()).thenReturn(true); + channelsBypassing.add(demotedConversation); + + when(mBackend.getNotificationChannelsBypassingDnd(entry.info.packageName, + entry.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing)); + + // WHEN a single app is passed to the controller with a demoted conversation notif channel + mController.updateAppsBypassingDndSummaryText(appEntries); + + // THEN the preference is enabled and the summary contains the app name from the list + assertThat(mController.mPreference.isEnabled()).isTrue(); + assertThat(mController.getSummary().contains(entry.label)).isTrue(); + } + @Test public void testUpdateAppsBypassingDnd_nullAppsList() { // GIVEN DND is off diff --git a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java index 563028e96cb..0f30c200bf1 100644 --- a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java +++ b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java @@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -58,6 +59,7 @@ import java.util.List; public class MediaOutputPanelTest { private static final String TEST_PACKAGENAME = "com.test.packagename"; + private static final String TEST_PACKAGENAME2 = "com.test.packagename2"; private static final String TEST_ARTIST = "test_artist"; private static final String TEST_SONG = "test_song"; @@ -131,6 +133,21 @@ public class MediaOutputPanelTest { verify(mLocalMediaManager).startScan(); } + @Test + public void onStart_activeSession_verifyOnHeaderChanged() { + mPanel.onStart(); + + verify(mCallback).onHeaderChanged(); + } + + @Test + public void onStart_noMatchedActiveSession_verifyNeverOnHeaderChanged() { + when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGENAME2); + mPanel.onStart(); + + verify(mCallback, never()).onHeaderChanged(); + } + @Test public void onStop_shouldUnregisterCallback() { mPanel.onStop(); @@ -255,12 +272,13 @@ public class MediaOutputPanelTest { @Test public void onMetadataChanged_verifyCallOnHeaderChanged() { mPanel.onStart(); + verify(mCallback).onHeaderChanged(); verify(mMediaController).registerCallback(mControllerCbs.capture()); final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); controllerCallbacks.onMetadataChanged(mMediaMetadata); - verify(mCallback).onHeaderChanged(); + verify(mCallback, times(2)).onHeaderChanged(); } @Test diff --git a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java new file mode 100644 index 00000000000..5bd4538dfa5 --- /dev/null +++ b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 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.search; + +import static com.google.common.truth.Truth.assertThat; + +import com.android.settings.DisplaySettings; +import com.android.settings.network.NetworkDashboardFragment; +import com.android.settings.security.SecuritySettings; +import com.android.settings.security.screenlock.ScreenLockSettings; +import com.android.settings.wallpaper.WallpaperSuggestionActivity; +import com.android.settings.wifi.WifiSettings2; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class CustomSiteMapRegistryTest { + + @Test + public void shouldContainScreenLockSettingsPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(ScreenLockSettings.class.getName())) + .isEqualTo(SecuritySettings.class.getName()); + } + + @Test + public void shouldContainWallpaperSuggestionActivityPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get( + WallpaperSuggestionActivity.class.getName())) + .isEqualTo(DisplaySettings.class.getName()); + } + + @Test + public void shouldContainWifiSettings2Pairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(WifiSettings2.class.getName())) + .isEqualTo(NetworkDashboardFragment.class.getName()); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java index 4db63e7d3ef..1d13232345e 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -109,7 +110,7 @@ public class WifiMasterSwitchPreferenceControllerTest { mController.onPause(); verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); - verify(mConnectivityManager).unregisterNetworkCallback( + verify(mConnectivityManager, times(2)).unregisterNetworkCallback( any(ConnectivityManager.NetworkCallback.class)); } diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java index dc3b2b0a714..90633cb8d6b 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsTest.java @@ -78,7 +78,8 @@ public class WifiCallingSettingsTest { doReturn(true).when(mQueryImsState2).isEnabledByUser(); doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt()); doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt()); - doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); + mQueryImsState1.setIsEnabledByPlatform(true); + mQueryImsState2.setIsEnabledByPlatform(true); mQueryImsState1.setIsProvisionedOnDevice(true); mQueryImsState2.setIsProvisionedOnDevice(true); @@ -100,7 +101,7 @@ public class WifiCallingSettingsTest { SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>( Collections.singletonList(info))); - doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); + mQueryImsState1.setIsEnabledByPlatform(true); mQueryImsState1.setIsProvisionedOnDevice(true); final Intent intent = new Intent();