Snap for 6349563 from 545c95317c to mainline-release

Change-Id: I67899520e4e195c2b6eda28dbdeb12b71def4d73
This commit is contained in:
android-build-team Robot
2020-03-31 07:13:46 +00:00
37 changed files with 489 additions and 143 deletions

View File

@@ -16,7 +16,6 @@
<ScrollView <ScrollView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:id="@+id/scroll" android:id="@+id/scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@@ -43,6 +42,7 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:contentDescription="@string/notification_history" android:contentDescription="@string/notification_history"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:focusable="false"
android:tint="?android:attr/colorControlNormal" android:tint="?android:attr/colorControlNormal"
android:src="@drawable/ic_history" /> android:src="@drawable/ic_history" />
@@ -55,6 +55,7 @@
android:layout_marginStart="48dp" android:layout_marginStart="48dp"
android:layout_marginEnd="48dp" android:layout_marginEnd="48dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:focusable="true"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/notification_history_off_title_extended" /> android:text="@string/notification_history_off_title_extended" />
@@ -68,6 +69,7 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:textAlignment="center" android:textAlignment="center"
android:focusable="true"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/notification_history_off_summary" /> android:text="@string/notification_history_off_summary" />
</LinearLayout> </LinearLayout>
@@ -106,11 +108,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="true" android:clipChildren="true"
settings:fastScrollEnabled="true" android:scrollbars="none"/>
settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>
@@ -141,11 +139,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="true" android:clipChildren="true"
settings:fastScrollEnabled="true" android:scrollbars="none"/>
settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>

View File

@@ -16,7 +16,6 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
@@ -79,16 +78,12 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:clipChildren="true" android:clipChildren="true"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView <com.android.settings.notification.history.NotificationHistoryRecyclerView
android:id="@+id/notification_list" android:id="@+id/notification_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="true" android:clipChildren="true"
settings:fastScrollEnabled="true" android:scrollbars="none"/>
settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -79,6 +79,7 @@
android:layout_marginEnd="6dp" android:layout_marginEnd="6dp"
android:paddingTop="1dp" android:paddingTop="1dp"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:contentDescription="@*android:string/notification_work_profile_content_description"
android:layout_toStartOf="@id/timestamp" android:layout_toStartOf="@id/timestamp"
/> />

View File

@@ -8093,6 +8093,9 @@
<!-- Notification history screen; content description describing what happens when you tap on a notification history entry [CHAR LIMIT=NONE] --> <!-- Notification history screen; content description describing what happens when you tap on a notification history entry [CHAR LIMIT=NONE] -->
<string name="notification_history_view_settings">view notification settings</string> <string name="notification_history_view_settings">view notification settings</string>
<!-- Notification history screen; content description describing what happens when you tap on a snoozed or recently dismissed notification [CHAR LIMIT=NONE] -->
<string name="notification_history_open_notification">open notification</string>
<!-- Configure Notifications: setting title, whether the snooze menu is shown on notifications [CHAR LIMIT=80] --> <!-- Configure Notifications: setting title, whether the snooze menu is shown on notifications [CHAR LIMIT=80] -->
<string name="snooze_options_title">Allow notification snoozing</string> <string name="snooze_options_title">Allow notification snoozing</string>
@@ -9229,9 +9232,9 @@
<!-- Summary for app storage preference --> <!-- Summary for app storage preference -->
<string name="storage_summary_format"><xliff:g id="size" example="30.00MB">%1$s</xliff:g> used in <xliff:g id="storage_type" example="internal memory">%2$s</xliff:g></string> <string name="storage_summary_format"><xliff:g id="size" example="30.00MB">%1$s</xliff:g> used in <xliff:g id="storage_type" example="internal memory">%2$s</xliff:g></string>
<!-- Summary describing internal storage for applications [CHAR LIMIT=25] --> <!-- Summary describing internal storage for applications [CHAR LIMIT=25] -->
<string name="storage_type_internal">Internal storage</string> <string name="storage_type_internal">internal storage</string>
<!-- Summary describing external storage for applications [CHAR LIMIT=25] --> <!-- Summary describing external storage for applications [CHAR LIMIT=25] -->
<string name="storage_type_external">External storage</string> <string name="storage_type_external">external storage</string>
<!-- Summary for data usage preference [CHAR LIMIT=15] --> <!-- Summary for data usage preference [CHAR LIMIT=15] -->
<string name="data_summary_format"><xliff:g id="size" example="30.00MB">%1$s</xliff:g> used since <xliff:g id="date" example="Jan 12">%2$s</xliff:g></string> <string name="data_summary_format"><xliff:g id="size" example="30.00MB">%1$s</xliff:g> used since <xliff:g id="date" example="Jan 12">%2$s</xliff:g></string>

View File

@@ -108,12 +108,6 @@
settings:useAdditionalSummary="true" settings:useAdditionalSummary="true"
settings:restrictedSwitchSummary="@string/enabled_by_admin"/> settings:restrictedSwitchSummary="@string/enabled_by_admin"/>
<com.android.settingslib.RestrictedSwitchPreference
android:key="bubble_pref"
android:title="@string/notification_bubbles_title"
android:order="16"
settings:restrictedSwitchSummary="@string/enabled_by_admin" />
<!-- Bypass DND --> <!-- Bypass DND -->
<com.android.settingslib.RestrictedSwitchPreference <com.android.settingslib.RestrictedSwitchPreference
android:key="bypass_dnd" android:key="bypass_dnd"

