Merge "Use EmergencyNumberUtils to get/set emergency settings." into sc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 90aad1b..107ca38 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8306,6 +8306,9 @@
<!-- Configure Notifications Settings title. [CHAR LIMIT=30] -->
<string name="configure_notification_settings">Notifications</string>
+ <!-- notification header - settings for conversation type notifications -->
+ <string name="conversation_notifs_category">Conversation</string>
+
<!-- notification header - apps that have recently sent notifications -->
<string name="recent_notifications">Recently sent</string>
@@ -8313,7 +8316,7 @@
<string name="recent_notifications_see_all_title">See all from last 7 days</string>
<!-- Configure Notifications: Advanced section header [CHAR LIMIT=30] -->
- <string name="advanced_section_header">Advanced</string>
+ <string name="advanced_section_header">General</string>
<!-- Configure Notifications: Work profile section header [CHAR LIMIT=30] -->
<string name="profile_section_header">Work notifications</string>
@@ -8480,8 +8483,8 @@
<!-- Configure Notifications: Title for the pulse notification light option. [CHAR LIMIT=30] -->
<string name="notification_pulse_title">Blink light</string>
- <!-- Configure Notifications: Title for the option controlling notifications on the lockscreen. [CHAR LIMIT=60] -->
- <string name="lock_screen_notifications_title">Notifications on lock screen</string>
+ <!-- Configure Notifications: Title for the option controlling privacy options for notifications. [CHAR LIMIT=60] -->
+ <string name="lock_screen_notifications_title">Privacy</string>
<!-- Configure lock screen: Title for the option of unlocking directly to home. [CHAR LIMIT=30] -->
<string name="lockscreen_bypass_title">Skip lock screen</string>
@@ -10638,7 +10641,7 @@
<string name="operator_warning">Carrier data accounting may differ from device accounting</string>
<!-- A summary shown on data usage screens to indicate data tracking excluded from carrier networks [CHAR LIMIT=NONE] -->
- <string name="non_carrier_data_usage_warning">Excludes data that is used by carrier networks</string>
+ <string name="non_carrier_data_usage_warning">Excludes data used by carrier networks</string>
<!-- Format string describing how much data has been used [CHAR LIMIT=20] -->
<string name="data_used_template"><xliff:g name="amount" example="1 GB">%1$s</xliff:g> used</string>
@@ -12639,7 +12642,7 @@
<!-- Provider Model: No SIM status in summary for Calls & SMS -->
<string name="calls_sms_no_sim">No SIM</string>
<!-- Network & internet preferences title [CHAR LIMIT=NONE] -->
- <string name="network_and_internet_preferences_title">Preferences</string>
+ <string name="network_and_internet_preferences_title">Network preferences</string>
<!-- Network & internet preferences summary [CHAR LIMIT=NONE] -->
<string name="network_and_internet_preferences_summary">Connect to public networks</string>
<!-- Search keywords for "Internet" settings [CHAR_LIMIT=NONE] -->
@@ -12666,8 +12669,6 @@
<string name="airplane_mode_network_available">Airplane mode networks available</string>
<!-- Summary for warning to disconnect ethernet first then switch to other networks. [CHAR LIMIT=60] -->
<string name="to_switch_networks_disconnect_ethernet">To switch networks, disconnect ethernet</string>
- <!-- Summary for cannot switch networks to Wi-Fi nor mobile data networks while connected to an ethernet network. [CHAR LIMIT=60] -->
- <string name="cannot_switch_networks_while_connected">Cannot switch networks while connected</string>
<!-- Title for airplane mode network panel. [CHAR LIMIT=60] -->
<string name="airplane_mode_network_panel_title">Airplane mode networks</string>
diff --git a/res/xml/configure_notification_settings_v2.xml b/res/xml/configure_notification_settings_v2.xml
index 562e193..6c3ec52 100644
--- a/res/xml/configure_notification_settings_v2.xml
+++ b/res/xml/configure_notification_settings_v2.xml
@@ -18,59 +18,27 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/configure_notification_settings">
- <com.android.settings.widget.VideoPreference
- android:key="notification_model_illustration"
- android:title="@string/summary_placeholder"
- settings:animation="@raw/notification_interruption_model"
- settings:controller="com.android.settings.widget.VideoPreferenceController"
- android:persistent="false" />
-
- <Preference
- android:key="notification_history"
- android:title="@string/notification_history"
- android:summary="@string/notification_history_summary"
- settings:allowDividerAbove="true"
- settings:allowDividerBelow="false"
- android:order="2">
- <intent
- android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.notification.history.NotificationHistoryActivity" />
- </Preference>
-
- <Preference
- android:key="conversations"
- android:title="@string/conversations_category_title"
- android:order="3"
- settings:controller="com.android.settings.notification.ConversationListSummaryPreferenceController"
- android:fragment="com.android.settings.notification.app.ConversationListSettings"
- />
-
- <Preference
- android:key="notification_bubbles"
- android:title="@string/notification_bubbles_title"
- android:summary="@string/notifications_bubble_setting_on_summary"
- android:order="4"
- settings:controller="com.android.settings.notification.BubbleSummaryNotificationPreferenceController"
- android:fragment="com.android.settings.notification.BubbleNotificationSettings"
- />
-
- <com.android.settingslib.RestrictedPreference
- android:key="app_and_notif_cell_broadcast_settings"
- android:title="@string/cell_broadcast_settings"
- android:order="5"
- settings:useAdminDisabledSummary="true">
- <intent
- android:action="android.intent.action.MAIN"
- android:targetPackage="@string/cell_broadcast_receiver_package"
- android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings"/>
- </com.android.settingslib.RestrictedPreference>
+ <PreferenceCategory
+ android:key="conversation_category"
+ android:title="@string/conversation_notifs_category">
+ <Preference
+ android:key="conversations"
+ android:title="@string/conversations_category_title"
+ settings:controller="com.android.settings.notification.ConversationListSummaryPreferenceController"
+ android:fragment="com.android.settings.notification.app.ConversationListSettings"
+ />
+ <Preference
+ android:key="notification_bubbles"
+ android:title="@string/notification_bubbles_title"
+ android:summary="@string/notifications_bubble_setting_on_summary"
+ settings:controller="com.android.settings.notification.BubbleSummaryNotificationPreferenceController"
+ android:fragment="com.android.settings.notification.BubbleNotificationSettings"
+ />
+ </PreferenceCategory>
<PreferenceCategory
android:key="recent_notifications_category"
- android:title="@string/recent_notifications"
- settings:allowDividerAbove="true"
- android:order="6">
+ android:title="@string/recent_notifications">
<!-- Placeholder for a list of recent apps -->
<!-- See all apps button -->
@@ -78,7 +46,6 @@
android:key="all_notifications"
android:title="@string/notifications_title"
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
- android:order="7"
settings:searchable="false">
<extra
android:name="classname"
@@ -86,11 +53,18 @@
</Preference>
</PreferenceCategory>
-
<PreferenceCategory
android:key="configure_notifications_lock"
- android:title="@string/lock_screen_notifications_title"
- android:order="10">
+ android:title="@string/lock_screen_notifications_title">
+ <Preference
+ android:key="notification_history"
+ android:title="@string/notification_history"
+ android:summary="@string/notification_history_summary">
+ <intent
+ android:action="android.intent.action.MAIN"
+ android:targetPackage="com.android.settings"
+ android:targetClass="com.android.settings.notification.history.NotificationHistoryActivity" />
+ </Preference>
<!-- When device is locked -->
<com.android.settings.RestrictedListPreference
android:key="lock_screen_notifications"
@@ -120,14 +94,29 @@
</PreferenceCategory>
<PreferenceCategory
- android:key="configure_notifications_advanced"
- android:order="15"
- settings:initialExpandedChildrenCount="0">
+ android:key="advanced_section_header"
+ android:title="@string/advanced_section_header">
+ <com.android.settingslib.RestrictedPreference
+ android:key="zen_mode_notifications"
+ android:title="@string/zen_mode_settings_title"
+ settings:useAdminDisabledSummary="true"
+ android:fragment="com.android.settings.notification.zen.ZenModeSettings"
+ settings:controller="com.android.settings.notification.zen.ZenModePreferenceController"
+ />
+ <com.android.settingslib.RestrictedPreference
+ android:key="app_and_notif_cell_broadcast_settings"
+ android:title="@string/cell_broadcast_settings"
+ settings:useAdminDisabledSummary="true">
+ <intent
+ android:action="android.intent.action.MAIN"
+ android:targetPackage="@string/cell_broadcast_receiver_package"
+ android:targetClass="com.android.cellbroadcastreceiver.CellBroadcastSettings"/>
+ </com.android.settingslib.RestrictedPreference>
<SwitchPreference
- android:key="silent_icons"
- android:title="@string/silent_notifications_status_bar"
- settings:controller="com.android.settings.notification.SilentStatusBarPreferenceController"/>
+ android:key="silent_icons"
+ android:title="@string/silent_notifications_status_bar"
+ settings:controller="com.android.settings.notification.SilentStatusBarPreferenceController"/>
<SwitchPreference
android:key="show_snooze_options"
@@ -140,33 +129,10 @@
android:title="@string/notification_badging_title"
settings:controller="com.android.settings.notification.BadgingNotificationPreferenceController"/>
- <!-- Pulse notification light -->
+ <!-- Pulse notification light, on devices that support it -->
<SwitchPreference
android:key="notification_pulse"
android:title="@string/notification_pulse_title"
settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/>
-
- <!-- Default notification ringtone -->
- <com.android.settings.DefaultRingtonePreference
- android:key="notification_default_ringtone"
- android:title="@string/notification_ringtone_title"
- android:dialogTitle="@string/notification_ringtone_title"
- android:summary="@string/summary_placeholder"
- android:ringtoneType="notification"
- settings:searchable="false"/>
-
- <Preference
- android:key="gesture_swipe_down_fingerprint_notifications"
- android:title="@string/fingerprint_swipe_for_notifications_title"
- android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
- settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController"/>
-
- <com.android.settingslib.RestrictedPreference
- android:key="zen_mode_notifications"
- android:title="@string/zen_mode_settings_title"
- settings:useAdminDisabledSummary="true"
- android:fragment="com.android.settings.notification.zen.ZenModeSettings"
- settings:controller="com.android.settings.notification.zen.ZenModePreferenceController"
- settings:allowDividerAbove="false"/>
</PreferenceCategory>
</PreferenceScreen>
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 162dc38..fb03f4c 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -22,10 +22,16 @@
settings:keywords="@string/keywords_location">
<PreferenceCategory
- android:key="recent_location_access"
- android:title="@string/location_category_recent_location_access"
- settings:controller=
- "com.android.settings.location.RecentLocationAccessPreferenceController"/>
+ android:key="recent_location_requests"
+ android:title="@string/location_category_recent_location_requests"
+ settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
+
+ <Preference
+ android:key="recent_location_requests_see_all_button"
+ android:title="@string/location_recent_location_requests_see_all"
+ android:icon="@drawable/ic_chevron_right_24dp"
+ android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
+ settings:searchable="false"/>
<PreferenceCategory
android:key="location_advanced_settings"
diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml
index e2a2f15..de8ed81 100644
--- a/res/xml/location_settings_personal.xml
+++ b/res/xml/location_settings_personal.xml
@@ -25,8 +25,14 @@
<PreferenceCategory
android:key="recent_location_requests"
android:title="@string/location_category_recent_location_requests"
- settings:controller=
- "com.android.settings.location.RecentLocationAccessPreferenceController"/>
+ settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
+
+ <Preference
+ android:key="recent_location_requests_see_all_button"
+ android:title="@string/location_recent_location_requests_see_all"
+ android:icon="@drawable/ic_chevron_right_24dp"
+ android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
+ settings:searchable="false"/>
<!-- This preference category gets removed if new_recent_location_ui is disabled -->
<Preference
diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml
index f6f2d96..f15c8d8 100644
--- a/res/xml/location_settings_workprofile.xml
+++ b/res/xml/location_settings_workprofile.xml
@@ -25,8 +25,16 @@
<PreferenceCategory
android:key="recent_location_requests"
android:title="@string/location_category_recent_location_requests"
- settings:controller=
- "com.android.settings.location.RecentLocationAccessPreferenceController"/>
+ settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
+
+ <Preference
+ android:key="recent_location_requests_see_all_button"
+ android:title="@string/location_recent_location_requests_see_all"
+ android:icon="@drawable/ic_chevron_right_24dp"
+ android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
+ settings:controller="com.android.settings.core.WorkPreferenceController"
+ settings:forWork="true"
+ settings:searchable="false"/>
<com.android.settingslib.RestrictedSwitchPreference
android:key="managed_profile_location_switch"
diff --git a/res/xml/network_provider_settings.xml b/res/xml/network_provider_settings.xml
index 67fc73d..0a8dbaa 100644
--- a/res/xml/network_provider_settings.xml
+++ b/res/xml/network_provider_settings.xml
@@ -39,7 +39,7 @@
<Preference
android:key="connected_ethernet_network"
android:title="@string/ethernet"
- android:summary="@string/cannot_switch_networks_while_connected"
+ android:summary="@string/to_switch_networks_disconnect_ethernet"
android:icon="@drawable/ic_settings_ethernet"/>
<PreferenceCategory
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index f683f3c..b5e414b 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -21,11 +21,10 @@
android:title="@string/power_usage_summary_title"
settings:keywords="@string/keywords_battery">
- <com.android.settingslib.widget.LayoutPreference
+ <com.android.settingslib.widget.UsageProgressBarPreference
android:key="battery_header"
android:title="@string/summary_placeholder"
android:selectable="false"
- android:layout="@layout/battery_header"
settings:controller="com.android.settings.fuelgauge.BatteryHeaderPreferenceController" />
<Preference
diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
index 6e4818a..83b4241 100644
--- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
@@ -19,9 +19,12 @@
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
import android.os.Bundle;
+import android.os.UidBatteryConsumer;
import android.os.UserManager;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
@@ -36,6 +39,7 @@
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.BatteryEntry;
import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
+import com.android.settings.fuelgauge.BatteryUsageStatsLoader;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -46,11 +50,19 @@
import java.util.List;
public class AppBatteryPreferenceController extends BasePreferenceController
- implements LoaderManager.LoaderCallbacks<BatteryStatsHelper>,
- LifecycleObserver, OnResume, OnPause {
+ implements LifecycleObserver, OnResume, OnPause {
private static final String KEY_BATTERY = "battery";
+ // TODO(b/180630447): switch to BatteryUsageStatsLoader and remove all references to
+ // BatteryStatsHelper and BatterySipper
+ @VisibleForTesting
+ final BatteryStatsHelperLoaderCallbacks mBatteryStatsHelperLoaderCallbacks =
+ new BatteryStatsHelperLoaderCallbacks();
+ @VisibleForTesting
+ final BatteryUsageStatsLoaderCallbacks mBatteryUsageStatsLoaderCallbacks =
+ new BatteryUsageStatsLoaderCallbacks();
+
@VisibleForTesting
BatterySipper mSipper;
@VisibleForTesting
@@ -58,6 +70,11 @@
@VisibleForTesting
BatteryUtils mBatteryUtils;
+ @VisibleForTesting
+ BatteryUsageStats mBatteryUsageStats;
+ @VisibleForTesting
+ UidBatteryConsumer mUidBatteryConsumer;
+
private Preference mPreference;
private final AppInfoDashboardFragment mParent;
private String mBatteryPercent;
@@ -96,7 +113,8 @@
if (isBatteryStatsAvailable()) {
final UserManager userManager =
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
- final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper);
+ final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper,
+ mUidBatteryConsumer);
entry.defaultPackageName = mPackageName;
AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent,
mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent);
@@ -110,48 +128,48 @@
@Override
public void onResume() {
mParent.getLoaderManager().restartLoader(
- mParent.LOADER_BATTERY, Bundle.EMPTY, this);
+ AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY,
+ mBatteryStatsHelperLoaderCallbacks);
+ mParent.getLoaderManager().restartLoader(
+ AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS, Bundle.EMPTY,
+ mBatteryUsageStatsLoaderCallbacks);
}
@Override
public void onPause() {
- mParent.getLoaderManager().destroyLoader(mParent.LOADER_BATTERY);
+ mParent.getLoaderManager().destroyLoader(AppInfoDashboardFragment.LOADER_BATTERY);
+ mParent.getLoaderManager().destroyLoader(
+ AppInfoDashboardFragment.LOADER_BATTERY_USAGE_STATS);
}
- @Override
- public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
- return new BatteryStatsHelperLoader(mContext);
- }
+ private void onLoadFinished() {
+ // Wait for both loaders to finish before proceeding.
+ if (mBatteryHelper == null || mBatteryUsageStats == null) {
+ return;
+ }
- @Override
- public void onLoadFinished(Loader<BatteryStatsHelper> loader,
- BatteryStatsHelper batteryHelper) {
- mBatteryHelper = batteryHelper;
final PackageInfo packageInfo = mParent.getPackageInfo();
if (packageInfo != null) {
- mSipper = findTargetSipper(batteryHelper, packageInfo.applicationInfo.uid);
+ mSipper = findTargetSipper(mBatteryHelper, packageInfo.applicationInfo.uid);
+ mUidBatteryConsumer = findTargetUidBatteryConsumer(mBatteryUsageStats,
+ packageInfo.applicationInfo.uid);
if (mParent.getActivity() != null) {
updateBattery();
}
}
}
- @Override
- public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
- }
-
@VisibleForTesting
void updateBattery() {
mPreference.setEnabled(true);
if (isBatteryStatsAvailable()) {
- final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
- BatteryStats.STATS_SINCE_CHARGED);
+ final int dischargePercentage = mBatteryUsageStats.getDischargePercentage();
final List<BatterySipper> usageList = new ArrayList<>(mBatteryHelper.getUsageList());
final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList);
final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
- mSipper.totalPowerMah, mBatteryHelper.getTotalPower(), hiddenAmount,
- dischargeAmount);
+ mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(),
+ hiddenAmount, dischargePercentage);
mBatteryPercent = Utils.formatPercentage(percentOfMax);
mPreference.setSummary(mContext.getString(R.string.battery_summary, mBatteryPercent));
} else {
@@ -161,7 +179,7 @@
@VisibleForTesting
boolean isBatteryStatsAvailable() {
- return mBatteryHelper != null && mSipper != null;
+ return mBatteryHelper != null && mSipper != null && mUidBatteryConsumer != null;
}
@VisibleForTesting
@@ -176,4 +194,54 @@
return null;
}
+ @VisibleForTesting
+ UidBatteryConsumer findTargetUidBatteryConsumer(BatteryUsageStats batteryUsageStats, int uid) {
+ final List<UidBatteryConsumer> usageList = batteryUsageStats.getUidBatteryConsumers();
+ for (int i = 0, size = usageList.size(); i < size; i++) {
+ final UidBatteryConsumer consumer = usageList.get(i);
+ if (consumer.getUid() == uid) {
+ return consumer;
+ }
+ }
+ return null;
+ }
+
+ private class BatteryStatsHelperLoaderCallbacks
+ implements LoaderManager.LoaderCallbacks<BatteryStatsHelper> {
+ @Override
+ public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
+ return new BatteryStatsHelperLoader(mContext);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<BatteryStatsHelper> loader,
+ BatteryStatsHelper batteryHelper) {
+ mBatteryHelper = batteryHelper;
+ AppBatteryPreferenceController.this.onLoadFinished();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
+ }
+ }
+
+ private class BatteryUsageStatsLoaderCallbacks
+ implements LoaderManager.LoaderCallbacks<BatteryUsageStats> {
+ @Override
+ @NonNull
+ public Loader<BatteryUsageStats> onCreateLoader(int id, Bundle args) {
+ return new BatteryUsageStatsLoader(mContext);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<BatteryUsageStats> loader,
+ BatteryUsageStats batteryUsageStats) {
+ mBatteryUsageStats = batteryUsageStats;
+ AppBatteryPreferenceController.this.onLoadFinished();
+ }
+
+ @Override
+ public void onLoaderReset(Loader<BatteryUsageStats> loader) {
+ }
+ }
}
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index f584408..6a86c71c 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -95,6 +95,7 @@
static final int LOADER_CHART_DATA = 2;
static final int LOADER_STORAGE = 3;
static final int LOADER_BATTERY = 4;
+ static final int LOADER_BATTERY_USAGE_STATS = 5;
public static final String ARG_PACKAGE_NAME = "package";
public static final String ARG_PACKAGE_UID = "uid";
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
index 1f8b9d1..e53334d 100644
--- a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
+++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.text.TextUtils;
@@ -45,9 +46,11 @@
private PreferenceScreen mScreen;
private Preference mPreference;
private SettingObserver mSettingObserver;
+ private Context mContext;
public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
super(context);
+ mContext = context;
mSettingObserver = new SettingObserver();
mAssistUtils = new AssistUtils(context);
mHelper = new VoiceInputHelper(context);
@@ -59,13 +62,8 @@
@Override
public boolean isAvailable() {
- // If current assist is also voice service, don't show voice preference.
- final ComponentName currentVoiceService =
- DefaultVoiceInputPicker.getCurrentService(mHelper);
- final ComponentName currentAssist =
- mAssistUtils.getAssistComponentForUser(mUserId);
- return !DefaultVoiceInputPicker.isCurrentAssistVoiceService(
- currentAssist, currentVoiceService);
+ return mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_VOICE_RECOGNIZERS);
}
@Override
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 8d7bcd9..1a9db03 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -208,7 +208,7 @@
}
final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid()));
final BatteryEntry entry = new BatteryEntry(mActivity, mHandler, mUserManager,
- sipper);
+ sipper, null);
final Drawable badgedIcon = mUserManager.getBadgedIconForUser(entry.getIcon(),
userHandle);
final CharSequence contentDescription = mUserManager.getBadgedLabelForUser(
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 38ae2b2..d533c80 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -28,6 +28,7 @@
import android.os.Handler;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -122,6 +123,7 @@
public final Context context;
public final BatterySipper sipper;
+ public final UidBatteryConsumer uidBatteryConsumer;
public String name;
public Drawable icon;
@@ -134,10 +136,41 @@
Drawable icon;
}
- public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper) {
+ public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper,
+ UidBatteryConsumer uidBatteryConsumer) {
sHandler = handler;
this.context = context;
this.sipper = sipper;
+ this.uidBatteryConsumer = uidBatteryConsumer;
+
+ // This condition is met when BatteryEntry is initialized from BatteryUsageStats.
+ // Once the conversion from BatteryStatsHelper is completed, the condition will
+ // always be true and can be removed.
+ if (uidBatteryConsumer != null) {
+ PackageManager pm = context.getPackageManager();
+ int uid = uidBatteryConsumer.getUid();
+ String[] packages = pm.getPackagesForUid(uid);
+ // Apps should only have one package
+ if (packages == null || packages.length != 1) {
+ name = uidBatteryConsumer.getPackageWithHighestDrain();
+ } else {
+ defaultPackageName = packages[0];
+ try {
+ ApplicationInfo appInfo =
+ pm.getApplicationInfo(defaultPackageName, 0 /* no flags */);
+ name = pm.getApplicationLabel(appInfo).toString();
+ } catch (NameNotFoundException e) {
+ Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: "
+ + defaultPackageName);
+ name = defaultPackageName;
+ }
+ }
+ if ((name == null || iconId == 0) && uid != 0) {
+ getQuickNameIconForUid(uid);
+ }
+ return;
+ }
+
switch (sipper.drainType) {
case IDLE:
name = context.getResources().getString(R.string.power_idle);
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 11d7564..4415e71 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -25,11 +25,6 @@
import android.os.BatteryManager;
import android.os.PowerManager;
import android.text.TextUtils;
-import android.text.method.LinkMovementMethod;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceFragmentCompat;
@@ -39,14 +34,12 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.utils.AnnotationSpan;
import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.HelpUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.UsageProgressBarPreference;
/**
* Controller that update the battery header view
@@ -57,23 +50,18 @@
@VisibleForTesting
static final String KEY_BATTERY_HEADER = "battery_header";
private static final String ANNOTATION_URL = "url";
+ private static final int BATTERY_MAX_LEVEL = 100;
@VisibleForTesting
BatteryStatusFeatureProvider mBatteryStatusFeatureProvider;
@VisibleForTesting
- BatteryMeterView mBatteryMeterView;
- @VisibleForTesting
- TextView mBatteryPercentText;
- @VisibleForTesting
- TextView mSummary1;
+ UsageProgressBarPreference mBatteryUsageProgressBarPref;
private Activity mActivity;
private PreferenceFragmentCompat mHost;
private Lifecycle mLifecycle;
private final PowerManager mPowerManager;
- private LayoutPreference mBatteryLayoutPref;
-
public BatteryHeaderPreferenceController(Context context, String key) {
super(context, key);
mPowerManager = context.getSystemService(PowerManager.class);
@@ -96,16 +84,12 @@
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mBatteryLayoutPref = screen.findPreference(getPreferenceKey());
- mBatteryMeterView = mBatteryLayoutPref
- .findViewById(R.id.battery_header_icon);
- mBatteryPercentText = mBatteryLayoutPref.findViewById(R.id.battery_percent);
- mSummary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
+ mBatteryUsageProgressBarPref = screen.findPreference(getPreferenceKey());
if (com.android.settings.Utils.isBatteryPresent(mContext)) {
quickUpdateHeaderPreference();
} else {
- showHelpMessage();
+ //TODO(b/179237551): Make new progress bar widget support help message
}
}
@@ -116,8 +100,7 @@
@Override
public void onStart() {
- EntityHeaderController.newInstance(mActivity, mHost,
- mBatteryLayoutPref.findViewById(R.id.battery_entity_header))
+ EntityHeaderController.newInstance(mActivity, mHost, null /* header view */)
.setRecyclerView(mHost.getListView(), mLifecycle)
.styleActionBar(mActivity);
}
@@ -133,21 +116,20 @@
}
public void updateHeaderPreference(BatteryInfo info) {
- mBatteryPercentText.setText(formatBatteryPercentageText(info.batteryLevel));
- if (!mBatteryStatusFeatureProvider.triggerBatteryStatusUpdate(this, info)) {
- mSummary1.setText(generateLabel(info));
- }
- mBatteryMeterView.setBatteryLevel(info.batteryLevel);
- mBatteryMeterView.setCharging(!info.discharging);
- mBatteryMeterView.setPowerSave(mPowerManager.isPowerSaveMode());
+ //TODO(b/179237746): Make progress bar widget support battery state icon
+
+ mBatteryUsageProgressBarPref.setUsageSummary(
+ formatBatteryPercentageText(info.batteryLevel));
+ mBatteryUsageProgressBarPref.setTotalSummary(generateLabel(info));
+ mBatteryUsageProgressBarPref.setPercent(info.batteryLevel, BATTERY_MAX_LEVEL);
}
/**
* Callback which receives text for the summary line.
*/
public void updateBatteryStatus(String label, BatteryInfo info) {
- mSummary1.setText(label != null ? label : generateLabel(info));
+ mBatteryUsageProgressBarPref.setTotalSummary(label != null ? label : generateLabel(info));
}
public void quickUpdateHeaderPreference() {
@@ -157,37 +139,10 @@
final boolean discharging =
batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0;
- // Set battery level and charging status
- mBatteryMeterView.setBatteryLevel(batteryLevel);
- mBatteryMeterView.setCharging(!discharging);
- mBatteryMeterView.setPowerSave(mPowerManager.isPowerSaveMode());
- mBatteryPercentText.setText(formatBatteryPercentageText(batteryLevel));
- }
+ //TODO(b/179237746): Make progress bar widget support battery state icon
- @VisibleForTesting
- void showHelpMessage() {
- final LinearLayout batteryInfoLayout =
- mBatteryLayoutPref.findViewById(R.id.battery_info_layout);
- // Remove battery meter icon
- mBatteryMeterView.setVisibility(View.GONE);
- // Update the width of battery info layout
- final ViewGroup.LayoutParams params = batteryInfoLayout.getLayoutParams();
- params.width = LinearLayout.LayoutParams.WRAP_CONTENT;
- batteryInfoLayout.setLayoutParams(params);
- mBatteryPercentText.setText(mContext.getText(R.string.unknown));
- // Add linkable text for learn more
- final Intent helpIntent = HelpUtils.getHelpIntent(mContext,
- mContext.getString(R.string.help_url_battery_missing),
- mContext.getClass().getName());
- final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan
- .LinkInfo(mContext, ANNOTATION_URL, helpIntent);
- if (linkInfo.isActionable()) {
- mSummary1.setMovementMethod(LinkMovementMethod.getInstance());
- mSummary1.setText(AnnotationSpan
- .linkify(mContext.getText(R.string.battery_missing_help_message), linkInfo));
- } else {
- mSummary1.setText(mContext.getText(R.string.battery_missing_message));
- }
+ mBatteryUsageProgressBarPref.setUsageSummary(formatBatteryPercentageText(batteryLevel));
+ mBatteryUsageProgressBarPref.setPercent(batteryLevel, BATTERY_MAX_LEVEL);
}
private CharSequence formatBatteryPercentageText(int batteryLevel) {
diff --git a/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java b/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java
new file mode 100644
index 0000000..5b184a9
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryUsageStatsLoader.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.content.Context;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
+
+import com.android.settingslib.utils.AsyncLoaderCompat;
+
+/**
+ * Loader to get new {@link BatteryUsageStats} in the background
+ */
+public class BatteryUsageStatsLoader extends AsyncLoaderCompat<BatteryUsageStats> {
+ private final BatteryStatsManager mBatteryStatsManager;
+
+ public BatteryUsageStatsLoader(Context context) {
+ super(context);
+ mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
+ }
+
+ @Override
+ public BatteryUsageStats loadInBackground() {
+ return mBatteryStatsManager.getBatteryUsageStats();
+ }
+
+ @Override
+ protected void onDiscardResult(BatteryUsageStats result) {
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 735f43d..c00c131 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -25,14 +25,9 @@
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings.Global;
-import android.text.format.Formatter;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
-import androidx.loader.app.LoaderManager.LoaderCallbacks;
import androidx.loader.content.Loader;
import com.android.settings.R;
@@ -44,7 +39,6 @@
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.widget.LayoutPreference;
import java.util.List;
@@ -54,18 +48,15 @@
* since the last time it was unplugged.
*/
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class PowerUsageSummary extends PowerUsageBase implements OnLongClickListener,
+public class PowerUsageSummary extends PowerUsageBase implements
BatteryTipPreferenceController.BatteryTipListener {
static final String TAG = "PowerUsageSummary";
- private static final String KEY_BATTERY_HEADER = "battery_header";
-
@VisibleForTesting
static final int BATTERY_INFO_LOADER = 1;
@VisibleForTesting
static final int BATTERY_TIP_LOADER = 2;
- public static final int DEBUG_INFO_LOADER = 3;
@VisibleForTesting
PowerUsageFeatureProvider mPowerFeatureProvider;
@@ -112,49 +103,6 @@
}
};
- LoaderManager.LoaderCallbacks<List<BatteryInfo>> mBatteryInfoDebugLoaderCallbacks =
- new LoaderCallbacks<List<BatteryInfo>>() {
- @Override
- public Loader<List<BatteryInfo>> onCreateLoader(int i, Bundle bundle) {
- return new DebugEstimatesLoader(getContext(), mStatsHelper);
- }
-
- @Override
- public void onLoadFinished(Loader<List<BatteryInfo>> loader,
- List<BatteryInfo> batteryInfos) {
- updateViews(batteryInfos);
- }
-
- @Override
- public void onLoaderReset(Loader<List<BatteryInfo>> loader) {
- }
- };
-
- protected void updateViews(List<BatteryInfo> batteryInfos) {
- final BatteryMeterView batteryView = mBatteryLayoutPref
- .findViewById(R.id.battery_header_icon);
- final TextView percentRemaining =
- mBatteryLayoutPref.findViewById(R.id.battery_percent);
- final TextView summary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
- BatteryInfo oldInfo = batteryInfos.get(0);
- BatteryInfo newInfo = batteryInfos.get(1);
- percentRemaining.setText(Utils.formatPercentage(oldInfo.batteryLevel));
-
- // set the text to the old estimate (copied from battery info). Note that this
- // can sometimes say 0 time remaining because battery stats requires the phone
- // be unplugged for a period of time before being willing ot make an estimate.
- final String OldEstimateString = mPowerFeatureProvider.getOldEstimateDebugString(
- Formatter.formatShortElapsedTime(getContext(),
- PowerUtil.convertUsToMs(oldInfo.remainingTimeUs)));
- final String NewEstimateString = mPowerFeatureProvider.getEnhancedEstimateDebugString(
- Formatter.formatShortElapsedTime(getContext(),
- PowerUtil.convertUsToMs(newInfo.remainingTimeUs)));
- summary1.setText(OldEstimateString + "\n" + NewEstimateString);
-
- batteryView.setBatteryLevel(oldInfo.batteryLevel);
- batteryView.setCharging(!oldInfo.discharging);
- }
-
private LoaderManager.LoaderCallbacks<List<BatteryTip>> mBatteryTipsCallbacks =
new LoaderManager.LoaderCallbacks<List<BatteryTip>>() {
@@ -197,7 +145,6 @@
setAnimationAllowed(true);
initFeatureProvider();
- mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
mBatteryUtils = BatteryUtils.getInstance(getContext());
@@ -275,17 +222,6 @@
}
@VisibleForTesting
- void showBothEstimates() {
- final Context context = getContext();
- if (context == null
- || !mPowerFeatureProvider.isEnhancedBatteryPredictionEnabled(context)) {
- return;
- }
- getLoaderManager().restartLoader(DEBUG_INFO_LOADER, Bundle.EMPTY,
- mBatteryInfoDebugLoaderCallbacks);
- }
-
- @VisibleForTesting
void initFeatureProvider() {
final Context context = getContext();
mPowerFeatureProvider = FeatureFactory.getFactory(context)
@@ -303,11 +239,6 @@
}
getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
mBatteryInfoLoaderCallbacks);
- if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
- // Set long click action for summary to show debug info
- View header = mBatteryLayoutPref.findViewById(R.id.summary1);
- header.setOnLongClickListener(this);
- }
}
@VisibleForTesting
@@ -316,13 +247,6 @@
}
@Override
- public boolean onLongClick(View view) {
- showBothEstimates();
- view.setOnLongClickListener(null);
- return true;
- }
-
- @Override
protected void restartBatteryStatsLoader(@BatteryUpdateType int refreshType) {
super.restartBatteryStatsLoader(refreshType);
// Update battery header if battery is present.
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index ddcdd59..14fe6a6 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -31,6 +31,7 @@
import android.os.ServiceManager;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.VisibleForTesting;
@@ -38,6 +39,7 @@
import com.android.settings.R;
import com.android.settings.SettingsTutorialDialogWrapperActivity;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -77,8 +79,11 @@
@Override
public void onAttach(Context context) {
super.onAttach(context);
- SearchMenuController.init(this /* host */);
- HelpMenuController.init(this /* host */);
+ // TODO(b/176883483): Remove both search and help menu if this feature rolled out
+ if (!FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.SILKY_HOME)) {
+ SearchMenuController.init(this /* host */);
+ HelpMenuController.init(this /* host */);
+ }
SuggestionFeatureProvider suggestionFeatureProvider = FeatureFactory.getFactory(context)
.getSuggestionFeatureProvider(context);
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 0bc7fc7..b4f0f1f 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -82,7 +82,7 @@
super.onAttach(context);
use(AppLocationPermissionPreferenceController.class).init(this);
- use(RecentLocationAccessPreferenceController.class).init(this);
+ use(RecentLocationRequestPreferenceController.class).init(this);
use(LocationServicePreferenceController.class).init(this);
use(LocationFooterPreferenceController.class).init(this);
use(LocationForWorkPreferenceController.class).init(this);
diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java
index c312714..2bf5f98 100644
--- a/src/com/android/settings/location/LocationWorkProfileSettings.java
+++ b/src/com/android/settings/location/LocationWorkProfileSettings.java
@@ -21,6 +21,7 @@
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
/**
* Location Setting page for managed profile.
@@ -53,9 +54,11 @@
use(LocationFooterPreferenceController.class).init(this);
use(LocationForWorkPreferenceController.class).init(this);
- final RecentLocationAccessPreferenceController controller =
- use(RecentLocationAccessPreferenceController.class);
+ final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
+ final RecentLocationRequestPreferenceController controller = use(
+ RecentLocationRequestPreferenceController.class);
controller.init(this);
+ controller.setProfileType(profileType);
}
@Override
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
index 245118d..c835a51 100644
--- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -13,141 +13,114 @@
*/
package com.android.settings.location;
-import static android.Manifest.permission_group.LOCATION;
+import static java.util.concurrent.TimeUnit.DAYS;
+import android.Manifest;
import android.content.Context;
import android.content.Intent;
-import android.os.UserHandle;
-import android.os.UserManager;
+import android.icu.text.RelativeDateTimeFormatter;
+import android.provider.DeviceConfig;
+import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+import com.android.settings.Utils;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.location.RecentLocationAccesses;
-import com.android.settingslib.widget.AppPreference;
+import com.android.settingslib.utils.StringUtil;
+import com.android.settingslib.widget.AppEntitiesHeaderController;
+import com.android.settingslib.widget.AppEntityInfo;
+import com.android.settingslib.widget.LayoutPreference;
-import java.util.ArrayList;
import java.util.List;
-/**
- * Preference controller that handles the display of apps that access locations.
- */
-public class RecentLocationAccessPreferenceController extends LocationBasePreferenceController {
- @VisibleForTesting
- RecentLocationAccesses mRecentLocationApps;
- private PreferenceCategory mCategoryRecentLocationRequests;
- private int mType = ProfileSelectFragment.ProfileType.ALL;
+public class RecentLocationAccessPreferenceController extends AbstractPreferenceController
+ implements PreferenceControllerMixin {
+ /** Key for the recent location apps dashboard */
+ private static final String KEY_APPS_DASHBOARD = "apps_dashboard";
+ private final RecentLocationAccesses mRecentLocationAccesses;
+ private AppEntitiesHeaderController mController;
+ private static final int MAXIMUM_APP_COUNT = 3;
- private static class PackageEntryClickedListener implements
- Preference.OnPreferenceClickListener {
- private final Context mContext;
- private final String mPackage;
- private final UserHandle mUserHandle;
-
- PackageEntryClickedListener(Context context, String packageName,
- UserHandle userHandle) {
- mContext = context;
- mPackage = packageName;
- mUserHandle = userHandle;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
- intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, LOCATION);
- intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackage);
- intent.putExtra(Intent.EXTRA_USER, mUserHandle);
- mContext.startActivity(intent);
- return true;
- }
- }
-
- public RecentLocationAccessPreferenceController(Context context, String key) {
- this(context, key, new RecentLocationAccesses(context));
+ public RecentLocationAccessPreferenceController(Context context) {
+ this(context, new RecentLocationAccesses(context));
}
@VisibleForTesting
- public RecentLocationAccessPreferenceController(Context context, String key,
- RecentLocationAccesses recentLocationApps) {
- super(context, key);
- mRecentLocationApps = recentLocationApps;
+ RecentLocationAccessPreferenceController(Context context,
+ RecentLocationAccesses recentAccesses) {
+ super(context);
+ mRecentLocationAccesses = recentAccesses;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_APPS_DASHBOARD;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return Boolean.parseBoolean(
+ DeviceConfig.getProperty(DeviceConfig.NAMESPACE_PRIVACY,
+ Utils.PROPERTY_PERMISSIONS_HUB_ENABLED));
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
- final Context prefContext = mCategoryRecentLocationRequests.getContext();
- final List<RecentLocationAccesses.Access> recentLocationAccesses = new ArrayList<>();
- final UserManager userManager = UserManager.get(mContext);
- for (RecentLocationAccesses.Access access : mRecentLocationApps.getAppListSorted()) {
- if (isRequestMatchesProfileType(userManager, access, mType)) {
- recentLocationAccesses.add(access);
- }
- }
-
- if (recentLocationAccesses.size() > 0) {
- // Add preferences to container in original order (already sorted by recency).
- for (RecentLocationAccesses.Access access : recentLocationAccesses) {
- mCategoryRecentLocationRequests.addPreference(
- createAppPreference(prefContext, access, mFragment));
- }
- } else {
- // If there's no item to display, add a "No recent apps" item.
- final Preference banner = new AppPreference(prefContext);
- banner.setTitle(R.string.location_no_recent_accesses);
- banner.setSelectable(false);
- mCategoryRecentLocationRequests.addPreference(banner);
- }
+ final LayoutPreference preference = screen.findPreference(KEY_APPS_DASHBOARD);
+ final View view = preference.findViewById(R.id.app_entities_header);
+ mController = AppEntitiesHeaderController.newInstance(mContext, view)
+ .setHeaderTitleRes(R.string.location_category_recent_location_access)
+ .setHeaderDetailsRes(R.string.location_recent_location_access_view_details)
+ .setHeaderEmptyRes(R.string.location_no_recent_accesses)
+ .setHeaderDetailsClickListener((View v) -> {
+ final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
+ intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
+ mContext.startActivity(intent);
+ });
}
@Override
- public void onLocationModeChanged(int mode, boolean restricted) {
- mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
+ public void updateState(Preference preference) {
+ updateRecentApps();
}
- /**
- * Initialize {@link ProfileSelectFragment.ProfileType} of the controller
- *
- * @param type {@link ProfileSelectFragment.ProfileType} of the controller.
- */
- public void setProfileType(@ProfileSelectFragment.ProfileType int type) {
- mType = type;
- }
-
- /**
- * Create a {@link AppPreference}
- */
- public static AppPreference createAppPreference(Context prefContext,
- RecentLocationAccesses.Access access, DashboardFragment fragment) {
- final AppPreference pref = new AppPreference(prefContext);
- pref.setIcon(access.icon);
- pref.setTitle(access.label);
- pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
- fragment.getContext(), access.packageName, access.userHandle));
- return pref;
- }
-
- /**
- * Return if the {@link RecentLocationAccesses.Access} matches current UI
- * {@ProfileSelectFragment.ProfileType}
- */
- public static boolean isRequestMatchesProfileType(UserManager userManager,
- RecentLocationAccesses.Access access, @ProfileSelectFragment.ProfileType int type) {
-
- final boolean isWorkProfile = userManager.isManagedProfile(
- access.userHandle.getIdentifier());
- if (isWorkProfile && (type & ProfileSelectFragment.ProfileType.WORK) != 0) {
- return true;
+ private void updateRecentApps() {
+ final List<RecentLocationAccesses.Access> recentLocationAccesses =
+ mRecentLocationAccesses.getAppListSorted();
+ if (recentLocationAccesses.size() > 0) {
+ // Display the top 3 preferences to container in original order.
+ int i = 0;
+ for (; i < Math.min(recentLocationAccesses.size(), MAXIMUM_APP_COUNT); i++) {
+ final RecentLocationAccesses.Access access = recentLocationAccesses.get(i);
+ final AppEntityInfo appEntityInfo = new AppEntityInfo.Builder()
+ .setIcon(access.icon)
+ .setTitle(access.label)
+ .setSummary(StringUtil.formatRelativeTime(mContext,
+ System.currentTimeMillis() - access.accessFinishTime, false,
+ RelativeDateTimeFormatter.Style.SHORT))
+ .setOnClickListener((v) -> {
+ final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
+ intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, access.packageName);
+ intent.putExtra(Intent.EXTRA_USER, access.userHandle);
+ mContext.startActivity(intent);
+ })
+ .build();
+ mController.setAppEntity(i, appEntityInfo);
+ }
+ for (; i < MAXIMUM_APP_COUNT; i++) {
+ mController.removeAppEntity(i);
+ }
}
- if (!isWorkProfile && (type & ProfileSelectFragment.ProfileType.PERSONAL) != 0) {
- return true;
- }
- return false;
+ mController.apply();
}
}
diff --git a/src/com/android/settings/network/ProviderModelSlice.java b/src/com/android/settings/network/ProviderModelSlice.java
index 24077dd..c020f06 100644
--- a/src/com/android/settings/network/ProviderModelSlice.java
+++ b/src/com/android/settings/network/ProviderModelSlice.java
@@ -257,7 +257,7 @@
}
return rowBuilder
.setTitle(mContext.getText(R.string.ethernet))
- .setSubtitle(mContext.getText(R.string.cannot_switch_networks_while_connected));
+ .setSubtitle(mContext.getText(R.string.to_switch_networks_disconnect_ethernet));
}
/**
diff --git a/src/com/android/settings/network/ProviderModelSliceHelper.java b/src/com/android/settings/network/ProviderModelSliceHelper.java
index c7a7ad4..8ae4197 100644
--- a/src/com/android/settings/network/ProviderModelSliceHelper.java
+++ b/src/com/android/settings/network/ProviderModelSliceHelper.java
@@ -29,6 +29,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
@@ -141,7 +142,7 @@
.setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
.addEndItem(toggleAction)
.setPrimaryAction(primaryAction)
- .setSubtitle(summary);
+ .setSubtitle(Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY));
return rowBuilder;
}
diff --git a/src/com/android/settings/network/apn/ApnSettings.java b/src/com/android/settings/network/apn/ApnSettings.java
index f5bb1be..02d9b3d 100755
--- a/src/com/android/settings/network/apn/ApnSettings.java
+++ b/src/com/android/settings/network/apn/ApnSettings.java
@@ -43,6 +43,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
@@ -344,7 +345,8 @@
pref.setSummary(apn);
}
- final boolean selectable = ((type == null) || !type.equals("mms"));
+ final boolean selectable =
+ ((type == null) || type.contains(ApnSetting.TYPE_DEFAULT_STRING));
pref.setSelectable(selectable);
if (selectable) {
if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
diff --git a/src/com/android/settings/notification/app/ConversationListPreferenceController.java b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
index afb965f..948a361 100644
--- a/src/com/android/settings/notification/app/ConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
@@ -163,8 +163,16 @@
return o1.getNotificationChannel().getId().compareTo(
o2.getNotificationChannel().getId());
}
- return sCollator.compare(o1.getShortcutInfo().getLabel(),
- o2.getShortcutInfo().getLabel());
+ if (o1.getShortcutInfo().getLabel() == null
+ && o2.getShortcutInfo().getLabel() != null) {
+ return 1;
+ }
+ if (o1.getShortcutInfo().getLabel() != null
+ && o2.getShortcutInfo().getLabel() == null) {
+ return -1;
+ }
+ return sCollator.compare(o1.getShortcutInfo().getLabel().toString(),
+ o2.getShortcutInfo().getLabel().toString());
}
};
}
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java
index 154856e..c735452 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java
@@ -31,7 +31,9 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.BatteryStats;
+import android.os.BatteryUsageStats;
import android.os.Bundle;
+import android.os.UidBatteryConsumer;
import androidx.loader.app.LoaderManager;
import androidx.preference.Preference;
@@ -67,6 +69,10 @@
@Mock
private BatteryUtils mBatteryUtils;
@Mock
+ private BatteryUsageStats mBatteryUsageStats;
+ @Mock
+ private UidBatteryConsumer mUidBatteryConsumer;
+ @Mock
private BatterySipper mBatterySipper;
@Mock
private BatterySipper mOtherBatterySipper;
@@ -143,6 +149,8 @@
public void updateBattery_hasBatteryStats_summaryPercent() {
mController.mBatteryHelper = mBatteryStatsHelper;
mController.mSipper = mBatterySipper;
+ mController.mBatteryUsageStats = mBatteryUsageStats;
+ mController.mUidBatteryConsumer = mUidBatteryConsumer;
doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
anyDouble(), anyDouble(), anyInt());
doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
@@ -157,6 +165,8 @@
public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
mController.mBatteryHelper = mBatteryStatsHelper;
mController.mSipper = mBatterySipper;
+ mController.mBatteryUsageStats = mBatteryUsageStats;
+ mController.mUidBatteryConsumer = mUidBatteryConsumer;
assertThat(mController.isBatteryStatsAvailable()).isTrue();
}
@@ -175,6 +185,8 @@
when(mBatteryPreference.getKey()).thenReturn(key);
mController.mSipper = mBatterySipper;
mController.mBatteryHelper = mBatteryStatsHelper;
+ mController.mBatteryUsageStats = mBatteryUsageStats;
+ mController.mUidBatteryConsumer = mUidBatteryConsumer;
// Should not crash
mController.handlePreferenceTreeClick(mBatteryPreference);
@@ -187,7 +199,8 @@
mController.onResume();
verify(mLoaderManager)
- .restartLoader(AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY, mController);
+ .restartLoader(AppInfoDashboardFragment.LOADER_BATTERY, Bundle.EMPTY,
+ mController.mBatteryStatsHelperLoaderCallbacks);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index fceee7e..e40b270 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -79,7 +79,8 @@
}
private BatteryEntry createBatteryEntryForApp() {
- return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForApp());
+ return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForApp(),
+ null);
}
private BatterySipper createSipperForApp() {
@@ -90,7 +91,8 @@
}
private BatteryEntry createBatteryEntryForSystem() {
- return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem());
+ return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem(),
+ null);
}
private BatterySipper createSipperForSystem() {
@@ -144,7 +146,7 @@
final BatterySipper batterySipper = mock(BatterySipper.class);
batterySipper.drainType = DrainType.AMBIENT_DISPLAY;
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
- mockUserManager, batterySipper);
+ mockUserManager, batterySipper, null);
assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod);
assertThat(entry.name).isEqualTo("Ambient display");
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index ac3c8f9..14c943d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -32,9 +32,10 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.icu.text.NumberFormat;
import android.os.BatteryManager;
import android.os.PowerManager;
-import android.widget.TextView;
+import android.text.TextUtils;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceFragmentCompat;
@@ -47,7 +48,7 @@
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.UsageProgressBarPreference;
import org.junit.After;
import org.junit.Before;
@@ -57,9 +58,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowPowerManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowEntityHeaderController.class, ShadowUtils.class})
@@ -67,6 +66,7 @@
private static final String PREF_KEY = "battery_header";
private static final int BATTERY_LEVEL = 60;
+ private static final int BATTERY_MAX_LEVEL = 100;
private static final String TIME_LEFT = "2h30min";
private static final String BATTERY_STATUS = "Charging";
@@ -80,13 +80,11 @@
private BatteryInfo mBatteryInfo;
@Mock
private EntityHeaderController mEntityHeaderController;
+ @Mock
+ private UsageProgressBarPreference mBatteryUsageProgressBarPref;
private BatteryHeaderPreferenceController mController;
private Context mContext;
private PowerManager mPowerManager;
- private BatteryMeterView mBatteryMeterView;
- private TextView mBatteryPercentText;
- private TextView mSummary;
- private LayoutPreference mBatteryLayoutPref;
private Intent mBatteryIntent;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
@@ -98,9 +96,6 @@
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
mContext = spy(RuntimeEnvironment.application);
- mBatteryMeterView = new BatteryMeterView(mContext);
- mBatteryPercentText = new TextView(mContext);
- mSummary = new TextView(mContext);
ShadowEntityHeaderController.setUseMock(mEntityHeaderController);
mBatteryIntent = new Intent();
@@ -109,8 +104,7 @@
mBatteryIntent.putExtra(BatteryManager.EXTRA_PLUGGED, 1);
doReturn(mBatteryIntent).when(mContext).registerReceiver(any(), any());
- mBatteryLayoutPref = new LayoutPreference(mContext, R.layout.battery_header);
- doReturn(mBatteryLayoutPref).when(mPreferenceScreen)
+ doReturn(mBatteryUsageProgressBarPref).when(mPreferenceScreen)
.findPreference(BatteryHeaderPreferenceController.KEY_BATTERY_HEADER);
mBatteryInfo.batteryLevel = BATTERY_LEVEL;
@@ -122,9 +116,7 @@
mController.setActivity(mActivity);
mController.setFragment(mPreferenceFragment);
mController.setLifecycle(mLifecycle);
- mController.mBatteryMeterView = mBatteryMeterView;
- mController.mBatteryPercentText = mBatteryPercentText;
- mController.mSummary1 = mSummary;
+ mController.mBatteryUsageProgressBarPref = mBatteryUsageProgressBarPref;
}
@After
@@ -137,11 +129,8 @@
public void displayPreference_displayBatteryLevel() {
mController.displayPreference(mPreferenceScreen);
- assertThat(((BatteryMeterView) mBatteryLayoutPref.findViewById(
- R.id.battery_header_icon)).getBatteryLevel()).isEqualTo(BATTERY_LEVEL);
- assertThat(((TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent))
- .getText().toString())
- .isEqualTo("60 %");
+ verify(mBatteryUsageProgressBarPref).setUsageSummary(formatBatteryPercentageText());
+ verify(mBatteryUsageProgressBarPref).setPercent(BATTERY_LEVEL, BATTERY_MAX_LEVEL);
}
@Test
@@ -150,7 +139,7 @@
mController.updateHeaderPreference(mBatteryInfo);
- assertThat(mSummary.getText()).isEqualTo(mBatteryInfo.remainingLabel);
+ verify(mBatteryUsageProgressBarPref).setTotalSummary(mBatteryInfo.remainingLabel);
}
@Test
@@ -161,8 +150,9 @@
mController.updateHeaderPreference(mBatteryInfo);
- assertThat(mBatteryMeterView.mDrawable.getBatteryLevel()).isEqualTo(BATTERY_LEVEL);
- assertThat(mBatteryMeterView.mDrawable.getCharging()).isEqualTo(false);
+ verify(mBatteryUsageProgressBarPref).setUsageSummary(formatBatteryPercentageText());
+ verify(mBatteryUsageProgressBarPref).setTotalSummary(mBatteryInfo.remainingLabel);
+ verify(mBatteryUsageProgressBarPref).setPercent(BATTERY_LEVEL, BATTERY_MAX_LEVEL);
}
@Test
@@ -172,7 +162,7 @@
mController.updateHeaderPreference(mBatteryInfo);
- assertThat(mSummary.getText()).isEqualTo(BATTERY_STATUS);
+ verify(mBatteryUsageProgressBarPref).setTotalSummary(BATTERY_STATUS);
}
@Test
@@ -181,7 +171,7 @@
mController.updateHeaderPreference(mBatteryInfo);
- assertThat(mSummary.getText().toString().isEmpty()).isTrue();
+ verify(mBatteryUsageProgressBarPref).setTotalSummary(null);
}
@Test
@@ -197,27 +187,10 @@
@Test
public void quickUpdateHeaderPreference_onlyUpdateBatteryLevelAndChargingState() {
- mSummary.setText(BATTERY_STATUS);
-
mController.quickUpdateHeaderPreference();
- assertThat(mBatteryMeterView.getBatteryLevel()).isEqualTo(BATTERY_LEVEL);
- assertThat(mBatteryMeterView.getCharging()).isTrue();
- assertThat(mBatteryPercentText.getText().toString()).isEqualTo("60 %");
- assertThat(mSummary.getText()).isEqualTo(BATTERY_STATUS);
- }
-
- @Test
- public void quickUpdateHeaderPreference_showPowerSave() {
- boolean testValues[] = {false, true};
-
- ShadowPowerManager shadowPowerManager = Shadows.shadowOf(mPowerManager);
- for (boolean value : testValues) {
- shadowPowerManager.setIsPowerSaveMode(value);
- mController.quickUpdateHeaderPreference();
-
- assertThat(mBatteryMeterView.getPowerSave()).isEqualTo(value);
- }
+ verify(mBatteryUsageProgressBarPref).setUsageSummary(formatBatteryPercentageText());
+ verify(mBatteryUsageProgressBarPref).setPercent(BATTERY_LEVEL, BATTERY_MAX_LEVEL);
}
@Test
@@ -226,12 +199,8 @@
BasePreferenceController.AVAILABLE_UNSEARCHABLE);
}
- @Test
- public void displayPreference_batteryNotPresent_shouldShowHelpMessage() {
- ShadowUtils.setIsBatteryPresent(false);
-
- mController.displayPreference(mPreferenceScreen);
-
- verify(mController).showHelpMessage();
+ private CharSequence formatBatteryPercentageText() {
+ return TextUtils.expandTemplate(mContext.getText(R.string.battery_header_title_alternate),
+ NumberFormat.getIntegerInstance().format(BATTERY_LEVEL));
}
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index cf278f6..e345ab2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -23,13 +23,11 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -38,8 +36,6 @@
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
-import android.view.View;
-import android.widget.TextView;
import androidx.loader.app.LoaderManager;
import androidx.preference.PreferenceScreen;
@@ -53,19 +49,14 @@
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
-import com.android.settingslib.widget.LayoutPreference;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@@ -79,15 +70,12 @@
public class PowerUsageSummaryTest {
private static final int UID = 123;
- private static final int UID_2 = 234;
private static final int POWER_MAH = 100;
private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 120 * 60 * 1000;
private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;
private static final long USAGE_TIME_MS = 65 * 60 * 1000;
private static final double TOTAL_POWER = 200;
- private static final String NEW_ML_EST_SUFFIX = "(New ML est)";
- private static final String OLD_EST_SUFFIX = "(Old est)";
private static Intent sAdditionalBatteryInfoIntent;
@BeforeClass
@@ -101,12 +89,6 @@
private BatterySipper mScreenBatterySipper;
@Mock
private BatterySipper mCellBatterySipper;
- @Mock
- private LayoutPreference mBatteryLayoutPref;
- @Mock
- private TextView mBatteryPercentText;
- @Mock
- private TextView mSummary1;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BatteryStatsHelper mBatteryHelper;
@Mock
@@ -114,8 +96,6 @@
@Mock
private LoaderManager mLoaderManager;
@Mock
- private BatteryInfo mBatteryInfo;
- @Mock
private ContentResolver mContentResolver;
@Mock
private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
@@ -128,8 +108,6 @@
private Context mRealContext;
private TestFragment mFragment;
private FakeFeatureFactory mFeatureFactory;
- private BatteryMeterView mBatteryMeterView;
- private Intent mIntent;
@Before
public void setUp() {
@@ -139,8 +117,6 @@
mFeatureFactory = FakeFeatureFactory.setupForTest();
mFragment = spy(new TestFragment(mRealContext));
mFragment.initFeatureProvider();
- mBatteryMeterView = new BatteryMeterView(mRealContext);
- mBatteryMeterView.mDrawable = new BatteryMeterView.BatteryMeterDrawable(mRealContext, 0);
doNothing().when(mFragment).restartBatteryStatsLoader(anyInt());
doReturn(mock(LoaderManager.class)).when(mFragment).getLoaderManager();
@@ -158,12 +134,6 @@
mCellBatterySipper.drainType = BatterySipper.DrainType.CELL;
mCellBatterySipper.totalPowerMah = POWER_MAH;
- when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1);
- when(mBatteryLayoutPref.findViewById(R.id.battery_percent)).thenReturn(mBatteryPercentText);
- when(mBatteryLayoutPref.findViewById(R.id.battery_header_icon))
- .thenReturn(mBatteryMeterView);
- mFragment.setBatteryLayoutPreference(mBatteryLayoutPref);
-
mScreenBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
mScreenBatterySipper.usageTimeMs = USAGE_TIME_MS;
@@ -207,51 +177,6 @@
}
@Test
- public void showBothEstimates_summariesAreBothModified() {
- when(mFeatureFactory.powerUsageFeatureProvider.isEnhancedBatteryPredictionEnabled(any()))
- .thenReturn(true);
- doAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocation) {
- return mRealContext.getString(
- R.string.power_usage_old_debug, invocation.getArguments()[0]);
- }
- }).when(mFeatureFactory.powerUsageFeatureProvider).getOldEstimateDebugString(any());
- doAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocation) {
- return mRealContext.getString(
- R.string.power_usage_enhanced_debug, invocation.getArguments()[0]);
- }
- }).when(mFeatureFactory.powerUsageFeatureProvider).getEnhancedEstimateDebugString(any());
-
- doReturn(new TextView(mRealContext)).when(mBatteryLayoutPref).findViewById(R.id.summary1);
- mFragment.onLongClick(new View(mRealContext));
- TextView summary1 = mFragment.mBatteryLayoutPref.findViewById(R.id.summary1);
- Robolectric.flushBackgroundThreadScheduler();
- assertThat(summary1.getText().toString()).contains(NEW_ML_EST_SUFFIX);
- assertThat(summary1.getText().toString()).contains(OLD_EST_SUFFIX);
- }
-
- @Test
- public void debugMode() {
- doReturn(true).when(mFeatureFactory.powerUsageFeatureProvider).isEstimateDebugEnabled();
-
- mFragment.restartBatteryInfoLoader();
- ArgumentCaptor<View.OnLongClickListener> listener = ArgumentCaptor.forClass(
- View.OnLongClickListener.class);
- verify(mSummary1).setOnLongClickListener(listener.capture());
-
- // Calling the listener should disable it.
- listener.getValue().onLongClick(mSummary1);
- verify(mSummary1).setOnLongClickListener(null);
-
- // Restarting the loader should reset the listener.
- mFragment.restartBatteryInfoLoader();
- verify(mSummary1, times(2)).setOnLongClickListener(any(View.OnLongClickListener.class));
- }
-
- @Test
public void refreshUi_deviceRotate_doNotUpdateBatteryTip() {
mFragment.mBatteryTipPreferenceController = mock(BatteryTipPreferenceController.class);
when(mFragment.mBatteryTipPreferenceController.needUpdate()).thenReturn(false);
@@ -330,23 +255,5 @@
// Override it so we can access this method in test
return super.getContentResolver();
}
-
- @Override
- void showBothEstimates() {
- List<BatteryInfo> fakeBatteryInfo = new ArrayList<>(2);
- BatteryInfo info1 = new BatteryInfo();
- info1.batteryLevel = 10;
- info1.remainingTimeUs = 10000;
- info1.discharging = true;
-
- BatteryInfo info2 = new BatteryInfo();
- info2.batteryLevel = 10;
- info2.remainingTimeUs = 10000;
- info2.discharging = true;
-
- fakeBatteryInfo.add(info1);
- fakeBatteryInfo.add(info2);
- updateViews(fakeBatteryInfo);
- }
}
}
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
index 5feee60..71a80de 100644
--- a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
@@ -24,17 +24,19 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.provider.DeviceConfig;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.ImageView;
import android.widget.TextView;
-import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.Utils;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settingslib.location.RecentLocationAccesses;
+import com.android.settingslib.widget.LayoutPreference;
import org.junit.After;
import org.junit.Before;
@@ -53,14 +55,11 @@
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowDeviceConfig.class})
public class RecentLocationAccessPreferenceControllerTest {
- private static final String PREFERENCE_KEY = "test_preference_key";
@Mock
- private PreferenceCategory mLayoutPreference;
+ private LayoutPreference mLayoutPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
- private DashboardFragment mDashboardFragment;
- @Mock
private RecentLocationAccesses mRecentLocationApps;
private Context mContext;
@@ -72,16 +71,15 @@
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mController = spy(
- new RecentLocationAccessPreferenceController(mContext, PREFERENCE_KEY,
- mRecentLocationApps));
- mController.init(mDashboardFragment);
+ new RecentLocationAccessPreferenceController(mContext, mRecentLocationApps));
final String key = mController.getPreferenceKey();
mAppEntitiesHeaderView = LayoutInflater.from(mContext).inflate(
R.layout.app_entities_header, null /* root */);
when(mScreen.findPreference(key)).thenReturn(mLayoutPreference);
when(mLayoutPreference.getKey()).thenReturn(key);
when(mLayoutPreference.getContext()).thenReturn(mContext);
- when(mDashboardFragment.getContext()).thenReturn(mContext);
+ when(mLayoutPreference.findViewById(R.id.app_entities_header)).thenReturn(
+ mAppEntitiesHeaderView);
}
@After
@@ -90,7 +88,16 @@
}
@Test
- public void isAvailable_shouldReturnTrue() {
+ public void isAvailable_permissionHubNotSet_shouldReturnFalse() {
+ // We have not yet set the property to show the Permissions Hub.
+ assertThat(mController.isAvailable()).isEqualTo(false);
+ }
+
+ @Test
+ public void isAvailable_permissionHubEnabled_shouldReturnTrue() {
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
+ Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
+
assertThat(mController.isAvailable()).isEqualTo(true);
}
@@ -111,6 +118,39 @@
assertThat(details.hasOnClickListeners()).isTrue();
}
+ @Test
+ public void updateState_whenAppListMoreThanThree_shouldDisplayTopThreeApps() {
+ final List<RecentLocationAccesses.Access> accesses = createMockAccesses(6);
+ doReturn(accesses).when(mRecentLocationApps).getAppListSorted();
+ mController.displayPreference(mScreen);
+ mController.updateState(mLayoutPreference);
+
+ // The widget can display the top 3 apps from the list when there're more than 3.
+ final View app1View = mAppEntitiesHeaderView.findViewById(R.id.app1_view);
+ final ImageView appIconView1 = app1View.findViewById(R.id.app_icon);
+ final TextView appTitle1 = app1View.findViewById(R.id.app_title);
+
+ assertThat(app1View.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(appIconView1.getDrawable()).isNotNull();
+ assertThat(appTitle1.getText()).isEqualTo("appTitle0");
+
+ final View app2View = mAppEntitiesHeaderView.findViewById(R.id.app2_view);
+ final ImageView appIconView2 = app2View.findViewById(R.id.app_icon);
+ final TextView appTitle2 = app2View.findViewById(R.id.app_title);
+
+ assertThat(app2View.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(appIconView2.getDrawable()).isNotNull();
+ assertThat(appTitle2.getText()).isEqualTo("appTitle1");
+
+ final View app3View = mAppEntitiesHeaderView.findViewById(R.id.app3_view);
+ final ImageView appIconView3 = app3View.findViewById(R.id.app_icon);
+ final TextView appTitle3 = app3View.findViewById(R.id.app_title);
+
+ assertThat(app3View.getVisibility()).isEqualTo(View.VISIBLE);
+ assertThat(appIconView3.getDrawable()).isNotNull();
+ assertThat(appTitle3.getText()).isEqualTo("appTitle2");
+ }
+
private List<RecentLocationAccesses.Access> createMockAccesses(int count) {
final List<RecentLocationAccesses.Access> accesses = new ArrayList<>();
for (int i = 0; i < count; i++) {
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
index 6714031..8113f22 100644
--- a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
@@ -33,6 +33,12 @@
import android.os.Bundle;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.BulletSpan;
+import android.text.style.QuoteSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.UnderlineSpan;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -211,6 +217,29 @@
ccw.getNotificationChannel().getConversationId());
}
+ @Test
+ public void testCompareSpans() {
+ ConversationChannelWrapper one = new ConversationChannelWrapper();
+ String text1 = "one one";
+ SpannableStringBuilder builder1 = new SpannableStringBuilder(text1);
+ Object first1 = new SubscriptSpan();
+ builder1.setSpan(first1, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ShortcutInfo s1 = new ShortcutInfo.Builder(mContext, "one").setShortLabel(
+ builder1).build();
+ one.setShortcutInfo(s1);
+
+ ConversationChannelWrapper two = new ConversationChannelWrapper();
+ String text2 = "two two";
+ SpannableStringBuilder builder2 = new SpannableStringBuilder(text2);
+ Object first2 = new SubscriptSpan();
+ builder2.setSpan(first2, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ShortcutInfo s2 = new ShortcutInfo.Builder(mContext, "two").setShortLabel(
+ builder2).build();
+ two.setShortcutInfo(s2);
+
+ assertThat(mController.mConversationComparator.compare(one, two)).isLessThan(0);
+ }
+
private final class TestPreferenceController extends ConversationListPreferenceController {
private TestPreferenceController(Context context, NotificationBackend backend) {
diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
index 72e9be4..d205607 100644
--- a/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
+++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java
@@ -40,6 +40,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.Html;
import androidx.slice.Slice;
import androidx.slice.builders.GridRowBuilder;
@@ -169,7 +170,7 @@
@Test
public void createCarrierRow_hasDdsAndActiveNetworkIsNotCellular_verifyTitleAndSummary() {
String expectDisplayName = "Name1";
- String expectedSubtitle = "5G";
+ CharSequence expectedSubtitle = Html.fromHtml("5G", Html.FROM_HTML_MODE_LEGACY);
String networkType = "5G";
final int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
@@ -199,8 +200,9 @@
String networkType = "5G";
String connectedText = ResourcesUtils.getResourcesString(mContext,
"mobile_data_connection_active");
- String expectedSubtitle = ResourcesUtils.getResourcesString(mContext,
- "preference_summary_default_combination", connectedText, networkType);
+ CharSequence expectedSubtitle = Html.fromHtml(ResourcesUtils.getResourcesString(mContext,
+ "preference_summary_default_combination", connectedText, networkType),
+ Html.FROM_HTML_MODE_LEGACY);
final int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
when(mDefaultDataSubscriptionInfo.getSubscriptionId()).thenReturn(defaultDataSubId);