Merge "Developer option off must not affect laser sensor"
diff --git a/res/layout/disable_accessibility_service_dialog_content.xml b/res/layout/disable_accessibility_service_dialog_content.xml
deleted file mode 100644
index 680de4a..0000000
--- a/res/layout/disable_accessibility_service_dialog_content.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<ScrollView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:textDirection="locale"
- android:scrollbarStyle="outsideOverlay"
- android:gravity="top">
-
- <LinearLayout
- android:theme="@style/Theme.AlertDialog"
- style="@style/AccessibilityDialog">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="center_horizontal"
- android:paddingTop="32dp"
- android:paddingLeft="24dp"
- android:paddingRight="24dp">
-
- <TextView
- android:id="@+id/permissionDialog_disable_title"
- style="@style/AccessibilityDialogTitle" />
-
- <TextView
- android:id="@+id/permissionDialog_disable_message"
- android:gravity="center"
- android:text="@string/accessibility_service_warning_description"
- style="@style/AccessibilityDialogDescription" />
-
- </LinearLayout>
- <!-- Buttons on bottom of dialog -->
- <LinearLayout
- style="@style/AccessibilityDialogButtonList">
-
- <Space
- style="@style/AccessibilityDialogButtonBarSpace"/>
-
- <Button
- android:id="@+id/permission_disable_stop_button"
- android:text="@string/accessibility_dialog_button_stop"
- style="@style/AccessibilityDialogButton" />
-
- <Button
- android:id="@+id/permission_disable_cancel_button"
- android:text="@string/accessibility_dialog_button_cancel"
- style="@style/AccessibilityDialogButton" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/res/layout/legacy_suggestion_tile.xml b/res/layout/legacy_suggestion_tile.xml
index 9af5b6b..2a18403 100644
--- a/res/layout/legacy_suggestion_tile.xml
+++ b/res/layout/legacy_suggestion_tile.xml
@@ -42,6 +42,23 @@
android:layout_marginTop="16dp"
android:layout_marginBottom="6dp"/>
+ <FrameLayout
+ android:id="@+id/close_button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_alignParentEnd="true"
+ android:paddingTop="8dp"
+ android:paddingEnd="8dp"
+ android:orientation="horizontal"
+ android:contentDescription="@string/suggestion_button_close">
+ <ImageView
+ android:layout_width="18dp"
+ android:layout_height="18dp"
+ android:layout_gravity="end|top"
+ android:alpha="0.54"
+ android:src="@drawable/ic_suggestion_close_button"/>
+ </FrameLayout>
+
</RelativeLayout>
<TextView
diff --git a/res/layout/notification_log_row.xml b/res/layout/notification_log_row.xml
index e76835e..4d44f9f 100644
--- a/res/layout/notification_log_row.xml
+++ b/res/layout/notification_log_row.xml
@@ -26,8 +26,7 @@
<RelativeLayout
android:layout_width="match_parent"
- android:layout_height="@*android:dimen/status_bar_icon_size"
- android:layout_marginBottom="6dp"
+ android:layout_height="wrap_content"
>
<ImageView
@@ -46,24 +45,38 @@
android:scaleType="fitCenter" />
<TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
+ android:id="@+id/pkgname"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:layout_toStartOf="@+id/timestamp"
android:layout_toEndOf="@id/icon"
android:ellipsize="end"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold"
- android:textAlignment="viewStart"
- android:labelFor="@android:id/button2" />
+ android:textAlignment="viewStart" />
+
+ <ImageView
+ android:id="@+id/alerted_icon"
+ android:layout_width="@*android:dimen/status_bar_icon_size"
+ android:layout_height="@*android:dimen/status_bar_icon_size"
+ android:layout_centerVertical="true"
+ android:layout_marginStart="6dp"
+ android:paddingTop="1dp"
+ android:scaleType="fitCenter"
+ android:visibility="gone"
+ android:layout_toEndOf="@id/pkgname"
+ android:tint="?android:attr/textColorSecondary"
+ android:src="@drawable/ic_notifications_alert"
+ />
<DateTimeView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingTop="13dp"
+ android:paddingBottom="13dp"
android:layout_alignBottom="@android:id/widget_frame"
android:layout_alignParentEnd="true"
android:layout_alignTop="@android:id/widget_frame"
@@ -78,26 +91,25 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="@*android:dimen/status_bar_icon_size"
- android:orientation="horizontal"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
android:layout_marginStart="30dp"
android:layout_marginBottom="6dp"
>
- <ImageView
- android:id="@+id/pkgicon"
- android:layout_width="@*android:dimen/status_bar_icon_size"
- android:layout_height="@*android:dimen/status_bar_icon_size"
- android:layout_marginStart="0dp"
- android:layout_marginEnd="6dp"
- android:contentDescription="@null"
- android:adjustViewBounds="true"
- android:maxHeight="@*android:dimen/status_bar_icon_size"
- android:maxWidth="@*android:dimen/status_bar_icon_size"
- android:scaleType="fitCenter" />
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|center_vertical"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textAlignment="viewStart"
+ />
<TextView
- android:id="@+id/pkgname"
+ android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
@@ -106,12 +118,30 @@
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textAlignment="viewStart"
- />
+ />
</LinearLayout>
- <TextView
- android:id="@+id/extra"
+ <LinearLayout
+ android:id="@+id/extra"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ >
+ <TextView
+ android:id="@+id/notification_extra"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginStart="30dp"
+ android:singleLine="false"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="10sp"
+ android:fontFamily="monospace"
+ android:textAlignment="viewStart"
+ />
+ <TextView
+ android:id="@+id/ranking_extra"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
@@ -122,6 +152,7 @@
android:textSize="10sp"
android:fontFamily="monospace"
android:textAlignment="viewStart"
- />
+ />
+ </LinearLayout>
</LinearLayout>
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index a7c1690..e205157 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -373,6 +373,34 @@
android:orientation="vertical"
android:visibility="gone">
+ <LinearLayout android:id="@+id/hidden_settings_field"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="@style/wifi_item">
+
+ <TextView android:id="@+id/hidden_settings_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/wifi_item_label"
+ android:text="@string/wifi_hidden_network" />
+
+ <Spinner android:id="@+id/hidden_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/wifi_item_spinner"
+ android:prompt="@string/wifi_hidden_network"
+ android:entries="@array/wifi_hidden_entries"/>
+
+ <TextView android:id="@+id/hidden_settings_warning"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:text="@string/wifi_hidden_network_warning"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone"/>
+ </LinearLayout>
+
<LinearLayout android:id="@+id/metered_settings_fields"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -677,34 +705,6 @@
android:checked="true" />
</LinearLayout>
</LinearLayout>
-
- <LinearLayout android:id="@+id/hidden_settings_field"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- style="@style/wifi_item">
-
- <TextView android:id="@+id/hidden_settings_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@style/wifi_item_label"
- android:text="@string/wifi_hidden_network" />
-
- <Spinner android:id="@+id/hidden_settings"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/wifi_item_spinner"
- android:prompt="@string/wifi_hidden_network"
- android:entries="@array/wifi_hidden_entries"/>
-
- <TextView android:id="@+id/hidden_settings_warning"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="8dp"
- android:text="@string/wifi_hidden_network_warning"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:visibility="gone"/>
- </LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 430819f..b545045 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8716,6 +8716,9 @@
<!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
<string name="suggestion_button_text">Ok</string>
+ <!-- Strings for suggestion card's close button [CHAR LIMIT=20] -->
+ <string name="suggestion_button_close">Close</string>
+
<!-- [CHAR LIMIT=35] Feedback on the device -->
<string name="device_feedback">Send feedback about this device</string>
@@ -9997,14 +10000,7 @@
<string name="notification_log_details_ashmem">ashmem</string>
<!-- Notification log debug tool: header: notification alert info -->
<string name="notification_log_details_alerted">notification alerted</string>
- <!-- Notification log debug tool: header: notification sound info -->
- <string name="notification_log_details_sound">sound</string>
- <!-- Notification log debug tool: header: notification vibration info -->
- <string name="notification_log_details_vibrate">vibrate</string>
- <!-- Notification log debug tool: header: notification vibration info -->
- <string name="notification_log_details_vibrate_pattern">pattern</string>
- <!-- Notification log debug tool: the word 'default' -->
- <string name="notification_log_details_default">default</string>
+ <string name="notification_log_channel">channel</string>
<!-- Notification log debug tool: the word 'none' -->
<string name="notification_log_details_none">none</string>
<!-- Notification log debug tool: missing ranking information -->
@@ -11327,4 +11323,7 @@
<!-- Summary for Enterprise Privacy settings, explaining what the user can expect to find under it [CHAR LIMIT=NONE]-->
<string name="work_policy_privacy_settings_summary">Settings managed by your IT admin</string>
+ <!-- Developer Settings: Search keywords for the Profile HWUI rendering. [CHAR_LIMIT=NONE] -->
+ <string name="track_frame_time_keywords">GPU</string>
+
</resources>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 68307fc..a89997a 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -471,7 +471,8 @@
android:key="track_frame_time"
android:title="@string/track_frame_time"
android:entries="@array/track_frame_time_entries"
- android:entryValues="@array/track_frame_time_values" />
+ android:entryValues="@array/track_frame_time_values"
+ settings:keywords="@string/track_frame_time_keywords" />
</PreferenceCategory>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index ae7c903..ea31b1c 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -53,6 +53,22 @@
settings:keywords="@string/keywords_enhance_4g_lte"
settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
+ <SwitchPreference
+ android:key="4g_calling"
+ android:title="@string/enhanced_4g_lte_mode_title_4g_calling"
+ android:persistent="false"
+ android:summary="@string/enhanced_4g_lte_mode_summary_4g_calling"
+ settings:keywords="@string/keywords_enhance_4g_lte"
+ settings:controller="com.android.settings.network.telephony.Enhanced4gCallingPreferenceController"/>
+
+ <SwitchPreference
+ android:key="advance_call"
+ android:title="@string/enhanced_4g_lte_mode_title_advanced_calling"
+ android:persistent="false"
+ android:summary="@string/enhanced_4g_lte_mode_summary"
+ settings:keywords="@string/keywords_enhance_4g_lte"
+ settings:controller="com.android.settings.network.telephony.Enhanced4gAdvancedCallingPreferenceController"/>
+
<ListPreference
android:key="preferred_network_mode_key"
android:title="@string/preferred_network_mode_title"
diff --git a/res/xml/mobile_network_settings_v2.xml b/res/xml/mobile_network_settings_v2.xml
index 31a5ef7..af1fe20 100644
--- a/res/xml/mobile_network_settings_v2.xml
+++ b/res/xml/mobile_network_settings_v2.xml
@@ -100,6 +100,22 @@
settings:keywords="@string/keywords_enhance_4g_lte"
settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
+ <SwitchPreference
+ android:key="4g_calling"
+ android:title="@string/enhanced_4g_lte_mode_title_4g_calling"
+ android:persistent="false"
+ android:summary="@string/enhanced_4g_lte_mode_summary_4g_calling"
+ settings:keywords="@string/keywords_enhance_4g_lte"
+ settings:controller="com.android.settings.network.telephony.Enhanced4gCallingPreferenceController"/>
+
+ <SwitchPreference
+ android:key="advance_call"
+ android:title="@string/enhanced_4g_lte_mode_title_advanced_calling"
+ android:persistent="false"
+ android:summary="@string/enhanced_4g_lte_mode_summary"
+ settings:keywords="@string/keywords_enhance_4g_lte"
+ settings:controller="com.android.settings.network.telephony.Enhanced4gAdvancedCallingPreferenceController"/>
+
<ListPreference
android:key="preferred_network_mode_key"
android:title="@string/preferred_network_mode_title"
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index e07ede7..b0d962a 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -39,7 +39,7 @@
settings:controller="com.android.settings.enterprise.ManageDeviceAdminPreferenceController" />
<Preference
- android:key="system_alert_window"
+ android:key="system_alert_window_app_list"
android:title="@string/system_alert_window_settings"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
settings:keywords="@string/keywords_draw_overlay"
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index 40ac641..1203e11 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -22,6 +22,7 @@
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.storage.StorageManager;
import android.text.BidiFormatter;
@@ -77,10 +78,16 @@
}
public static Dialog createDisableDialog(Activity parentActivity,
- AccessibilityServiceInfo info, View.OnClickListener listener) {
+ AccessibilityServiceInfo info, DialogInterface.OnClickListener listener) {
final AlertDialog ad = new AlertDialog.Builder(parentActivity)
- .setView(createDisableDialogContentView(parentActivity, info, listener))
+ .setTitle(parentActivity.getString(R.string.disable_service_title,
+ info.getResolveInfo().loadLabel(parentActivity.getPackageManager())))
+ .setMessage(parentActivity.getString(R.string.disable_service_message,
+ parentActivity.getString(R.string.accessibility_dialog_button_stop),
+ getServiceName(parentActivity, info)))
.setCancelable(true)
+ .setPositiveButton(R.string.accessibility_dialog_button_stop, listener)
+ .setNegativeButton(R.string.accessibility_dialog_button_cancel, listener)
.create();
return ad;
@@ -148,33 +155,6 @@
return content;
}
- private static View createDisableDialogContentView(Context context,
- AccessibilityServiceInfo info, View.OnClickListener listener) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
-
- View content = inflater.inflate(R.layout.disable_accessibility_service_dialog_content,
- null);
-
- TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_disable_title);
- permissionDialogTitle.setText(context.getString(R.string.disable_service_title,
- getServiceName(context, info)));
- TextView permissionDialogMessage = content
- .findViewById(R.id.permissionDialog_disable_message);
- permissionDialogMessage.setText(context.getString(R.string.disable_service_message,
- context.getString(R.string.accessibility_dialog_button_stop),
- getServiceName(context, info)));
-
- Button permissionAllowButton = content.findViewById(
- R.id.permission_disable_stop_button);
- Button permissionDenyButton = content.findViewById(
- R.id.permission_disable_cancel_button);
- permissionAllowButton.setOnClickListener(listener);
- permissionDenyButton.setOnClickListener(listener);
-
- return content;
- }
-
// Get the service name and bidi wrap it to protect from bidi side effects.
private static CharSequence getServiceName(Context context, AccessibilityServiceInfo info) {
final Locale locale = context.getResources().getConfiguration().getLocales().get(0);
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index ec8df88..1556bec 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -25,6 +25,7 @@
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -49,8 +50,7 @@
import java.util.List;
-public class ToggleAccessibilityServicePreferenceFragment
- extends ToggleFeaturePreferenceFragment implements View.OnClickListener {
+public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeaturePreferenceFragment {
private static final int DIALOG_ID_ENABLE_WARNING = 1;
private static final int DIALOG_ID_DISABLE_WARNING = 2;
@@ -72,6 +72,42 @@
private Dialog mDialog;
+ private final View.OnClickListener mViewOnClickListener =
+ (View view) -> {
+ if (view.getId() == R.id.permission_enable_allow_button) {
+ if (isFullDiskEncrypted()) {
+ String title = createConfirmCredentialReasonMessage();
+ Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
+ startActivityForResult(intent,
+ ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
+ } else {
+ handleConfirmServiceEnabled(true);
+ if (isServiceSupportAccessibilityButton()) {
+ showDialog(DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL);
+ }
+ }
+ } else if (view.getId() == R.id.permission_enable_deny_button) {
+ handleConfirmServiceEnabled(false);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ mDialog.dismiss();
+ };
+
+ private final DialogInterface.OnClickListener mDialogInterfaceOnClickListener =
+ (DialogInterface dialog, int which) -> {
+ switch (which) {
+ case DialogInterface.BUTTON_POSITIVE:
+ handleConfirmServiceEnabled(false);
+ break;
+ case DialogInterface.BUTTON_NEGATIVE:
+ handleConfirmServiceEnabled(true);
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ };
+
@Override
public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_SERVICE;
@@ -137,7 +173,7 @@
return null;
}
mDialog = AccessibilityServiceWarning
- .createCapabilitiesDialog(getActivity(), info, this);
+ .createCapabilitiesDialog(getActivity(), info, mViewOnClickListener);
break;
}
case DIALOG_ID_DISABLE_WARNING: {
@@ -146,7 +182,7 @@
return null;
}
mDialog = AccessibilityServiceWarning
- .createDisableDialog(getActivity(), info, this);
+ .createDisableDialog(getActivity(), info, mDialogInterfaceOnClickListener);
break;
}
case DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL: {
@@ -210,32 +246,6 @@
}
}
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.permission_enable_allow_button) {
- if (isFullDiskEncrypted()) {
- String title = createConfirmCredentialReasonMessage();
- Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
- startActivityForResult(intent,
- ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
- } else {
- handleConfirmServiceEnabled(true);
- if (isServiceSupportAccessibilityButton()) {
- showDialog(DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL);
- }
- }
- } else if (view.getId() == R.id.permission_enable_deny_button) {
- handleConfirmServiceEnabled(false);
- } else if (view.getId() == R.id.permission_disable_stop_button) {
- handleConfirmServiceEnabled(false);
- } else if (view.getId() == R.id.permission_disable_cancel_button) {
- handleConfirmServiceEnabled(true);
- } else {
- throw new IllegalArgumentException();
- }
- mDialog.dismiss();
- }
-
private boolean isGestureNavigateEnabled() {
return getContext().getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode)
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index 6a9e9fc..a0b1f44 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -29,6 +30,7 @@
private final int OFF = 0;
private static final int MY_USER = UserHandle.myUserId();
+ private static final String PROP_AWARE_AVAILABLE = "ro.vendor.aware_available";
private AmbientDisplayConfiguration mConfig;
private OnPreferenceChangedCallback mCallback;
@@ -43,7 +45,9 @@
@Override
public int getAvailabilityStatus() {
- return isAvailable(getConfig()) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return isAvailable(getConfig())
+ && !SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) ?
+ AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index 54064ad..b9c390d 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -31,7 +31,6 @@
import android.content.SharedPreferences;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
-import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.SearchIndexableResource;
@@ -48,6 +47,7 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settings.utils.CandidateInfoExtra;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
import com.android.settings.widget.VideoPreference;
@@ -150,12 +150,12 @@
@Override
public void bindPreferenceExtra(RadioButtonPreference pref,
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
- if (!(info instanceof NavModeCandidateInfo)
+ if (!(info instanceof CandidateInfoExtra)
|| !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
return;
}
- pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
+ pref.setSummary(((CandidateInfoExtra) info).loadSummary());
RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
@@ -175,25 +175,25 @@
@Override
protected List<? extends CandidateInfo> getCandidates() {
final Context c = getContext();
- List<NavModeCandidateInfo> candidates = new ArrayList<>();
+ List<CandidateInfoExtra> candidates = new ArrayList<>();
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_GESTURAL_OVERLAY)) {
- candidates.add(new NavModeCandidateInfo(
+ candidates.add(new CandidateInfoExtra(
c.getText(R.string.edge_to_edge_navigation_title),
c.getText(R.string.edge_to_edge_navigation_summary),
KEY_SYSTEM_NAV_GESTURAL, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_2BUTTON_OVERLAY)) {
- candidates.add(new NavModeCandidateInfo(
+ candidates.add(new CandidateInfoExtra(
c.getText(R.string.swipe_up_to_switch_apps_title),
c.getText(R.string.swipe_up_to_switch_apps_summary),
KEY_SYSTEM_NAV_2BUTTONS, true /* enabled */));
}
if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
NAV_BAR_MODE_3BUTTON_OVERLAY)) {
- candidates.add(new NavModeCandidateInfo(
+ candidates.add(new CandidateInfoExtra(
c.getText(R.string.legacy_navigation_title),
c.getText(R.string.legacy_navigation_summary),
KEY_SYSTEM_NAV_3BUTTONS, true /* enabled */));
@@ -325,39 +325,6 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
}
- static class NavModeCandidateInfo extends CandidateInfo {
- private final CharSequence mLabel;
- private final CharSequence mSummary;
- private final String mKey;
-
- NavModeCandidateInfo(CharSequence label, CharSequence summary, String key,
- boolean enabled) {
- super(enabled);
- mLabel = label;
- mSummary = summary;
- mKey = key;
- }
-
- @Override
- public CharSequence loadLabel() {
- return mLabel;
- }
-
- public CharSequence loadSummary() {
- return mSummary;
- }
-
- @Override
- public Drawable loadIcon() {
- return null;
- }
-
- @Override
- public String getKey() {
- return mKey;
- }
- }
-
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.system_navigation_gesture_settings) {
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
index d11f771..facfcde 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
@@ -17,16 +17,19 @@
package com.android.settings.homepage.contextualcards.legacysuggestion;
import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard;
public class LegacySuggestionContextualCard extends ContextualCard {
private final PendingIntent mPendingIntent;
+ private final Suggestion mSuggestion;
public LegacySuggestionContextualCard(Builder builder) {
super(builder);
mPendingIntent = builder.mPendingIntent;
+ mSuggestion = builder.mSuggestion;
}
@Override
@@ -38,15 +41,25 @@
return mPendingIntent;
}
+ public Suggestion getSuggestion() {
+ return mSuggestion;
+ }
+
public static class Builder extends ContextualCard.Builder {
private PendingIntent mPendingIntent;
+ private Suggestion mSuggestion;
public Builder setPendingIntent(PendingIntent pendingIntent) {
mPendingIntent = pendingIntent;
return this;
}
+ public Builder setSuggestion(Suggestion suggestion) {
+ mSuggestion = suggestion;
+ return this;
+ }
+
@Override
public Builder setCardType(int cardType) {
throw new IllegalArgumentException(
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
index 3b0b46d..834aa8e 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
@@ -47,6 +47,9 @@
private static final String TAG = "LegacySuggestCardCtrl";
@VisibleForTesting
+ final List<ContextualCard> mSuggestions;
+
+ @VisibleForTesting
SuggestionController mSuggestionController;
private ContextualCardUpdateListener mCardUpdateListener;
@@ -55,6 +58,7 @@
public LegacySuggestionContextualCardController(Context context) {
mContext = context;
+ mSuggestions = new ArrayList<>();
if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
return;
@@ -88,7 +92,10 @@
@Override
public void onDismissed(ContextualCard card) {
-
+ mSuggestionController
+ .dismissSuggestions(((LegacySuggestionContextualCard)card).getSuggestion());
+ mSuggestions.remove(card);
+ updateAdapter();
}
@Override
@@ -144,6 +151,7 @@
}
cardBuilder
.setPendingIntent(suggestion.getPendingIntent())
+ .setSuggestion(suggestion)
.setName(suggestion.getId())
.setTitleText(suggestion.getTitle().toString())
.setSummaryText(suggestion.getSummary().toString())
@@ -153,12 +161,16 @@
}
}
- // Update adapter
- final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
- suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
- ThreadUtils.postOnMainThread(
- () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
-
+ mSuggestions.clear();
+ mSuggestions.addAll(cards);
+ updateAdapter();
});
}
+
+ private void updateAdapter() {
+ final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
+ suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, mSuggestions);
+ ThreadUtils.postOnMainThread(
+ () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
+ }
}
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
index 3bccabc..395e814 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
@@ -26,6 +26,7 @@
import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardController;
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
@@ -51,12 +52,13 @@
@Override
public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
+ final ContextualCardController controller = mControllerRendererPool
+ .getController(mContext, card.getCardType());
vh.icon.setImageDrawable(card.getIconDrawable());
vh.title.setText(card.getTitleText());
vh.summary.setText(card.getSummaryText());
- vh.itemView.setOnClickListener(v ->
- mControllerRendererPool.getController(mContext,
- card.getCardType()).onPrimaryClick(card));
+ vh.itemView.setOnClickListener(v -> controller.onPrimaryClick(card));
+ vh.closeButton.setOnClickListener(v -> controller.onDismissed(card));
}
private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
@@ -64,12 +66,14 @@
public final ImageView icon;
public final TextView title;
public final TextView summary;
+ public final View closeButton;
public LegacySuggestionViewHolder(View itemView) {
super(itemView);
icon = itemView.findViewById(android.R.id.icon);
title = itemView.findViewById(android.R.id.title);
summary = itemView.findViewById(android.R.id.summary);
+ closeButton = itemView.findViewById(R.id.close_button);
}
}
}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java
new file mode 100644
index 0000000..96e43b7
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import android.content.Context;
+
+/**
+ * Preference controller for "Advance Calling"
+ */
+public class Enhanced4gAdvancedCallingPreferenceController extends
+ Enhanced4gBasePreferenceController {
+
+ public Enhanced4gAdvancedCallingPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ protected int getMode() {
+ return MODE_ADVANCED_CALL;
+ }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
new file mode 100644
index 0000000..25eefdf
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.ims.ImsManager;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Preference controller for "Enhanced 4G LTE"
+ */
+public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenceController
+ implements LifecycleObserver, OnStart, OnStop {
+
+ private Preference mPreference;
+ private TelephonyManager mTelephonyManager;
+ private CarrierConfigManager mCarrierConfigManager;
+ private PersistableBundle mCarrierConfig;
+ @VisibleForTesting
+ ImsManager mImsManager;
+ private PhoneCallStateListener mPhoneStateListener;
+ private final List<On4gLteUpdateListener> m4gLteListeners;
+
+ protected static final int MODE_NONE = -1;
+ protected static final int MODE_VOLTE = 0;
+ protected static final int MODE_ADVANCED_CALL = 1;
+ protected static final int MODE_4G_CALLING = 2;
+ private int m4gCurrentMode = MODE_NONE;
+
+ public Enhanced4gBasePreferenceController(Context context, String key) {
+ super(context, key);
+ mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+ m4gLteListeners = new ArrayList<>();
+ mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
+ }
+
+ public Enhanced4gBasePreferenceController init(int subId) {
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && mSubId == subId) {
+ return this;
+ }
+ mSubId = subId;
+ mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+ mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+ if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
+ }
+
+ final boolean show4GForLTE = mCarrierConfig.getBoolean(
+ CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
+ m4gCurrentMode = mCarrierConfig.getInt(
+ CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT);
+ if (m4gCurrentMode != MODE_ADVANCED_CALL) {
+ m4gCurrentMode = show4GForLTE ? MODE_4G_CALLING : MODE_VOLTE;
+ }
+ return this;
+ }
+
+ @Override
+ public int getAvailabilityStatus(int subId) {
+ init(subId);
+ if (!isModeMatched()) {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+ final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+ final boolean isVisible = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ && mImsManager != null && carrierConfig != null
+ && mImsManager.isVolteEnabledByPlatform()
+ && mImsManager.isVolteProvisionedOnDevice()
+ && MobileNetworkUtils.isImsServiceStateReady(mImsManager)
+ && !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL);
+ return isVisible
+ ? (isPrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE)
+ : CONDITIONALLY_UNAVAILABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ }
+
+ @Override
+ public void onStart() {
+ mPhoneStateListener.register(mSubId);
+ }
+
+ @Override
+ public void onStop() {
+ mPhoneStateListener.unregister();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ final SwitchPreference switchPreference = (SwitchPreference) preference;
+
+ switchPreference.setEnabled(isPrefEnabled());
+ switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
+ && mImsManager.isNonTtyOrTtyOnVolteEnabled());
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ mImsManager.setEnhanced4gLteModeSetting(isChecked);
+ for (final On4gLteUpdateListener lsn : m4gLteListeners) {
+ lsn.on4gLteUpdated();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
+ }
+
+ public Enhanced4gBasePreferenceController addListener(On4gLteUpdateListener lsn) {
+ m4gLteListeners.add(lsn);
+ return this;
+ }
+
+ protected int getMode() {
+ return MODE_NONE;
+ }
+
+ private boolean isModeMatched() {
+ return m4gCurrentMode == getMode();
+ }
+
+ private boolean isPrefEnabled() {
+ return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE
+ && mImsManager != null
+ && mImsManager.isNonTtyOrTtyOnVolteEnabled()
+ && mCarrierConfig.getBoolean(
+ CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
+ }
+
+ private class PhoneCallStateListener extends PhoneStateListener {
+
+ public PhoneCallStateListener(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ updateState(mPreference);
+ }
+
+ public void register(int subId) {
+ mSubId = subId;
+ mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
+ }
+
+ public void unregister() {
+ mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
+ }
+ }
+
+ /**
+ * Update other preferences when 4gLte state is changed
+ */
+ public interface On4gLteUpdateListener {
+ void on4gLteUpdated();
+ }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java
new file mode 100644
index 0000000..a0d2e34
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import android.content.Context;
+
+/**
+ * Preference controller for "4G Calling"
+ */
+public class Enhanced4gCallingPreferenceController extends Enhanced4gBasePreferenceController {
+
+ public Enhanced4gCallingPreferenceController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ protected int getMode() {
+ return MODE_4G_CALLING;
+ }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
index 9069c35..22cbd97 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
@@ -17,177 +17,18 @@
package com.android.settings.network.telephony;
import android.content.Context;
-import android.os.Looper;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
-import com.android.ims.ImsManager;
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
-
-import java.util.ArrayList;
-import java.util.List;
/**
* Preference controller for "Enhanced 4G LTE"
*/
-public class Enhanced4gLtePreferenceController extends TelephonyTogglePreferenceController
- implements LifecycleObserver, OnStart, OnStop {
-
- private Preference mPreference;
- private TelephonyManager mTelephonyManager;
- private CarrierConfigManager mCarrierConfigManager;
- private PersistableBundle mCarrierConfig;
- @VisibleForTesting
- ImsManager mImsManager;
- private PhoneCallStateListener mPhoneStateListener;
- private final List<On4gLteUpdateListener> m4gLteListeners;
- private final CharSequence[] mVariantTitles;
- private final CharSequence[] mVariantSumaries;
-
- private final int VARIANT_TITLE_VOLTE = 0;
- private final int VARIANT_TITLE_ADVANCED_CALL = 1;
- private final int VARIANT_TITLE_4G_CALLING = 2;
+public class Enhanced4gLtePreferenceController extends Enhanced4gBasePreferenceController {
public Enhanced4gLtePreferenceController(Context context, String key) {
super(context, key);
- mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
- m4gLteListeners = new ArrayList<>();
- mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
- mVariantTitles = context.getResources()
- .getTextArray(R.array.enhanced_4g_lte_mode_title_variant);
- mVariantSumaries = context.getResources()
- .getTextArray(R.array.enhanced_4g_lte_mode_sumary_variant);
}
@Override
- public int getAvailabilityStatus(int subId) {
- init(subId);
- final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
- final boolean isVisible = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
- && mImsManager != null && carrierConfig != null
- && mImsManager.isVolteEnabledByPlatform()
- && mImsManager.isVolteProvisionedOnDevice()
- && MobileNetworkUtils.isImsServiceStateReady(mImsManager)
- && !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL);
- return isVisible
- ? (is4gLtePrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE)
- : CONDITIONALLY_UNAVAILABLE;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mPreference = screen.findPreference(getPreferenceKey());
- }
-
- @Override
- public void onStart() {
- mPhoneStateListener.register(mSubId);
- }
-
- @Override
- public void onStop() {
- mPhoneStateListener.unregister();
- }
-
- @Override
- public void updateState(Preference preference) {
- super.updateState(preference);
- final SwitchPreference switchPreference = (SwitchPreference) preference;
- final boolean show4GForLTE = mCarrierConfig.getBoolean(
- CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
- int variant4glteTitleIndex = mCarrierConfig.getInt(
- CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT);
-
- if (variant4glteTitleIndex != VARIANT_TITLE_ADVANCED_CALL) {
- variant4glteTitleIndex = show4GForLTE ? VARIANT_TITLE_4G_CALLING : VARIANT_TITLE_VOLTE;
- }
-
- switchPreference.setTitle(mVariantTitles[variant4glteTitleIndex]);
- switchPreference.setSummary(mVariantSumaries[variant4glteTitleIndex]);
- switchPreference.setEnabled(is4gLtePrefEnabled());
- switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
- && mImsManager.isNonTtyOrTtyOnVolteEnabled());
- }
-
- @Override
- public boolean setChecked(boolean isChecked) {
- mImsManager.setEnhanced4gLteModeSetting(isChecked);
- for (final On4gLteUpdateListener lsn : m4gLteListeners) {
- lsn.on4gLteUpdated();
- }
- return true;
- }
-
- @Override
- public boolean isChecked() {
- return mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
- }
-
- public Enhanced4gLtePreferenceController init(int subId) {
- if (mSubId == subId) {
- return this;
- }
- mSubId = subId;
- mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
- mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
- if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
- }
-
- return this;
- }
-
- public Enhanced4gLtePreferenceController addListener(On4gLteUpdateListener lsn) {
- m4gLteListeners.add(lsn);
- return this;
- }
-
- private boolean is4gLtePrefEnabled() {
- return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
- && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE
- && mImsManager != null
- && mImsManager.isNonTtyOrTtyOnVolteEnabled()
- && mCarrierConfig.getBoolean(
- CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
- }
-
- private class PhoneCallStateListener extends PhoneStateListener {
-
- public PhoneCallStateListener(Looper looper) {
- super(looper);
- }
-
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- updateState(mPreference);
- }
-
- public void register(int subId) {
- mSubId = subId;
- mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
- }
-
- public void unregister() {
- mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
- }
- }
-
- /**
- * Update other preferences when 4gLte state is changed
- */
- public interface On4gLteUpdateListener {
- void on4gLteUpdated();
+ protected int getMode() {
+ return MODE_VOLTE;
}
}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index c06b78b..bdcc736 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -65,7 +65,7 @@
public int getAvailabilityStatus(int subId) {
return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
? AVAILABLE
- : DISABLED_DEPENDENT_SETTING;
+ : AVAILABLE_UNSEARCHABLE;
}
@Override
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 0a63e73..2dc9f91 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -32,6 +32,9 @@
import android.view.MenuInflater;
import android.view.MenuItem;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
@@ -53,9 +56,6 @@
import java.util.Arrays;
import java.util.List;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MobileNetworkSettings extends RestrictedDashboardFragment {
@@ -175,6 +175,10 @@
use(VideoCallingPreferenceController.class).init(mSubId);
use(Enhanced4gLtePreferenceController.class).init(mSubId)
.addListener(videoCallingPreferenceController);
+ use(Enhanced4gCallingPreferenceController.class).init(mSubId)
+ .addListener(videoCallingPreferenceController);
+ use(Enhanced4gAdvancedCallingPreferenceController.class).init(mSubId)
+ .addListener(videoCallingPreferenceController);
}
@Override
diff --git a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
index 1c78863..a16dc24 100644
--- a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
@@ -43,7 +43,7 @@
*/
public class VideoCallingPreferenceController extends TelephonyTogglePreferenceController implements
LifecycleObserver, OnStart, OnStop,
- Enhanced4gLtePreferenceController.On4gLteUpdateListener {
+ Enhanced4gBasePreferenceController.On4gLteUpdateListener {
private Preference mPreference;
private TelephonyManager mTelephonyManager;
diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java
index 80b2d45..e5db3ee 100644
--- a/src/com/android/settings/notification/NotificationStation.java
+++ b/src/com/android/settings/notification/NotificationStation.java
@@ -16,7 +16,8 @@
package com.android.settings.notification;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.provider.Settings.EXTRA_APP_PACKAGE;
+import static android.provider.Settings.EXTRA_CHANNEL_ID;
import android.app.Activity;
import android.app.ActivityManager;
@@ -27,18 +28,19 @@
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.os.Handler;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -49,6 +51,7 @@
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.DateTimeView;
import android.widget.ImageView;
import android.widget.TextView;
@@ -62,8 +65,8 @@
import com.android.settings.Utils;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
+import java.util.LinkedList;
import java.util.List;
public class NotificationStation extends SettingsPreferenceFragment {
@@ -72,33 +75,44 @@
private static final boolean DEBUG = false;
private static final boolean DUMP_EXTRAS = true;
private static final boolean DUMP_PARCEL = true;
- private Handler mHandler;
private static class HistoricalNotificationInfo {
public String key;
- public String channel;
+ public NotificationChannel channel;
public String pkg;
public Drawable pkgicon;
public CharSequence pkgname;
public Drawable icon;
public CharSequence title;
+ public CharSequence text;
public int priority;
public int user;
public long timestamp;
public boolean active;
- public CharSequence extra;
+ public CharSequence notificationExtra;
+ public CharSequence rankingExtra;
+ public boolean alerted;
+ public boolean visuallyInterruptive;
+
+ public void updateFrom(HistoricalNotificationInfo updatedInfo) {
+ this.channel = updatedInfo.channel;
+ this.icon = updatedInfo.icon;
+ this.title = updatedInfo.title;
+ this.text = updatedInfo.text;
+ this.priority = updatedInfo.priority;
+ this.timestamp = updatedInfo.timestamp;
+ this.active = updatedInfo.active;
+ this.alerted = updatedInfo.alerted;
+ this.visuallyInterruptive = updatedInfo.visuallyInterruptive;
+ this.notificationExtra = updatedInfo.notificationExtra;
+ this.rankingExtra = updatedInfo.rankingExtra;
+ }
}
private PackageManager mPm;
private INotificationManager mNoMan;
private RankingMap mRanking;
-
- private Runnable mRefreshListRunnable = new Runnable() {
- @Override
- public void run() {
- refreshList();
- }
- };
+ private LinkedList<HistoricalNotificationInfo> mNotificationInfos;
private final NotificationListenerService mListener = new NotificationListenerService() {
@Override
@@ -106,15 +120,21 @@
logd("onNotificationPosted: %s, with update for %d", sbn.getNotification(),
ranking == null ? 0 : ranking.getOrderedKeys().length);
mRanking = ranking;
- scheduleRefreshList();
+ if (sbn.getNotification().isGroupSummary()) {
+ return;
+ }
+ addOrUpdateNotification(sbn);
}
@Override
- public void onNotificationRemoved(StatusBarNotification notification, RankingMap ranking) {
+ public void onNotificationRemoved(StatusBarNotification sbn, RankingMap ranking) {
logd("onNotificationRankingUpdate with update for %d",
ranking == null ? 0 : ranking.getOrderedKeys().length);
mRanking = ranking;
- scheduleRefreshList();
+ if (sbn.getNotification().isGroupSummary()) {
+ return;
+ }
+ markNotificationAsDismissed(sbn);
}
@Override
@@ -122,7 +142,7 @@
logd("onNotificationRankingUpdate with update for %d",
ranking == null ? 0 : ranking.getOrderedKeys().length);
mRanking = ranking;
- scheduleRefreshList();
+ updateNotificationsFromRanking();
}
@Override
@@ -130,44 +150,29 @@
mRanking = getCurrentRanking();
logd("onListenerConnected with update for %d",
mRanking == null ? 0 : mRanking.getOrderedKeys().length);
- scheduleRefreshList();
+ populateNotifications();
}
};
- private void scheduleRefreshList() {
- if (mHandler != null) {
- mHandler.removeCallbacks(mRefreshListRunnable);
- mHandler.postDelayed(mRefreshListRunnable, 100);
- }
- }
-
private Context mContext;
private final Comparator<HistoricalNotificationInfo> mNotificationSorter
- = new Comparator<HistoricalNotificationInfo>() {
- @Override
- public int compare(HistoricalNotificationInfo lhs,
- HistoricalNotificationInfo rhs) {
- return Long.compare(rhs.timestamp, lhs.timestamp);
- }
- };
+ = (lhs, rhs) -> Long.compare(rhs.timestamp, lhs.timestamp);
@Override
public void onAttach(Activity activity) {
logd("onAttach(%s)", activity.getClass().getSimpleName());
super.onAttach(activity);
- mHandler = new Handler(activity.getMainLooper());
mContext = activity;
mPm = mContext.getPackageManager();
mNoMan = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ mNotificationInfos = new LinkedList<>();
}
@Override
public void onDetach() {
logd("onDetach()");
- mHandler.removeCallbacks(mRefreshListRunnable);
- mHandler = null;
super.onDetach();
}
@@ -205,24 +210,84 @@
} catch (RemoteException e) {
Log.e(TAG, "Cannot register listener", e);
}
- refreshList();
}
- private void refreshList() {
- List<HistoricalNotificationInfo> infos = loadNotifications();
- if (infos != null) {
- final int N = infos.size();
- logd("adding %d infos", N);
- Collections.sort(infos, mNotificationSorter);
- if (getPreferenceScreen() == null) {
- setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
+ /**
+ * Adds all current and historical notifications when the NLS connects.
+ */
+ private void populateNotifications() {
+ loadNotifications();
+ final int N = mNotificationInfos.size();
+ logd("adding %d infos", N);
+ if (getPreferenceScreen() == null) {
+ setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
+ }
+ getPreferenceScreen().removeAll();
+ for (int i = 0; i < N; i++) {
+ getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
+ getPrefContext(), mNotificationInfos.get(i), i));
+ }
+ }
+
+ /**
+ * Finds and dims the given notification in the preferences list.
+ */
+ private void markNotificationAsDismissed(StatusBarNotification sbn) {
+ final int N = mNotificationInfos.size();
+ for (int i = 0; i < N; i++) {
+ final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+ if (TextUtils.equals(info.key, sbn.getKey())) {
+ info.active = false;
+ ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+ sbn.getKey())).updatePreference(info);
+ break;
}
- getPreferenceScreen().removeAll();
- for (int i = 0; i < N; i++) {
- getPreferenceScreen().addPreference(
- new HistoricalNotificationPreference(getPrefContext(), infos.get(i)));
+ }
+ }
+
+ /**
+ * Either updates a notification with its latest information or (if it's something the user
+ * would consider a new notification) adds a new entry at the start of the list.
+ */
+ private void addOrUpdateNotification(StatusBarNotification sbn) {
+ HistoricalNotificationInfo newInfo = createFromSbn(sbn, true);
+ boolean needsAdd = true;
+ final int N = mNotificationInfos.size();
+ for (int i = 0; i < N; i++) {
+ final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+ if (TextUtils.equals(info.key, sbn.getKey()) && info.active
+ && !newInfo.alerted && !newInfo.visuallyInterruptive) {
+ info.updateFrom(newInfo);
+
+ ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+ sbn.getKey())).updatePreference(info);
+ needsAdd = false;
+ break;
}
}
+ if (needsAdd) {
+ mNotificationInfos.addFirst(newInfo);
+ getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
+ getPrefContext(),
+ mNotificationInfos.peekFirst(), -1 * mNotificationInfos.size()));
+ }
+ }
+
+ /**
+ * Updates all notifications in the list based on new information in the ranking.
+ */
+ private void updateNotificationsFromRanking() {
+ Ranking rank = new Ranking();
+ for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
+ final HistoricalNotificationPreference p =
+ (HistoricalNotificationPreference) getPreferenceScreen().getPreference(i);
+ final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+ mRanking.getRanking(p.getKey(), rank);
+
+ updateFromRanking(info);
+ ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+ info.key)).updatePreference(info);
+ }
}
private static void logd(String msg, Object... args) {
@@ -242,14 +307,46 @@
CharSequence title = null;
if (n.extras != null) {
title = n.extras.getCharSequence(Notification.EXTRA_TITLE);
- if (TextUtils.isEmpty(title)) {
- title = n.extras.getCharSequence(Notification.EXTRA_TEXT);
+ }
+ return title == null? null : String.valueOf(title);
+ }
+
+ /**
+ * Returns the appropriate substring for this notification based on the style of notification.
+ */
+ private static String getTextString(Context appContext, Notification n) {
+ CharSequence text = null;
+ if (n.extras != null) {
+ text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
+
+ Notification.Builder nb = Notification.Builder.recoverBuilder(appContext, n);
+
+ if (nb.getStyle() instanceof Notification.BigTextStyle) {
+ text = ((Notification.BigTextStyle) nb.getStyle()).getBigText();
+ } else if (nb.getStyle() instanceof Notification.MessagingStyle) {
+ Notification.MessagingStyle ms = (Notification.MessagingStyle) nb.getStyle();
+ final List<Notification.MessagingStyle.Message> messages = ms.getMessages();
+ if (messages != null && messages.size() > 0) {
+ text = messages.get(messages.size() - 1).getText();
+ }
+ }
+
+ if (TextUtils.isEmpty(text)) {
+ text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
}
}
- if (TextUtils.isEmpty(title) && !TextUtils.isEmpty(n.tickerText)) {
- title = n.tickerText;
+ return text == null ? null : String.valueOf(text);
+ }
+
+ private static Drawable loadIcon(Context context, StatusBarNotification sbn) {
+ Drawable draw = sbn.getNotification().getSmallIcon().loadDrawableAsUser(
+ sbn.getPackageContext(context), sbn.getUserId());
+ if (draw == null) {
+ return null;
}
- return String.valueOf(title);
+ draw.mutate();
+ draw.setColorFilter(sbn.getNotification().color, PorterDuff.Mode.SRC_ATOP);
+ return draw;
}
private static String formatPendingIntent(PendingIntent pi) {
@@ -265,7 +362,11 @@
return sb.toString();
}
- private List<HistoricalNotificationInfo> loadNotifications() {
+ /**
+ * Reads all current and past notifications (up to the system limit, since the device was
+ * booted), stores the data we need to present them, and sorts them chronologically for display.
+ */
+ private void loadNotifications() {
final int currentUserId = ActivityManager.getCurrentUser();
try {
StatusBarNotification[] active = mNoMan.getActiveNotifications(
@@ -274,51 +375,125 @@
mContext.getPackageName(), 50);
List<HistoricalNotificationInfo> list
- = new ArrayList<HistoricalNotificationInfo>(active.length + dismissed.length);
+ = new ArrayList<>(active.length + dismissed.length);
- for (StatusBarNotification[] resultset
+ for (StatusBarNotification[] resultSet
: new StatusBarNotification[][] { active, dismissed }) {
- for (StatusBarNotification sbn : resultset) {
+ for (StatusBarNotification sbn : resultSet) {
if (sbn.getUserId() != UserHandle.USER_ALL & sbn.getUserId() != currentUserId) {
continue;
}
-
- final Notification n = sbn.getNotification();
- final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
- info.pkg = sbn.getPackageName();
- info.user = sbn.getUserId();
- info.icon = loadIconDrawable(info.pkg, info.user, n.icon);
- info.pkgicon = loadPackageIconDrawable(info.pkg, info.user);
- info.pkgname = loadPackageName(info.pkg);
- info.title = getTitleString(n);
- if (TextUtils.isEmpty(info.title)) {
- info.title = getString(R.string.notification_log_no_title);
+ if (sbn.getNotification().isGroupSummary()) {
+ continue;
}
- info.timestamp = sbn.getPostTime();
- info.priority = n.priority;
- info.channel = n.getChannelId();
- info.key = sbn.getKey();
-
- info.active = (resultset == active);
-
- info.extra = generateExtraText(sbn, info);
-
+ final HistoricalNotificationInfo info = createFromSbn(sbn, resultSet == active);
logd(" [%d] %s: %s", info.timestamp, info.pkg, info.title);
list.add(info);
}
}
- return list;
+ // notifications are given to us in the same order as the shade; sorted by inferred
+ // priority. Resort chronologically for our display.
+ list.sort(mNotificationSorter);
+ mNotificationInfos = new LinkedList<>(list);
+
} catch (RemoteException e) {
Log.e(TAG, "Cannot load Notifications: ", e);
}
- return null;
}
+ private HistoricalNotificationInfo createFromSbn(StatusBarNotification sbn, boolean active) {
+ final Notification n = sbn.getNotification();
+ final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
+ info.pkg = sbn.getPackageName();
+ info.user = sbn.getUserId();
+ info.icon = loadIcon(mContext, sbn);
+ if (info.icon == null) {
+ info.icon = loadPackageIconDrawable(info.pkg, info.user);
+ }
+ info.pkgname = loadPackageName(info.pkg);
+ info.title = getTitleString(n);
+ info.text = getTextString(sbn.getPackageContext(mContext), n);
+ info.timestamp = sbn.getPostTime();
+ info.priority = n.priority;
+ info.key = sbn.getKey();
+
+ info.active = active;
+ info.notificationExtra = generateExtraText(sbn, info);
+
+ updateFromRanking(info);
+
+ return info;
+ }
+
+ private void updateFromRanking(HistoricalNotificationInfo info) {
+ Ranking rank = new Ranking();
+ if (mRanking == null) {
+ return;
+ }
+ mRanking.getRanking(info.key, rank);
+ info.alerted = rank.getLastAudiblyAlertedMillis() > 0;
+ info.visuallyInterruptive = rank.visuallyInterruptive();
+ info.channel = rank.getChannel();
+ info.rankingExtra = generateRankingExtraText(info);
+ }
+
+ /**
+ * Generates a string of debug information for this notification based on the RankingMap
+ */
+ private CharSequence generateRankingExtraText(HistoricalNotificationInfo info) {
+ final SpannableStringBuilder sb = new SpannableStringBuilder();
+ final String delim = getString(R.string.notification_log_details_delimiter);
+
+ Ranking rank = new Ranking();
+ if (mRanking != null && mRanking.getRanking(info.key, rank)) {
+ if (info.active && info.alerted) {
+ sb.append("\n")
+ .append(bold(getString(R.string.notification_log_details_alerted)));
+ }
+ sb.append("\n")
+ .append(bold(getString(R.string.notification_log_channel)))
+ .append(delim)
+ .append(info.channel.toString());
+ if (info.active) {
+ sb.append("\n")
+ .append(bold(getString(
+ R.string.notification_log_details_importance)))
+ .append(delim)
+ .append(Ranking.importanceToString(rank.getImportance()));
+ if (rank.getImportanceExplanation() != null) {
+ sb.append("\n")
+ .append(bold(getString(
+ R.string.notification_log_details_explanation)))
+ .append(delim)
+ .append(rank.getImportanceExplanation());
+ }
+ sb.append("\n")
+ .append(bold(getString(
+ R.string.notification_log_details_badge)))
+ .append(delim)
+ .append(Boolean.toString(rank.canShowBadge()));
+ }
+ } else {
+ if (mRanking == null) {
+ sb.append("\n")
+ .append(bold(getString(
+ R.string.notification_log_details_ranking_null)));
+ } else {
+ sb.append("\n")
+ .append(bold(getString(
+ R.string.notification_log_details_ranking_none)));
+ }
+ }
+
+ return sb;
+ }
+
+ /**
+ * Generates a string of debug information for this notification
+ */
private CharSequence generateExtraText(StatusBarNotification sbn,
HistoricalNotificationInfo info) {
- final Ranking rank = new Ranking();
-
final Notification n = sbn.getNotification();
final SpannableStringBuilder sb = new SpannableStringBuilder();
final String delim = getString(R.string.notification_log_details_delimiter);
@@ -334,10 +509,6 @@
.append(delim)
.append(String.valueOf(n.getSmallIcon()));
sb.append("\n")
- .append(bold("channelId"))
- .append(delim)
- .append(String.valueOf(n.getChannelId()));
- sb.append("\n")
.append(bold("postTime"))
.append(delim)
.append(String.valueOf(sbn.getPostTime()));
@@ -357,58 +528,6 @@
getString(R.string.notification_log_details_group_summary)));
}
}
- if (info.active) {
- // mRanking only applies to active notifications
- if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
- if (rank.getLastAudiblyAlertedMillis() > 0) {
- sb.append("\n")
- .append(bold(getString(R.string.notification_log_details_alerted)));
- }
- }
- }
- try {
- NotificationChannel channel = mNoMan.getNotificationChannelForPackage(
- sbn.getPackageName(), sbn.getUid(), n.getChannelId(), false);
- sb.append("\n")
- .append(bold(getString(R.string.notification_log_details_sound)))
- .append(delim);
- if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
-
- if (0 != (n.defaults & Notification.DEFAULT_SOUND)) {
- sb.append(getString(R.string.notification_log_details_default));
- } else if (n.sound != null) {
- sb.append(n.sound.toString());
- } else {
- sb.append(getString(R.string.notification_log_details_none));
- }
- } else {
- sb.append(String.valueOf(channel.getSound()));
- }
- sb.append("\n")
- .append(bold(getString(R.string.notification_log_details_vibrate)))
- .append(delim);
- if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
- if (0 != (n.defaults & Notification.DEFAULT_VIBRATE)) {
- sb.append(getString(R.string.notification_log_details_default));
- } else if (n.vibrate != null) {
- sb.append(getString(R.string.notification_log_details_vibrate_pattern));
- } else {
- sb.append(getString(R.string.notification_log_details_none));
- }
- } else {
- if (channel.getVibrationPattern() != null) {
- sb.append(getString(R.string.notification_log_details_vibrate_pattern));
- } else {
- sb.append(getString(R.string.notification_log_details_none));
- }
- }
- } catch (RemoteException e) {
- Log.d(TAG, "cannot read channel info", e);
- }
- sb.append("\n")
- .append(bold(getString(R.string.notification_log_details_visibility)))
- .append(delim)
- .append(Notification.visibilityToString(n.visibility));
if (n.publicVersion != null) {
sb.append("\n")
.append(bold(getString(
@@ -416,42 +535,7 @@
.append(delim)
.append(getTitleString(n.publicVersion));
}
- sb.append("\n")
- .append(bold(getString(R.string.notification_log_details_priority)))
- .append(delim)
- .append(Notification.priorityToString(n.priority));
- if (info.active) {
- // mRanking only applies to active notifications
- if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
- sb.append("\n")
- .append(bold(getString(
- R.string.notification_log_details_importance)))
- .append(delim)
- .append(Ranking.importanceToString(rank.getImportance()));
- if (rank.getImportanceExplanation() != null) {
- sb.append("\n")
- .append(bold(getString(
- R.string.notification_log_details_explanation)))
- .append(delim)
- .append(rank.getImportanceExplanation());
- }
- sb.append("\n")
- .append(bold(getString(
- R.string.notification_log_details_badge)))
- .append(delim)
- .append(Boolean.toString(rank.canShowBadge()));
- } else {
- if (mRanking == null) {
- sb.append("\n")
- .append(bold(getString(
- R.string.notification_log_details_ranking_null)));
- } else {
- sb.append("\n")
- .append(bold(getString(
- R.string.notification_log_details_ranking_none)));
- }
- }
- }
+
if (n.contentIntent != null) {
sb.append("\n")
.append(bold(getString(
@@ -535,25 +619,6 @@
return sb;
}
- private Resources getResourcesForUserPackage(String pkg, int userId) {
- Resources r = null;
-
- if (pkg != null) {
- try {
- if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_SYSTEM;
- }
- r = mPm.getResourcesForApplicationAsUser(pkg, userId);
- } catch (PackageManager.NameNotFoundException ex) {
- Log.e(TAG, "Icon package not found: " + pkg, ex);
- return null;
- }
- } else {
- r = mContext.getResources();
- }
- return r;
- }
-
private Drawable loadPackageIconDrawable(String pkg, int userId) {
Drawable icon = null;
try {
@@ -576,31 +641,17 @@
return pkg;
}
- private Drawable loadIconDrawable(String pkg, int userId, int resId) {
- Resources r = getResourcesForUserPackage(pkg, userId);
-
- if (resId == 0) {
- return null;
- }
-
- try {
- return r.getDrawable(resId, null);
- } catch (RuntimeException e) {
- Log.w(TAG, "Icon not found in "
- + (pkg != null ? resId : "<system>")
- + ": " + Integer.toHexString(resId), e);
- }
-
- return null;
- }
-
private static class HistoricalNotificationPreference extends Preference {
private final HistoricalNotificationInfo mInfo;
private static long sLastExpandedTimestamp; // quick hack to keep things from collapsing
+ public ViewGroup mItemView; // hack to update prefs fast;
- public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info) {
+ public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info,
+ int order) {
super(context);
setLayoutResource(R.layout.notification_log_row);
+ setOrder(order);
+ setKey(info.key);
mInfo = info;
}
@@ -608,41 +659,67 @@
public void onBindViewHolder(PreferenceViewHolder row) {
super.onBindViewHolder(row);
- if (mInfo.icon != null) {
- ((ImageView) row.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
+ mItemView = (ViewGroup) row.itemView;
+
+ updatePreference(mInfo);
+
+ row.findViewById(R.id.timestamp).setOnLongClickListener(v -> {
+ final View extras = row.findViewById(R.id.extra);
+ extras.setVisibility(extras.getVisibility() == View.VISIBLE
+ ? View.GONE : View.VISIBLE);
+ sLastExpandedTimestamp = mInfo.timestamp;
+ return false;
+ });
+ }
+
+ public void updatePreference(HistoricalNotificationInfo info) {
+ if (mItemView == null) {
+ return;
}
- if (mInfo.pkgicon != null) {
- ((ImageView) row.findViewById(R.id.pkgicon)).setImageDrawable(mInfo.pkgicon);
+ if (info.icon != null) {
+ ((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
+ }
+ ((TextView) mItemView.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
+ ((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(info.timestamp);
+ if (!TextUtils.isEmpty(info.title)) {
+ ((TextView) mItemView.findViewById(R.id.title)).setText(info.title);
+ mItemView.findViewById(R.id.title).setVisibility(View.VISIBLE);
+ } else {
+ mItemView.findViewById(R.id.title).setVisibility(View.GONE);
+ }
+ if (!TextUtils.isEmpty(info.text)) {
+ ((TextView) mItemView.findViewById(R.id.text)).setText(info.text);
+ mItemView.findViewById(R.id.text).setVisibility(View.VISIBLE);
+ } else {
+ mItemView.findViewById(R.id.text).setVisibility(View.GONE);
+ }
+ if (info.icon != null) {
+ ((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(info.icon);
}
- ((DateTimeView) row.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
- ((TextView) row.findViewById(R.id.title)).setText(mInfo.title);
- ((TextView) row.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
+ ((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
- final TextView extra = (TextView) row.findViewById(R.id.extra);
- extra.setText(mInfo.extra);
- extra.setVisibility(mInfo.timestamp == sLastExpandedTimestamp
- ? View.VISIBLE : View.GONE);
+ ((TextView) mItemView.findViewById(R.id.notification_extra))
+ .setText(mInfo.notificationExtra);
+ ((TextView) mItemView.findViewById(R.id.ranking_extra))
+ .setText(mInfo.rankingExtra);
- row.itemView.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- extra.setVisibility(extra.getVisibility() == View.VISIBLE
- ? View.GONE : View.VISIBLE);
- sLastExpandedTimestamp = mInfo.timestamp;
- }
- });
+ mItemView.findViewById(R.id.extra).setVisibility(
+ mInfo.timestamp == sLastExpandedTimestamp ? View.VISIBLE : View.GONE);
- row.itemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
+ mItemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
+
+ mItemView.findViewById(R.id.alerted_icon).setVisibility(
+ mInfo.alerted ? View.VISIBLE : View.GONE);
}
@Override
public void performClick() {
-// Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
-// Uri.fromParts("package", mInfo.pkg, null));
-// intent.setComponent(intent.resolveActivity(getContext().getPackageManager()));
-// getContext().startActivity(intent);
+ Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
+ .putExtra(EXTRA_APP_PACKAGE, mInfo.pkg)
+ .putExtra(EXTRA_CHANNEL_ID, mInfo.channel.getId());
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ getContext().startActivity(intent);
}
}
}
diff --git a/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java b/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
index 8aff223..a36d3ce 100644
--- a/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
+++ b/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
@@ -29,20 +29,31 @@
import java.util.List;
-public class AccessibilityUsagePreferenceController extends BasePreferenceController {
+public class AccessibilityUsagePreferenceController extends BasePreferenceController {
- private final @NonNull List<AccessibilityServiceInfo> mEnabledServiceInfos;
+ private final AccessibilityManager mAccessibilityManager;
+ @NonNull
+ private List<AccessibilityServiceInfo> mEnabledServiceInfos;
public AccessibilityUsagePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
-
- final AccessibilityManager accessibilityManager = context.getSystemService(
- AccessibilityManager.class);
- mEnabledServiceInfos = accessibilityManager.getEnabledAccessibilityServiceList(
+ mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
+ mEnabledServiceInfos = mAccessibilityManager.getEnabledAccessibilityServiceList(
AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
}
@Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ mEnabledServiceInfos = mAccessibilityManager.getEnabledAccessibilityServiceList(
+ AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+
+ if (mEnabledServiceInfos.isEmpty()) {
+ preference.setVisible(false);
+ }
+ }
+
+ @Override
public int getAvailabilityStatus() {
return mEnabledServiceInfos.isEmpty() ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
}
diff --git a/src/com/android/settings/utils/CandidateInfoExtra.java b/src/com/android/settings/utils/CandidateInfoExtra.java
new file mode 100644
index 0000000..5bccea6
--- /dev/null
+++ b/src/com/android/settings/utils/CandidateInfoExtra.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.utils;
+
+import android.graphics.drawable.Drawable;
+
+import com.android.settingslib.widget.CandidateInfo;
+
+public class CandidateInfoExtra extends CandidateInfo {
+ private final CharSequence mLabel;
+ private final CharSequence mSummary;
+ private final String mKey;
+
+ public CandidateInfoExtra(CharSequence label, CharSequence summary, String key,
+ boolean enabled) {
+ super(enabled);
+ mLabel = label;
+ mSummary = summary;
+ mKey = key;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return mLabel;
+ }
+
+ public CharSequence loadSummary() {
+ return mSummary;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return mKey;
+ }
+}
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 28c987b..4920e11 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -67,6 +67,7 @@
test_options: {
timeout: 36000,
+ shards: 10,
},
coverage_libs: [
diff --git a/tests/robotests/assets/grandfather_slice_controller_not_in_xml b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
index 55ecffe..94d5815 100644
--- a/tests/robotests/assets/grandfather_slice_controller_not_in_xml
+++ b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
@@ -3,6 +3,7 @@
com.android.settings.biometrics.face.FaceSettingsAttentionPreferenceController
com.android.settings.network.telephony.MmsMessagePreferenceController
com.android.settings.network.telephony.DataDuringCallsPreferenceController
+com.android.settings.network.telephony.Enhanced4gBasePreferenceController
com.android.settings.testutils.FakeToggleController
com.android.settings.testutils.FakeSliderController
com.android.settings.testutils.FakeInvalidSliderController
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
index 55c2009..3e96847 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
@@ -37,9 +37,9 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -49,20 +49,20 @@
@RunWith(RobolectricTestRunner.class)
public class DefaultAppPickerFragmentTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private FragmentActivity mActivity;
@Mock
private PreferenceScreen mScreen;
@Mock
private UserManager mUserManager;
private FakeFeatureFactory mFeatureFactory;
+ private FragmentActivity mActivity;
private TestFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFeatureFactory = FakeFeatureFactory.setupForTest();
+ mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get());
mFragment = spy(new TestFragment());
when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
index 69242fe..502a62b 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
@@ -18,11 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.service.settings.suggestions.Suggestion;
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.suggestions.SuggestionController;
@@ -91,4 +97,49 @@
verify(mSuggestionController).getSuggestions();
}
+
+ @Test
+ public void onDismiss_shouldCallSuggestionControllerDismiss() {
+ mController.mSuggestionController = mSuggestionController;
+ mController.setCardUpdateListener(mCardUpdateListener);
+
+ mController.onDismissed(buildContextualCard("test1"));
+
+ verify(mSuggestionController).dismissSuggestions(any(Suggestion.class));
+ }
+
+ @Test
+ public void onDismiss_shouldRemoveSuggestionFromList() {
+ mController.setCardUpdateListener(mCardUpdateListener);
+ mController.mSuggestions.add(buildContextualCard("test1"));
+ final ContextualCard card2 = buildContextualCard("test2");
+ mController.mSuggestions.add(card2);
+ assertThat(mController.mSuggestions).hasSize(2);
+
+ mController.onDismissed(card2);
+
+ assertThat(mController.mSuggestions).hasSize(1);
+ }
+
+ @Test
+ public void onDismiss_shouldCallUpdateAdapter() {
+ mController.setCardUpdateListener(mCardUpdateListener);
+ final ContextualCard card = buildContextualCard("test1");
+ mController.mSuggestions.add(card);
+
+ mController.onDismissed(card);
+
+ verify(mCardUpdateListener).onContextualCardUpdated(anyMap());
+ }
+
+ private ContextualCard buildContextualCard(String name) {
+ return new LegacySuggestionContextualCard.Builder()
+ .setSuggestion(mock(Suggestion.class))
+ .setName(name)
+ .setTitleText("test_title")
+ .setSummaryText("test_summary")
+ .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+ .setViewType(LegacySuggestionContextualCardRenderer.VIEW_TYPE)
+ .build();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
index 596e95d6..65b3233 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
@@ -83,6 +83,25 @@
}
@Test
+ public void bindView_closeButton_shouldSetListener() {
+ final RecyclerView recyclerView = new RecyclerView(mActivity);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ final ContextualCard card = buildContextualCard();
+ final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+ recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+ card.getViewType());
+ final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+ when(mControllerRendererPool.getController(mActivity,
+ ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildContextualCard());
+
+ assertThat(closeButton).isNotNull();
+ assertThat(closeButton.hasOnClickListeners()).isTrue();
+ }
+
+ @Test
public void viewClick_shouldInvokeControllerPrimaryClick() {
final RecyclerView recyclerView = new RecyclerView(mActivity);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
@@ -102,6 +121,27 @@
verify(mController).onPrimaryClick(any(ContextualCard.class));
}
+ @Test
+ public void viewClick_closeButton_shouldInvokeControllerDismissClick() {
+ final RecyclerView recyclerView = new RecyclerView(mActivity);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ final ContextualCard card = buildContextualCard();
+ final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+ recyclerView, false);
+ final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+ card.getViewType());
+ final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+ when(mControllerRendererPool.getController(mActivity,
+ ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+ mRenderer.bindView(viewHolder, buildContextualCard());
+
+ assertThat(closeButton).isNotNull();
+ closeButton.performClick();
+
+ verify(mController).onDismissed(any(ContextualCard.class));
+ }
+
private ContextualCard buildContextualCard() {
return new LegacySuggestionContextualCard.Builder()
.setName("test_name")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
index e0e5a0c..2ffbdc9 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Mockito.mock;
import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
import com.android.settings.homepage.contextualcards.ContextualCard;
@@ -51,4 +52,12 @@
.build()
.getPendingIntent()).isNotNull();
}
+
+ @Test
+ public void build_shouldSetSuggestion() {
+ assertThat(new LegacySuggestionContextualCard.Builder()
+ .setSuggestion(mock(Suggestion.class))
+ .build()
+ .getSuggestion()).isNotNull();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
new file mode 100644
index 0000000..e4eac68
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.SwitchPreference;
+
+import com.android.ims.ImsManager;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class Enhanced4gBasePreferenceControllerTest {
+ private static final int SUB_ID = 2;
+
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private TelephonyManager mInvalidTelephonyManager;
+ @Mock
+ private SubscriptionManager mSubscriptionManager;
+ @Mock
+ private CarrierConfigManager mCarrierConfigManager;
+ @Mock
+ private ImsManager mImsManager;
+
+ private Enhanced4gLtePreferenceController mController;
+ private SwitchPreference mPreference;
+ private PersistableBundle mCarrierConfig;
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+ doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+ doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
+ doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+ doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+ mCarrierConfig = new PersistableBundle();
+ doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+ mPreference = new RestrictedSwitchPreference(mContext);
+ mController = new Enhanced4gLtePreferenceController(mContext, "roaming");
+ mController.init(SUB_ID);
+ mController.mImsManager = mImsManager;
+ mPreference.setKey(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void getAvailabilityStatus_default_returnUnavailable() {
+ mController.init(SUB_ID);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
+ doReturn(false).when(mImsManager).isVolteEnabledByPlatform();
+ doReturn(true).when(mImsManager).isVolteProvisionedOnDevice();
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void updateState_configEnabled_prefEnabled() {
+ mPreference.setEnabled(false);
+ mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
+ doReturn(TelephonyManager.CALL_STATE_IDLE).when(mTelephonyManager).getCallState(SUB_ID);
+ doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+ mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ }
+
+ @Test
+ public void updateState_configOn_prefChecked() {
+ mPreference.setChecked(false);
+ doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
+ doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java
deleted file mode 100644
index bea8f67..0000000
--- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.network.telephony;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.preference.SwitchPreference;
-
-import com.android.ims.ImsManager;
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.RestrictedSwitchPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class Enhanced4gLtePreferenceControllerTest {
- private static final int SUB_ID = 2;
-
- @Mock
- private TelephonyManager mTelephonyManager;
- @Mock
- private TelephonyManager mInvalidTelephonyManager;
- @Mock
- private SubscriptionManager mSubscriptionManager;
- @Mock
- private CarrierConfigManager mCarrierConfigManager;
- @Mock
- private ImsManager mImsManager;
-
- private Enhanced4gLtePreferenceController mController;
- private SwitchPreference mPreference;
- private PersistableBundle mCarrierConfig;
- private Context mContext;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mContext = spy(RuntimeEnvironment.application);
- doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
- doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
- doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
- doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
- doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
- mCarrierConfig = new PersistableBundle();
- doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
-
- mPreference = new RestrictedSwitchPreference(mContext);
- mController = new Enhanced4gLtePreferenceController(mContext, "roaming");
- mController.init(SUB_ID);
- mController.mImsManager = mImsManager;
- mPreference.setKey(mController.getPreferenceKey());
- }
-
- @Test
- public void getAvailabilityStatus_invalidSubId_returnUnavailable() {
- mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(
- BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
- }
-
- @Test
- public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
- doReturn(false).when(mImsManager).isVolteEnabledByPlatform();
- doReturn(true).when(mImsManager).isVolteProvisionedOnDevice();
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(
- BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
- }
-
- @Test
- public void updateState_doNotShow4GForLTE_showVolteTitleAndSummary() {
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
-
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary));
- }
-
- @Test
- public void updateState_show4GForLTE_show4GTitleAndSummary() {
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
-
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling));
-
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling));
- }
-
- @Test
- public void updateState_variantAdvancedCalling_showAdvancedCallingTitleAndSummary() {
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
-
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
- mController.updateState(mPreference);
- assertThat(mPreference.getTitle()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling));
- assertThat(mPreference.getSummary()).isEqualTo(
- mContext.getString(R.string.enhanced_4g_lte_mode_summary));
- }
-
- @Test
- public void updateState_configEnabled_prefEnabled() {
- mPreference.setEnabled(false);
- mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
- doReturn(TelephonyManager.CALL_STATE_IDLE).when(mTelephonyManager).getCallState(SUB_ID);
- doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
- mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
-
- mController.updateState(mPreference);
-
- assertThat(mPreference.isEnabled()).isTrue();
- }
-
- @Test
- public void updateState_configOn_prefChecked() {
- mPreference.setChecked(false);
- doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
- doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
-
- mController.updateState(mPreference);
-
- assertThat(mPreference.isChecked()).isTrue();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 86f2355..f079396 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -16,7 +16,7 @@
package com.android.settings.network.telephony;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -88,10 +88,10 @@
}
@Test
- public void getAvailabilityStatus_invalidSubscription_returnDisabledDependentSetting() {
+ public void getAvailabilityStatus_invalidSubscription_returnAvailableUnsearchable() {
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
index 33109b0..c07b1ad 100644
--- a/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
@@ -20,12 +20,13 @@
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
-import android.provider.DeviceConfig;
import android.view.accessibility.AccessibilityManager;
-import com.android.settings.Utils;
+import androidx.preference.Preference;
+
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import org.junit.After;
@@ -65,10 +66,8 @@
@Test
public void getAvailabilityStatus_noEnabledServices_shouldReturnUnsupported() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
- Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
mAccessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
- AccessibilityUsagePreferenceController controller =
+ final AccessibilityUsagePreferenceController controller =
new AccessibilityUsagePreferenceController(mContext, "test_key");
assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
@@ -76,13 +75,24 @@
@Test
public void getAvailabilityStatus_enabledServices_shouldReturnAvailable() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
- Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "false", true);
mAccessibilityManager.setEnabledAccessibilityServiceList(
new ArrayList<>(Arrays.asList(new AccessibilityServiceInfo())));
- AccessibilityUsagePreferenceController controller =
+ final AccessibilityUsagePreferenceController controller =
new AccessibilityUsagePreferenceController(mContext, "test_key");
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
+
+ @Test
+ public void updateState_noEnabledServices_shouldHidePreference() {
+ mAccessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
+ final AccessibilityUsagePreferenceController controller =
+ new AccessibilityUsagePreferenceController(mContext, "test_key");
+ final Preference preference = new Preference(mContext);
+ preference.setVisible(true);
+
+ controller.updateState(preference);
+
+ assertThat(preference.isVisible()).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index e692fed..226dfdb 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -40,6 +40,7 @@
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
@@ -546,4 +547,14 @@
assertThat(eapMethodSpinner.getSelectedItemPosition()).isEqualTo(Eap.TLS);
}
+
+ @Test
+ public void getHiddenSettingsPosition_whenAdvancedToggled_shouldBeFirst() {
+ final LinearLayout advancedFieldsLayout = mView.findViewById(R.id.wifi_advanced_fields);
+ final LinearLayout hiddenSettingLayout = mView.findViewById(R.id.hidden_settings_field);
+
+ final LinearLayout firstChild = (LinearLayout) advancedFieldsLayout.getChildAt(0);
+
+ assertThat(firstChild).isEqualTo(hiddenSettingLayout);
+ }
}