View File

@@ -83,7 +83,7 @@ public class AppStoragePreferenceController extends AppInfoPreferenceControllerB
: R.string.storage_type_internal); : R.string.storage_type_internal);
return mContext.getString(R.string.storage_summary_format, return mContext.getString(R.string.storage_summary_format,
Formatter.formatFileSize(mContext, stats.getTotalBytes()), Formatter.formatFileSize(mContext, stats.getTotalBytes()),
storageType.toString().toLowerCase()); storageType.toString());
} }
@Override @Override

View File

@@ -47,6 +47,11 @@ public class FaceSettingsLockscreenBypassPreferenceController
@Override @Override
public boolean isChecked() { public boolean isChecked() {
if (!FaceSettings.isAvailable(mContext)) {
return false;
} else if (getRestrictingAdmin() != null) {
return false;
}
int defaultValue = mContext.getResources().getBoolean( int defaultValue = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_faceAuthDismissesKeyguard) ? 1 : 0; com.android.internal.R.bool.config_faceAuthDismissesKeyguard) ? 1 : 0;
return Settings.Secure.getIntForUser(mContext.getContentResolver(), return Settings.Secure.getIntForUser(mContext.getContentResolver(),

View File

@@ -39,12 +39,17 @@ public class NightDisplayActivationPreferenceController extends TogglePreference
private ColorDisplayManager mColorDisplayManager; private ColorDisplayManager mColorDisplayManager;
private NightDisplayTimeFormatter mTimeFormatter; private NightDisplayTimeFormatter mTimeFormatter;
private LayoutPreference mPreference; private LayoutPreference mPreference;
// Night light can also be toggled from QS. If night light wasn't toggled by this preference,
// don't requestFocus
private boolean mButtonTriggered = false;
private Button mTurnOffButton; private Button mTurnOffButton;
private Button mTurnOnButton; private Button mTurnOnButton;
private final OnClickListener mListener = new OnClickListener() { private final OnClickListener mListener = new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
mButtonTriggered = true;
mMetricsFeatureProvider.logClickedPreference(mPreference, mMetricsFeatureProvider.logClickedPreference(mPreference,
SettingsEnums.NIGHT_DISPLAY_SETTINGS); SettingsEnums.NIGHT_DISPLAY_SETTINGS);
mColorDisplayManager.setNightDisplayActivated( mColorDisplayManager.setNightDisplayActivated(
@@ -140,12 +145,18 @@ public class NightDisplayActivationPreferenceController extends TogglePreference
mTurnOnButton.setVisibility(View.GONE); mTurnOnButton.setVisibility(View.GONE);
mTurnOffButton.setVisibility(View.VISIBLE); mTurnOffButton.setVisibility(View.VISIBLE);
mTurnOffButton.setText(buttonText); mTurnOffButton.setText(buttonText);
if (mButtonTriggered) {
mButtonTriggered = false;
mTurnOffButton.requestFocus(); mTurnOffButton.requestFocus();
}
} else { } else {
mTurnOnButton.setVisibility(View.VISIBLE); mTurnOnButton.setVisibility(View.VISIBLE);
mTurnOffButton.setVisibility(View.GONE); mTurnOffButton.setVisibility(View.GONE);
mTurnOnButton.setText(buttonText); mTurnOnButton.setText(buttonText);
if (mButtonTriggered) {
mButtonTriggered = false;
mTurnOnButton.requestFocus(); mTurnOnButton.requestFocus();
} }
} }
} }
}

View File

@@ -106,6 +106,7 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
public void onNotifyChange(Intent i) { public void onNotifyChange(Intent i) {
final MediaController mediaController = getWorker().getActiveLocalMediaController(); final MediaController mediaController = getWorker().getActiveLocalMediaController();
final Intent intent = new Intent() final Intent intent = new Intent()
.setPackage(Utils.SETTINGS_PACKAGE_NAME)
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (mediaController != null) { if (mediaController != null) {

View File

@@ -27,9 +27,6 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.ims.ImsManager;
import com.android.settings.network.SubscriptionUtil;
/** /**
* Controller class for querying VT status * Controller class for querying VT status
*/ */
@@ -65,12 +62,6 @@ public class VtQueryImsState extends ImsQueryController {
return (new ImsQueryVtUserSetting(subId)).query(); return (new ImsQueryVtUserSetting(subId)).query();
} }
@VisibleForTesting
ImsManager getImsManager(int subId) {
return ImsManager.getInstance(mContext,
SubscriptionUtil.getPhoneId(mContext, subId));
}
/** /**
* Check whether Video Call can be perform or not on this subscription * Check whether Video Call can be perform or not on this subscription
* *
@@ -81,19 +72,10 @@ public class VtQueryImsState extends ImsQueryController {
return false; return false;
} }
final ImsManager imsManager = getImsManager(mSubId);
if (imsManager == null) {
return false;
}
if (!imsManager.isVtEnabledByPlatform()) {
return false;
}
try { try {
return isServiceStateReady(mSubId); return isEnabledByPlatform(mSubId) && isServiceStateReady(mSubId);
} catch (InterruptedException | IllegalArgumentException | ImsException exception) { } catch (InterruptedException | IllegalArgumentException | ImsException exception) {
Log.w(LOG_TAG, "fail to get Vt service status. subId=" + mSubId, exception); Log.w(LOG_TAG, "fail to get Vt ready. subId=" + mSubId, exception);
} }
return false; return false;
} }

View File

@@ -20,8 +20,10 @@ import android.content.Context;
import android.telecom.TelecomManager; import android.telecom.TelecomManager;
import android.telephony.AccessNetworkConstants; import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.ims.ImsException;
import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase; import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -34,6 +36,8 @@ import com.android.settings.network.telephony.MobileNetworkUtils;
*/ */
public class WifiCallingQueryImsState extends ImsQueryController { public class WifiCallingQueryImsState extends ImsQueryController {
private static final String LOG_TAG = "WifiCallingQueryImsState";
private Context mContext; private Context mContext;
private int mSubId; private int mSubId;
@@ -68,22 +72,30 @@ public class WifiCallingQueryImsState extends ImsQueryController {
SubscriptionUtil.getPhoneId(mContext, subId)); SubscriptionUtil.getPhoneId(mContext, subId));
} }
/**
* Check whether Wifi Calling is a supported feature on this subscription
*
* @return true when Wifi Calling is a supported feature, otherwise false
*/
public boolean isWifiCallingSupported() {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
return false;
}
try {
return isEnabledByPlatform(mSubId);
} catch (InterruptedException | IllegalArgumentException | ImsException exception) {
Log.w(LOG_TAG, "fail to get WFC supporting status. subId=" + mSubId, exception);
}
return false;
}
/** /**
* Check whether Wifi Calling has been provisioned or not on this subscription * Check whether Wifi Calling has been provisioned or not on this subscription
* *
* @return true when Wifi Calling has been enabled, otherwise false * @return true when Wifi Calling has been enabled, otherwise false
*/ */
public boolean isWifiCallingProvisioned() { public boolean isWifiCallingProvisioned() {
if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { return isWifiCallingSupported() && isProvisionedOnDevice(mSubId);
return false;
}
final ImsManager imsManager = getImsManager(mSubId);
if (imsManager == null) {
return false;
}
return imsManager.isWfcEnabledByPlatform()
&& isProvisionedOnDevice(mSubId);
} }
/** /**

View File

@@ -23,7 +23,7 @@ import com.android.settings.Utils;
public class PhoneRingtonePreferenceController extends RingtonePreferenceControllerBase { public class PhoneRingtonePreferenceController extends RingtonePreferenceControllerBase {
private static final String KEY_PHONE_RINGTONE = "ringtone"; private static final String KEY_PHONE_RINGTONE = "phone_ringtone";
public PhoneRingtonePreferenceController(Context context) { public PhoneRingtonePreferenceController(Context context) {
super(context); super(context);

View File

@@ -129,8 +129,6 @@ public class ChannelNotificationSettings extends NotificationSettings {
mControllers.add(new BadgePreferenceController(context, mBackend)); mControllers.add(new BadgePreferenceController(context, mBackend));
mControllers.add(new DndPreferenceController(context, mBackend)); mControllers.add(new DndPreferenceController(context, mBackend));
mControllers.add(new NotificationsOffPreferenceController(context)); mControllers.add(new NotificationsOffPreferenceController(context));
mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(),
mBackend, false /* isAppPage */));
mControllers.add(new ConversationPromotePreferenceController(context, this, mBackend)); mControllers.add(new ConversationPromotePreferenceController(context, this, mBackend));
return new ArrayList<>(mControllers); return new ArrayList<>(mControllers);
} }

View File

@@ -66,6 +66,7 @@ public class ConversationPromotePreferenceController extends NotificationPrefere
return false; return false;
} }
mChannel.setDemoted(false); mChannel.setDemoted(false);
mChannel.setBypassDnd(false);
saveChannel(); saveChannel();
if (mHostFragment != null) { if (mHostFragment != null) {

View File

@@ -101,14 +101,12 @@ public class NotificationHistoryActivity extends Activity {
count.setText(getResources().getQuantityString(R.plurals.notification_history_count, count.setText(getResources().getQuantityString(R.plurals.notification_history_count,
nhp.notifications.size(), nhp.notifications.size())); nhp.notifications.size(), nhp.notifications.size()));
RecyclerView rv = viewForPackage.findViewById(R.id.notification_list); NotificationHistoryRecyclerView rv =
LinearLayoutManager lm = new LinearLayoutManager(this); viewForPackage.findViewById(R.id.notification_list);
rv.setLayoutManager(lm); rv.setAdapter(new NotificationHistoryAdapter(mNm, rv));
rv.setAdapter(new NotificationHistoryAdapter()); ((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration( new ArrayList<>(nhp.notifications));
rv.getContext(), lm.getOrientation());
rv.addItemDecoration(dividerItemDecoration);
((NotificationHistoryAdapter) rv.getAdapter()).onRebuildComplete(nhp.notifications);
mTodayView.addView(viewForPackage); mTodayView.addView(viewForPackage);
} }
}; };

View File

@@ -16,11 +16,10 @@
package com.android.settings.notification.history; package com.android.settings.notification.history;
import android.app.NotificationHistory; import android.app.INotificationManager;
import android.app.NotificationHistory.HistoricalNotification; import android.app.NotificationHistory.HistoricalNotification;
import android.content.Context; import android.os.RemoteException;
import android.graphics.drawable.Drawable; import android.util.Slog;
import android.os.UserHandle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -29,24 +28,25 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.notification.NotificationBackend;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class NotificationHistoryAdapter extends public class NotificationHistoryAdapter extends
RecyclerView.Adapter<NotificationHistoryViewHolder> { RecyclerView.Adapter<NotificationHistoryViewHolder> implements
NotificationHistoryRecyclerView.OnItemSwipeDeleteListener {
private static String TAG = "NotiHistoryAdapter";
private INotificationManager mNm;
private List<HistoricalNotification> mValues; private List<HistoricalNotification> mValues;
public NotificationHistoryAdapter() { public NotificationHistoryAdapter(INotificationManager nm,
NotificationHistoryRecyclerView listView) {
mValues = new ArrayList<>(); mValues = new ArrayList<>();
setHasStableIds(true); setHasStableIds(true);
listView.setOnItemSwipeDeleteListener(this);
mNm = nm;
} }
@Override @Override
@@ -77,4 +77,18 @@ public class NotificationHistoryAdapter extends
mValues.sort((o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs())); mValues.sort((o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs()));
notifyDataSetChanged(); 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);
}
} }

View File

@@ -20,27 +20,31 @@ import android.app.NotificationHistory;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
public class NotificationHistoryPackage { public class NotificationHistoryPackage {
String pkgName; String pkgName;
int uid; int uid;
List<NotificationHistory.HistoricalNotification> notifications; TreeSet<NotificationHistory.HistoricalNotification> notifications;
CharSequence label; CharSequence label;
Drawable icon; Drawable icon;
public NotificationHistoryPackage(String pkgName, int uid) { public NotificationHistoryPackage(String pkgName, int uid) {
this.pkgName = pkgName; this.pkgName = pkgName;
this.uid = uid; this.uid = uid;
notifications = new ArrayList<>(); notifications = new TreeSet<>(
(o1, o2) -> Long.compare(o2.getPostedTimeMs(), o1.getPostedTimeMs()));
} }
public long getMostRecent() { public long getMostRecent() {
if (notifications.isEmpty()) { if (notifications.isEmpty()) {
return 0; return 0;
} }
return notifications.get(0).getPostedTimeMs(); return notifications.first().getPostedTimeMs();
} }
@Override @Override

View File

@@ -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);
}
}

View File

@@ -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.MATCH_ANY_USER;
import static android.content.pm.PackageManager.NameNotFoundException; import static android.content.pm.PackageManager.NameNotFoundException;
import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_CURRENT;
import android.annotation.ColorInt; import android.annotation.ColorInt;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
@@ -48,7 +47,6 @@ import com.android.internal.util.ContrastColorUtil;
import com.android.settings.R; import com.android.settings.R;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Currency;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -92,7 +90,7 @@ public class NotificationSbnAdapter extends
final StatusBarNotification sbn = mValues.get(position); final StatusBarNotification sbn = mValues.get(position);
if (sbn != null) { if (sbn != null) {
holder.setIcon(loadIcon(sbn)); holder.setIcon(loadIcon(sbn));
holder.setPackageName(loadPackageName(sbn.getPackageName()).toString()); holder.setPackageLabel(loadPackageLabel(sbn.getPackageName()).toString());
holder.setTitle(getTitleString(sbn.getNotification())); holder.setTitle(getTitleString(sbn.getNotification()));
holder.setSummary(getTextString(mContext, sbn.getNotification())); holder.setSummary(getTextString(mContext, sbn.getNotification()));
holder.setPostedTime(sbn.getPostTime()); holder.setPostedTime(sbn.getPostTime());
@@ -103,6 +101,8 @@ public class NotificationSbnAdapter extends
mUserBadgeCache.put(userId, profile); mUserBadgeCache.put(userId, profile);
} }
holder.setProfileBadge(mUserBadgeCache.get(userId)); holder.setProfileBadge(mUserBadgeCache.get(userId));
holder.addOnClick(sbn.getPackageName(), sbn.getUserId(),
sbn.getNotification().contentIntent);
} else { } else {
Slog.w(TAG, "null entry in list at position " + position); Slog.w(TAG, "null entry in list at position " + position);
} }
@@ -133,7 +133,7 @@ public class NotificationSbnAdapter extends
notifyDataSetChanged(); notifyDataSetChanged();
} }
private @NonNull CharSequence loadPackageName(String pkg) { private @NonNull CharSequence loadPackageLabel(String pkg) {
try { try {
ApplicationInfo info = mPm.getApplicationInfo(pkg, ApplicationInfo info = mPm.getApplicationInfo(pkg,
MATCH_ANY_USER); MATCH_ANY_USER);

View File

@@ -16,19 +16,26 @@
package com.android.settings.notification.history; package com.android.settings.notification.history;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Slog;
import android.view.View; import android.view.View;
import android.widget.DateTimeView; import android.widget.DateTimeView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; 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 androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { public class NotificationSbnViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "SbnViewHolder";
private final TextView mPkgName; private final TextView mPkgName;
private final ImageView mIcon; private final ImageView mIcon;
@@ -63,7 +70,7 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder {
mIcon.setImageDrawable(icon); mIcon.setImageDrawable(icon);
} }
void setPackageName(String pkg) { void setPackageLabel(String pkg) {
mPkgName.setText(pkg); mPkgName.setText(pkg);
} }
@@ -74,4 +81,34 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder {
void setProfileBadge(Drawable badge) { void setProfileBadge(Drawable badge) {
mProfileBadge.setImageDrawable(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);
}
});
}
} }

View File

@@ -39,6 +39,9 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
private static final String TAG = "EnableZenModeButton"; private static final String TAG = "EnableZenModeButton";
private final FragmentManager mFragment; 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 mZenButtonOn;
private Button mZenButtonOff; private Button mZenButtonOff;
@@ -65,7 +68,6 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
if (null == mZenButtonOn) { if (null == mZenButtonOn) {
mZenButtonOn = ((LayoutPreference) preference) mZenButtonOn = ((LayoutPreference) preference)
.findViewById(R.id.zen_mode_settings_turn_on_button); .findViewById(R.id.zen_mode_settings_turn_on_button);
mZenButtonOn.setFocusableInTouchMode(true);
updateZenButtonOnClickListener(preference); updateZenButtonOnClickListener(preference);
} }
@@ -73,6 +75,7 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
mZenButtonOff = ((LayoutPreference) preference) mZenButtonOff = ((LayoutPreference) preference)
.findViewById(R.id.zen_mode_settings_turn_off_button); .findViewById(R.id.zen_mode_settings_turn_off_button);
mZenButtonOff.setOnClickListener(v -> { mZenButtonOff.setOnClickListener(v -> {
mButtonTriggered = true;
writeMetrics(preference, false); writeMetrics(preference, false);
mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF); mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF);
}); });
@@ -88,38 +91,39 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS: case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
mZenButtonOff.setVisibility(View.VISIBLE); mZenButtonOff.setVisibility(View.VISIBLE);
mZenButtonOn.setVisibility(View.GONE); mZenButtonOn.setVisibility(View.GONE);
if (mButtonTriggered) {
mButtonTriggered = false;
mZenButtonOff.requestFocus(); mZenButtonOff.requestFocus();
}
break; break;
case Settings.Global.ZEN_MODE_OFF: case Settings.Global.ZEN_MODE_OFF:
default: default:
mZenButtonOff.setVisibility(View.GONE); mZenButtonOff.setVisibility(View.GONE);
updateZenButtonOnClickListener(preference); updateZenButtonOnClickListener(preference);
mZenButtonOn.setVisibility(View.VISIBLE); mZenButtonOn.setVisibility(View.VISIBLE);
if (mButtonTriggered) {
mButtonTriggered = false;
mZenButtonOn.requestFocus(); mZenButtonOn.requestFocus();
} }
} }
}
private void updateZenButtonOnClickListener(Preference preference) { private void updateZenButtonOnClickListener(Preference preference) {
mZenButtonOn.setOnClickListener(v -> {
mButtonTriggered = true;
writeMetrics(preference, true);
int zenDuration = getZenDuration(); int zenDuration = getZenDuration();
switch (zenDuration) { switch (zenDuration) {
case Settings.Secure.ZEN_DURATION_PROMPT: case Settings.Secure.ZEN_DURATION_PROMPT:
mZenButtonOn.setOnClickListener(v -> {
writeMetrics(preference, true);
new SettingsEnableZenModeDialog().show(mFragment, TAG); new SettingsEnableZenModeDialog().show(mFragment, TAG);
});
break; break;
case Settings.Secure.ZEN_DURATION_FOREVER: case Settings.Secure.ZEN_DURATION_FOREVER:
mZenButtonOn.setOnClickListener(v -> {
writeMetrics(preference, true);
mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS); mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
});
break; break;
default: default:
mZenButtonOn.setOnClickListener(v -> {
writeMetrics(preference, true);
mBackend.setZenModeForDuration(zenDuration); mBackend.setZenModeForDuration(zenDuration);
});
} }
});
} }
private void writeMetrics(Preference preference, boolean buttonOn) { private void writeMetrics(Preference preference, boolean buttonOn) {

View File

@@ -109,7 +109,7 @@ public class ZenModeBypassingAppsPreferenceController extends AbstractZenModePre
String pkg = entry.info.packageName; String pkg = entry.info.packageName;
for (NotificationChannel channel : mNotificationBackend for (NotificationChannel channel : mNotificationBackend
.getNotificationChannelsBypassingDnd(pkg, entry.info.uid).getList()) { .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 // conversation channels that bypass dnd will be shown on the People page
continue; continue;
} }

View File

@@ -220,6 +220,7 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC
if (TextUtils.equals(controller.getPackageName(), mPackageName)) { if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
mMediaController = controller; mMediaController = controller;
mMediaController.registerCallback(mCb); mMediaController.registerCallback(mCb);
mCallback.onHeaderChanged();
break; break;
} }
} }

View File

@@ -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<String, String> 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());
}
}

View File

@@ -211,6 +211,14 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
.add(SearchIndexablesContract.SiteMapColumns.CHILD_TITLE, childTitle); .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. // Done.
return cursor; return cursor;
} }

View File

@@ -419,7 +419,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment
updateBody(); updateBody();
if (mImsManager.isWfcEnabledByPlatform()) { if (queryImsState(mSubId).isWifiCallingSupported()) {
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
mSwitchBar.addOnSwitchChangeListener(this); mSwitchBar.addOnSwitchChangeListener(this);

View File

@@ -93,6 +93,7 @@ public class FaceSettingsLockscreenBypassPreferenceControllerTest {
boolean state = Settings.Secure.getInt(mContext.getContentResolver(), boolean state = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0; Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, defaultValue ? 1 : 0) != 0;
assertThat(mController.isChecked()).isFalse();
assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue(); assertThat(mController.onPreferenceChange(mPreference, !state)).isTrue();
boolean newState = Settings.Secure.getInt(mContext.getContentResolver(), boolean newState = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0) != 0; Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0) != 0;

View File

@@ -42,6 +42,7 @@ import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData; import androidx.slice.widget.SliceLiveData;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -202,6 +203,8 @@ public class MediaOutputIndicatorSliceTest {
assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra( assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra(
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
.getPackage())).isTrue();
assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable( assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable(
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue(); MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
} }
@@ -217,6 +220,8 @@ public class MediaOutputIndicatorSliceTest {
assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra( assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra(
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
.getPackage())).isTrue();
assertThat(intentCaptor.getValue().getExtras().getParcelable( assertThat(intentCaptor.getValue().getExtras().getParcelable(
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue(); MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
} }

View File

@@ -19,15 +19,13 @@ package com.android.settings.network.ims;
import android.content.Context; import android.content.Context;
import android.telephony.ims.ImsException; import android.telephony.ims.ImsException;
import com.android.ims.ImsManager;
/** /**
* Controller class for mock VT status * Controller class for mock VT status
*/ */
public class MockVtQueryImsState extends VtQueryImsState { public class MockVtQueryImsState extends VtQueryImsState {
private Boolean mIsTtyOnVolteEnabled; private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice; private Boolean mIsProvisionedOnDevice;
private Boolean mIsEnabledByUser; private Boolean mIsEnabledByUser;
private Boolean mIsServiceStateReady; private Boolean mIsServiceStateReady;
@@ -42,10 +40,6 @@ public class MockVtQueryImsState extends VtQueryImsState {
super(context, subId); super(context, subId);
} }
public ImsManager getImsManager(int subId) {
return super.getImsManager(subId);
}
public void setIsTtyOnVolteEnabled(boolean enabled) { public void setIsTtyOnVolteEnabled(boolean enabled) {
mIsTtyOnVolteEnabled = enabled; mIsTtyOnVolteEnabled = enabled;
} }
@@ -58,6 +52,19 @@ public class MockVtQueryImsState extends VtQueryImsState {
return super.isTtyOnVolteEnabled(subId); 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) { public void setIsProvisionedOnDevice(boolean isProvisioned) {
mIsProvisionedOnDevice = isProvisioned; mIsProvisionedOnDevice = isProvisioned;
} }

View File

@@ -17,6 +17,7 @@
package com.android.settings.network.ims; package com.android.settings.network.ims;
import android.content.Context; import android.content.Context;
import android.telephony.ims.ImsException;
import com.android.ims.ImsManager; import com.android.ims.ImsManager;
@@ -27,6 +28,7 @@ import com.android.ims.ImsManager;
public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState { public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
private Boolean mIsTtyOnVolteEnabled; private Boolean mIsTtyOnVolteEnabled;
private Boolean mIsEnabledOnPlatform;
private Boolean mIsProvisionedOnDevice; private Boolean mIsProvisionedOnDevice;
private Boolean mIsEnabledByUser; private Boolean mIsEnabledByUser;
@@ -56,6 +58,20 @@ public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState {
return super.isTtyOnVolteEnabled(subId); 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) { public void setIsProvisionedOnDevice(boolean isProvisioned) {
mIsProvisionedOnDevice = isProvisioned; mIsProvisionedOnDevice = isProvisioned;
} }

View File

@@ -31,9 +31,8 @@ import android.telephony.ims.ProvisioningManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference; 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.MockVtQueryImsState;
import com.android.settings.network.ims.VolteQueryImsState;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -50,8 +49,6 @@ public class VideoCallingPreferenceControllerTest {
@Mock @Mock
private TelephonyManager mTelephonyManager; private TelephonyManager mTelephonyManager;
@Mock @Mock
private ImsManager mImsManager;
@Mock
private ProvisioningManager mProvisioningManager; private ProvisioningManager mProvisioningManager;
@Mock @Mock
private CarrierConfigManager mCarrierConfigManager; private CarrierConfigManager mCarrierConfigManager;
@@ -59,7 +56,7 @@ public class VideoCallingPreferenceControllerTest {
private PreferenceScreen mPreferenceScreen; private PreferenceScreen mPreferenceScreen;
private MockVtQueryImsState mQueryImsState; private MockVtQueryImsState mQueryImsState;
private VolteQueryImsState mQueryVoLteState; private MockVolteQueryImsState mQueryVoLteState;
private VideoCallingPreferenceController mController; private VideoCallingPreferenceController mController;
private PersistableBundle mCarrierConfig; private PersistableBundle mCarrierConfig;
@@ -81,12 +78,11 @@ public class VideoCallingPreferenceControllerTest {
CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true); CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true);
doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID); doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
mQueryImsState = spy(new MockVtQueryImsState(mContext, SUB_ID)); mQueryImsState = new MockVtQueryImsState(mContext, SUB_ID);
doReturn(true).when(mQueryImsState).isEnabledByUser(); mQueryImsState.setIsEnabledByUser(true);
doReturn(mImsManager).when(mQueryImsState).getImsManager(anyInt());
mQueryVoLteState = spy(new VolteQueryImsState(mContext, SUB_ID)); mQueryVoLteState = new MockVolteQueryImsState(mContext, SUB_ID);
doReturn(true).when(mQueryVoLteState).isEnabledByUser(); mQueryVoLteState.setIsEnabledByUser(true);
mPreference = new SwitchPreference(mContext); mPreference = new SwitchPreference(mContext);
mController = spy(new VideoCallingPreferenceController(mContext, "wifi_calling")); mController = spy(new VideoCallingPreferenceController(mContext, "wifi_calling"));
@@ -95,7 +91,7 @@ public class VideoCallingPreferenceControllerTest {
doReturn(mQueryVoLteState).when(mController).queryVoLteState(anyInt()); doReturn(mQueryVoLteState).when(mController).queryVoLteState(anyInt());
mPreference.setKey(mController.getPreferenceKey()); mPreference.setKey(mController.getPreferenceKey());
doReturn(true).when(mImsManager).isVtEnabledByPlatform(); mQueryImsState.setIsEnabledByPlatform(true);
mQueryImsState.setIsProvisionedOnDevice(true); mQueryImsState.setIsProvisionedOnDevice(true);
mQueryImsState.setServiceStateReady(true); mQueryImsState.setServiceStateReady(true);
doReturn(true).when(mTelephonyManager).isDataEnabled(); doReturn(true).when(mTelephonyManager).isDataEnabled();
@@ -111,7 +107,7 @@ public class VideoCallingPreferenceControllerTest {
@Test @Test
public void isVideoCallEnabled_disabledByPlatform_returnFalse() { public void isVideoCallEnabled_disabledByPlatform_returnFalse() {
mQueryImsState.setIsProvisionedOnDevice(false); mQueryImsState.setIsProvisionedOnDevice(false);
doReturn(false).when(mImsManager).isVtEnabledByPlatform(); mQueryImsState.setIsEnabledByPlatform(false);
assertThat(mController.isVideoCallEnabled(SUB_ID)).isFalse(); assertThat(mController.isVideoCallEnabled(SUB_ID)).isFalse();
} }
@@ -127,8 +123,8 @@ public class VideoCallingPreferenceControllerTest {
@Test @Test
public void updateState_4gLteOff_disabled() { public void updateState_4gLteOff_disabled() {
doReturn(false).when(mQueryImsState).isEnabledByUser(); mQueryImsState.setIsEnabledByUser(false);
doReturn(false).when(mQueryVoLteState).isEnabledByUser(); mQueryVoLteState.setIsEnabledByUser(false);
mController.updateState(mPreference); mController.updateState(mPreference);
@@ -138,9 +134,9 @@ public class VideoCallingPreferenceControllerTest {
@Test @Test
public void updateState_4gLteOnWithoutCall_checked() { public void updateState_4gLteOnWithoutCall_checked() {
doReturn(true).when(mQueryImsState).isEnabledByUser(); mQueryImsState.setIsEnabledByUser(true);
doReturn(true).when(mQueryVoLteState).isEnabledByUser(); mQueryVoLteState.setIsEnabledByUser(true);
doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled(); mQueryImsState.setIsTtyOnVolteEnabled(true);
mController.mCallState = TelephonyManager.CALL_STATE_IDLE; mController.mCallState = TelephonyManager.CALL_STATE_IDLE;
mController.updateState(mPreference); mController.updateState(mPreference);
@@ -152,7 +148,7 @@ public class VideoCallingPreferenceControllerTest {
@Test @Test
public void displayPreference_notAvailable_setPreferenceInvisible() { public void displayPreference_notAvailable_setPreferenceInvisible() {
doReturn(false).when(mImsManager).isVtEnabledByPlatform(); mQueryImsState.setIsEnabledByPlatform(false);
mController.displayPreference(mPreferenceScreen); mController.displayPreference(mPreferenceScreen);

View File

@@ -110,6 +110,7 @@ public class ConversationPromotePreferenceControllerTest {
NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT); NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_DEFAULT);
channel.setConversationId("a", "a"); channel.setConversationId("a", "a");
channel.setDemoted(true); channel.setDemoted(true);
channel.setBypassDnd(true);
mController.onResume(appRow, channel, null, null, null, null); mController.onResume(appRow, channel, null, null, null, null);
Preference pref = mock(Preference.class); Preference pref = mock(Preference.class);
@@ -121,6 +122,7 @@ public class ConversationPromotePreferenceControllerTest {
verify(mBackend).updateChannel(eq(null), anyInt(), captor.capture()); verify(mBackend).updateChannel(eq(null), anyInt(), captor.capture());
assertFalse(captor.getValue().isDemoted()); assertFalse(captor.getValue().isDemoted());
assertFalse(captor.getValue().canBypassDnd());
verify(mFragment).getActivity(); verify(mFragment).getActivity();
} }

View File

@@ -135,7 +135,9 @@ public class ZenModeBypassingAppsPreferenceControllerTest {
appEntries.add(entry2); appEntries.add(entry2);
List<NotificationChannel> channelsBypassing = new ArrayList<>(); List<NotificationChannel> 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, when(mBackend.getNotificationChannelsBypassingDnd(entry1.info.packageName,
entry1.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing)); entry1.info.uid)).thenReturn(new ParceledListSlice<>(channelsBypassing));
@@ -151,6 +153,73 @@ public class ZenModeBypassingAppsPreferenceControllerTest {
assertThat(mController.getSummary().contains(entry2.label)).isTrue(); 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<ApplicationsState.AppEntry> appEntries = new ArrayList<>();
appEntries.add(entry);
List<NotificationChannel> 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<ApplicationsState.AppEntry> appEntries = new ArrayList<>();
appEntries.add(entry);
List<NotificationChannel> 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 @Test
public void testUpdateAppsBypassingDnd_nullAppsList() { public void testUpdateAppsBypassingDnd_nullAppsList() {
// GIVEN DND is off // GIVEN DND is off

View File

@@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -58,6 +59,7 @@ import java.util.List;
public class MediaOutputPanelTest { public class MediaOutputPanelTest {
private static final String TEST_PACKAGENAME = "com.test.packagename"; 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_ARTIST = "test_artist";
private static final String TEST_SONG = "test_song"; private static final String TEST_SONG = "test_song";
@@ -131,6 +133,21 @@ public class MediaOutputPanelTest {
verify(mLocalMediaManager).startScan(); 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 @Test
public void onStop_shouldUnregisterCallback() { public void onStop_shouldUnregisterCallback() {
mPanel.onStop(); mPanel.onStop();
@@ -255,12 +272,13 @@ public class MediaOutputPanelTest {
@Test @Test
public void onMetadataChanged_verifyCallOnHeaderChanged() { public void onMetadataChanged_verifyCallOnHeaderChanged() {
mPanel.onStart(); mPanel.onStart();
verify(mCallback).onHeaderChanged();
verify(mMediaController).registerCallback(mControllerCbs.capture()); verify(mMediaController).registerCallback(mControllerCbs.capture());
final MediaController.Callback controllerCallbacks = mControllerCbs.getValue(); final MediaController.Callback controllerCallbacks = mControllerCbs.getValue();
controllerCallbacks.onMetadataChanged(mMediaMetadata); controllerCallbacks.onMetadataChanged(mMediaMetadata);
verify(mCallback).onHeaderChanged(); verify(mCallback, times(2)).onHeaderChanged();
} }
@Test @Test

View File

@@ -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());
}
}

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -109,7 +110,7 @@ public class WifiMasterSwitchPreferenceControllerTest {
mController.onPause(); mController.onPause();
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
verify(mConnectivityManager).unregisterNetworkCallback( verify(mConnectivityManager, times(2)).unregisterNetworkCallback(
any(ConnectivityManager.NetworkCallback.class)); any(ConnectivityManager.NetworkCallback.class));
} }

View File

@@ -78,7 +78,8 @@ public class WifiCallingSettingsTest {
doReturn(true).when(mQueryImsState2).isEnabledByUser(); doReturn(true).when(mQueryImsState2).isEnabledByUser();
doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt()); doReturn(mImsManager).when(mQueryImsState1).getImsManager(anyInt());
doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt()); doReturn(mImsManager).when(mQueryImsState2).getImsManager(anyInt());
doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); mQueryImsState1.setIsEnabledByPlatform(true);
mQueryImsState2.setIsEnabledByPlatform(true);
mQueryImsState1.setIsProvisionedOnDevice(true); mQueryImsState1.setIsProvisionedOnDevice(true);
mQueryImsState2.setIsProvisionedOnDevice(true); mQueryImsState2.setIsProvisionedOnDevice(true);
@@ -100,7 +101,7 @@ public class WifiCallingSettingsTest {
SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>( SubscriptionUtil.setActiveSubscriptionsForTesting(new ArrayList<>(
Collections.singletonList(info))); Collections.singletonList(info)));
doReturn(true).when(mImsManager).isWfcEnabledByPlatform(); mQueryImsState1.setIsEnabledByPlatform(true);
mQueryImsState1.setIsProvisionedOnDevice(true); mQueryImsState1.setIsProvisionedOnDevice(true);
final Intent intent = new Intent(); final Intent intent = new Intent();