diff --git a/res/drawable/ic_no_internet_airplane.xml b/res/drawable/ic_no_internet_airplane.xml new file mode 100644 index 00000000000..3b22811e7d2 --- /dev/null +++ b/res/drawable/ic_no_internet_airplane.xml @@ -0,0 +1,28 @@ + + + + + \ No newline at end of file diff --git a/res/drawable/ic_no_internet_unavailable.xml b/res/drawable/ic_no_internet_unavailable.xml deleted file mode 100644 index d255cb47377..00000000000 --- a/res/drawable/ic_no_internet_unavailable.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 01c38d83734..89665de59b9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4041,7 +4041,7 @@ apps have access to location - Past 24 hour access + Recent access See all @@ -9687,7 +9687,7 @@ Opening links Open supported links - Supported links open in this app + Allow web links to open in this app Links to open in this app @@ -10523,8 +10523,8 @@ associated with this device, including settings, permissions, corporate access, network activity, and the device\'s location information. - Your device admin may be able to access data associated - with this device and change this device\’s settings. + Your device administrator may be able to access data + associated with this device, manage apps, and change this device\’s settings. Turn off diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml index 1646b1d810d..93f30e58d56 100644 --- a/res/xml/location_settings.xml +++ b/res/xml/location_settings.xml @@ -32,6 +32,7 @@ android:title="@string/location_recent_location_access_see_all" android:icon="@drawable/ic_chevron_right_24dp" android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment" + settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController" settings:searchable="false"/> diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml index 40a822cc6b0..c3efcbe2af5 100644 --- a/res/xml/location_settings_workprofile.xml +++ b/res/xml/location_settings_workprofile.xml @@ -33,7 +33,7 @@ android:title="@string/location_recent_location_access_see_all" android:icon="@drawable/ic_chevron_right_24dp" android:fragment="com.android.settings.location.RecentLocationAccessSeeAllFragment" - settings:controller="com.android.settings.core.WorkPreferenceController" + settings:controller="com.android.settings.location.RecentLocationAccessSeeAllButtonPreferenceController" settings:forWork="true" settings:searchable="false"/> diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java index 6028c188d9f..8b29d67bb28 100644 --- a/src/com/android/settings/AirplaneModeEnabler.java +++ b/src/com/android/settings/AirplaneModeEnabler.java @@ -24,6 +24,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionInfo; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.util.Log; @@ -61,7 +62,7 @@ public class AirplaneModeEnabler extends GlobalSettingsChangeListener { private TelephonyManager mTelephonyManager; @VisibleForTesting - PhoneStateListener mPhoneStateListener; + AirplaneModeTelephonyCallback mTelephonyCallback; public AirplaneModeEnabler(Context context, OnAirplaneModeChangedListener listener) { super(context, Settings.Global.AIRPLANE_MODE_ON); @@ -71,16 +72,18 @@ public class AirplaneModeEnabler extends GlobalSettingsChangeListener { mOnAirplaneModeChangedListener = listener; mTelephonyManager = context.getSystemService(TelephonyManager.class); + mTelephonyCallback = new AirplaneModeTelephonyCallback(); + } - mPhoneStateListener = new PhoneStateListener(Looper.getMainLooper()) { - @Override - public void onRadioPowerStateChanged(int state) { - if (DEBUG) { - Log.d(LOG_TAG, "RadioPower: " + state); - } - onAirplaneModeChanged(); + class AirplaneModeTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.RadioPowerStateListener { + @Override + public void onRadioPowerStateChanged(int state) { + if (DEBUG) { + Log.d(LOG_TAG, "RadioPower: " + state); } - }; + onAirplaneModeChanged(); + } } /** @@ -98,16 +101,14 @@ public class AirplaneModeEnabler extends GlobalSettingsChangeListener { * Start listening to the phone state change */ public void start() { - mTelephonyManager.listen(mPhoneStateListener, - PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED); + mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback); } /** * Stop listening to the phone state change */ public void stop() { - mTelephonyManager.listen(mPhoneStateListener, - PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); } private void setAirplaneModeOn(boolean enabling) { diff --git a/src/com/android/settings/SettingsDumpService.java b/src/com/android/settings/SettingsDumpService.java index 2b6c7d87f89..5e6ee9307a7 100644 --- a/src/com/android/settings/SettingsDumpService.java +++ b/src/com/android/settings/SettingsDumpService.java @@ -14,13 +14,15 @@ package com.android.settings; +import static android.content.pm.PackageManager.FEATURE_ETHERNET; +import static android.content.pm.PackageManager.FEATURE_WIFI; + import android.app.Service; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.net.Uri; import android.os.IBinder; @@ -101,10 +103,10 @@ public class SettingsDumpService extends Service { private JSONObject dumpDataUsage() throws JSONException { JSONObject obj = new JSONObject(); DataUsageController controller = new DataUsageController(this); - ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class); SubscriptionManager manager = this.getSystemService(SubscriptionManager.class); TelephonyManager telephonyManager = this.getSystemService(TelephonyManager.class); - if (connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) { + final PackageManager packageManager = this.getPackageManager(); + if (telephonyManager.isDataCapable()) { JSONArray array = new JSONArray(); for (SubscriptionInfo info : manager.getAvailableSubscriptionInfoList()) { telephonyManager = telephonyManager @@ -117,10 +119,11 @@ public class SettingsDumpService extends Service { } obj.put("cell", array); } - if (connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_WIFI)) { + if (packageManager.hasSystemFeature(FEATURE_WIFI)) { obj.put("wifi", dumpDataUsage(NetworkTemplate.buildTemplateWifiWildcard(), controller)); } - if (connectivityManager.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET)) { + + if (packageManager.hasSystemFeature(FEATURE_ETHERNET)) { obj.put("ethernet", dumpDataUsage(NetworkTemplate.buildTemplateEthernet(), controller)); } return obj; diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index d510ac78c7a..6b629acaeac 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -16,7 +16,7 @@ package com.android.settings.accessibility; -import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM; +import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityShortcutInfo; diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java index 307ceb1e0a2..5f1d9d2a52d 100644 --- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java @@ -18,7 +18,6 @@ package com.android.settings.applications.appinfo; 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; @@ -46,7 +45,6 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; -import java.util.ArrayList; import java.util.List; public class AppBatteryPreferenceController extends BasePreferenceController @@ -113,11 +111,10 @@ public class AppBatteryPreferenceController extends BasePreferenceController if (isBatteryStatsAvailable()) { final UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - final BatteryEntry entry = new BatteryEntry(mContext, null, userManager, mSipper, - mUidBatteryConsumer); - entry.defaultPackageName = mPackageName; + final BatteryEntry entry = new BatteryEntry(mContext, /* handler */null, userManager, + mUidBatteryConsumer, /* isHidden */ false, /* packages */ null, mPackageName); AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, - mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent); + entry, mBatteryPercent); } else { AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent, mPackageName); @@ -163,13 +160,9 @@ public class AppBatteryPreferenceController extends BasePreferenceController void updateBattery() { mPreference.setEnabled(true); if (isBatteryStatsAvailable()) { - final int dischargePercentage = mBatteryUsageStats.getDischargePercentage(); - - final List usageList = new ArrayList<>(mBatteryHelper.getUsageList()); - final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList); final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent( mUidBatteryConsumer.getConsumedPower(), mBatteryUsageStats.getConsumedPower(), - hiddenAmount, dischargePercentage); + mBatteryUsageStats.getDischargePercentage()); mBatteryPercent = Utils.formatPercentage(percentOfMax); mPreference.setSummary(mContext.getString(R.string.battery_summary, mBatteryPercent)); } else { diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java index 73d80a34363..8e8e072a017 100644 --- a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java +++ b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java @@ -16,7 +16,7 @@ package com.android.settings.applications.defaultapps; -import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM; +import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM; import android.content.Context; import android.content.Intent; @@ -33,9 +33,9 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.widget.GearPreference; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.applications.DefaultAppInfo; import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.widget.TwoTargetPreference; public abstract class DefaultAppPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin { diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index 3e0591f81a0..5e6f7e92b90 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -63,8 +63,8 @@ import com.android.settingslib.HelpUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtilsInternal; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.widget.FooterPreference; +import com.android.settingslib.widget.TwoTargetPreference; import java.util.HashMap; import java.util.List; diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java index da0ca63b22b..7da69cb9352 100644 --- a/src/com/android/settings/datausage/DataUsageUtils.java +++ b/src/com/android/settings/datausage/DataUsageUtils.java @@ -14,13 +14,14 @@ package com.android.settings.datausage; -import static android.net.ConnectivityManager.TYPE_MOBILE; -import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.content.pm.PackageManager.FEATURE_ETHERNET; +import static android.content.pm.PackageManager.FEATURE_WIFI; import static android.telephony.TelephonyManager.SIM_STATE_READY; import android.app.usage.NetworkStats.Bucket; import android.app.usage.NetworkStatsManager; import android.content.Context; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.os.RemoteException; @@ -69,8 +70,7 @@ public final class DataUsageUtils extends com.android.settingslib.net.DataUsageU return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains(ETHERNET); } - final ConnectivityManager conn = context.getSystemService(ConnectivityManager.class); - if (!conn.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET)) { + if (!context.getPackageManager().hasSystemFeature(FEATURE_ETHERNET)) { return false; } @@ -96,10 +96,8 @@ public final class DataUsageUtils extends com.android.settingslib.net.DataUsageU * TODO: This is the opposite to Utils.isWifiOnly(), it should be refactored into 1 method. */ public static boolean hasMobileData(Context context) { - final ConnectivityManager connectivityManager = - context.getSystemService(ConnectivityManager.class); - return connectivityManager != null && connectivityManager - .isNetworkSupported(ConnectivityManager.TYPE_MOBILE); + final TelephonyManager tele = context.getSystemService(TelephonyManager.class); + return tele.isDataCapable(); } /** @@ -128,12 +126,13 @@ public final class DataUsageUtils extends com.android.settingslib.net.DataUsageU Log.d(TAG, "hasReadyMobileRadio: subInfo=" + subInfo); } } - final ConnectivityManager conn = context.getSystemService(ConnectivityManager.class); - final boolean retVal = conn.isNetworkSupported(TYPE_MOBILE) && isReady; + + final boolean isDataCapable = tele.isDataCapable(); + final boolean retVal = isDataCapable && isReady; if (LOGD) { Log.d(TAG, "hasReadyMobileRadio:" - + " conn.isNetworkSupported(TYPE_MOBILE)=" - + conn.isNetworkSupported(TYPE_MOBILE) + + " telephonManager.isDataCapable()=" + + isDataCapable + " isReady=" + isReady); } return retVal; @@ -147,9 +146,8 @@ public final class DataUsageUtils extends com.android.settingslib.net.DataUsageU return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi"); } - final ConnectivityManager connectivityManager = - context.getSystemService(ConnectivityManager.class); - return connectivityManager != null && connectivityManager.isNetworkSupported(TYPE_WIFI); + final PackageManager packageManager = context.getPackageManager(); + return packageManager != null && packageManager.hasSystemFeature(FEATURE_WIFI); } /** diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java index a6a211eada7..1e251794458 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java @@ -44,6 +44,7 @@ import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyDisplayInfo; import android.telephony.TelephonyManager; import android.telephony.UiccCardInfo; @@ -170,7 +171,8 @@ public class SimStatusDialogController implements LifecycleObserver { } }; - private PhoneStateListener mPhoneStateListener; + @VisibleForTesting + protected SimStatusDialogTelephonyCallback mTelephonyCallback; private CellBroadcastServiceConnection mCellBroadcastServiceConnection; @@ -235,7 +237,7 @@ public class SimStatusDialogController implements LifecycleObserver { } mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId()); - mPhoneStateListener = getPhoneStateListener(); + mTelephonyCallback = new SimStatusDialogTelephonyCallback(); updateLatestAreaInfo(); updateSubscriptionStatus(); } @@ -278,11 +280,7 @@ public class SimStatusDialogController implements LifecycleObserver { } mTelephonyManager = mTelephonyManager.createForSubscriptionId( mSubscriptionInfo.getSubscriptionId()); - mTelephonyManager.listen(mPhoneStateListener, - PhoneStateListener.LISTEN_DATA_CONNECTION_STATE - | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS - | PhoneStateListener.LISTEN_SERVICE_STATE - | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED); + mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyCallback); mSubscriptionManager.addOnSubscriptionsChangedListener( mContext.getMainExecutor(), mOnSubscriptionsChangedListener); registerImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId()); @@ -305,7 +303,7 @@ public class SimStatusDialogController implements LifecycleObserver { if (mIsRegisteredListener) { mSubscriptionManager.removeOnSubscriptionsChangedListener( mOnSubscriptionsChangedListener); - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); if (mShowLatestAreaInfo) { mContext.unregisterReceiver(mAreaInfoReceiver); } @@ -316,7 +314,7 @@ public class SimStatusDialogController implements LifecycleObserver { unregisterImsRegistrationCallback(mSubscriptionInfo.getSubscriptionId()); mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); if (mShowLatestAreaInfo) { mContext.unregisterReceiver(mAreaInfoReceiver); @@ -768,33 +766,35 @@ public class SimStatusDialogController implements LifecycleObserver { } @VisibleForTesting - protected PhoneStateListener getPhoneStateListener() { - return new PhoneStateListener() { - @Override - public void onDataConnectionStateChanged(int state) { - updateDataState(state); - updateNetworkType(); - } + class SimStatusDialogTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.DataConnectionStateListener, + TelephonyCallback.SignalStrengthsListener, + TelephonyCallback.ServiceStateListener, + TelephonyCallback.DisplayInfoListener { + @Override + public void onDataConnectionStateChanged(int state, int networkType) { + updateDataState(state); + updateNetworkType(); + } - @Override - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - updateSignalStrength(signalStrength); - } + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + updateSignalStrength(signalStrength); + } - @Override - public void onServiceStateChanged(ServiceState serviceState) { - updateNetworkProvider(); - updateServiceState(serviceState); - updateRoamingStatus(serviceState); - mPreviousServiceState = serviceState; - } + @Override + public void onServiceStateChanged(ServiceState serviceState) { + updateNetworkProvider(); + updateServiceState(serviceState); + updateRoamingStatus(serviceState); + mPreviousServiceState = serviceState; + } - @Override - public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo displayInfo) { - mTelephonyDisplayInfo = displayInfo; - updateNetworkType(); - } - }; + @Override + public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo displayInfo) { + mTelephonyDisplayInfo = displayInfo; + updateNetworkType(); + } } @VisibleForTesting diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index e8d5f3330f2..399a84d7fea 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -23,7 +23,6 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.os.BatteryStats; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; @@ -33,9 +32,6 @@ import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; -import com.android.internal.os.BatterySipper; -import com.android.internal.os.BatteryStatsHelper; -import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; @@ -101,63 +97,46 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements private String mPackageName; - @VisibleForTesting - static void startBatteryDetailPage(Activity caller, BatteryUtils batteryUtils, - InstrumentedPreferenceFragment fragment, BatteryStatsHelper helper, int which, - BatteryEntry entry, String usagePercent) { - // Initialize mStats if necessary. - helper.getStats(); - + /** + * Launches battery details page for an individual battery consumer. + */ + public static void startBatteryDetailPage(Activity caller, + InstrumentedPreferenceFragment fragment, BatteryEntry entry, String usagePercent) { final Bundle args = new Bundle(); - final BatterySipper sipper = entry.sipper; - final BatteryStats.Uid uid = sipper.uidObj; - final boolean isTypeApp = sipper.drainType == BatterySipper.DrainType.APP; - - final long foregroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs( - BatteryUtils.StatusType.FOREGROUND, uid, which) : sipper.usageTimeMs; - final long backgroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs( - BatteryUtils.StatusType.BACKGROUND, uid, which) : 0; - - if (ArrayUtils.isEmpty(sipper.mPackages)) { + final long foregroundTimeMs = entry.getTimeInForegroundMs(); + final long backgroundTimeMs = entry.getTimeInBackgroundMs(); + final String packageName = entry.getDefaultPackageName(); + if (packageName == null) { // populate data for system app args.putString(EXTRA_LABEL, entry.getLabel()); args.putInt(EXTRA_ICON_ID, entry.iconId); args.putString(EXTRA_PACKAGE_NAME, null); } else { // populate data for normal app - args.putString(EXTRA_PACKAGE_NAME, entry.defaultPackageName != null - ? entry.defaultPackageName - : sipper.mPackages[0]); + args.putString(EXTRA_PACKAGE_NAME, packageName); } - args.putInt(EXTRA_UID, sipper.getUid()); + args.putInt(EXTRA_UID, entry.getUid()); args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs); args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs); args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent); - args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah); + args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) entry.getConsumedPower()); new SubSettingLauncher(caller) .setDestination(AdvancedPowerUsageDetail.class.getName()) .setTitleRes(R.string.battery_details_title) .setArguments(args) .setSourceMetricsCategory(fragment.getMetricsCategory()) - .setUserHandle(new UserHandle(getUserIdToLaunchAdvancePowerUsageDetail(sipper))) + .setUserHandle(new UserHandle(getUserIdToLaunchAdvancePowerUsageDetail(entry))) .launch(); } - private static @UserIdInt - int getUserIdToLaunchAdvancePowerUsageDetail(BatterySipper bs) { - if (bs.drainType == BatterySipper.DrainType.USER) { + private static @UserIdInt int getUserIdToLaunchAdvancePowerUsageDetail( + BatteryEntry batteryEntry) { + if (batteryEntry.isUserEntry()) { return ActivityManager.getCurrentUser(); } - return UserHandle.getUserId(bs.getUid()); - } - - public static void startBatteryDetailPage(Activity caller, - InstrumentedPreferenceFragment fragment, BatteryStatsHelper helper, int which, - BatteryEntry entry, String usagePercent) { - startBatteryDetailPage(caller, BatteryUtils.getInstance(caller), fragment, helper, which, - entry, usagePercent); + return UserHandle.getUserId(batteryEntry.getUid()); } public static void startBatteryDetailPage(Activity caller, diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java index 1a9db0352b8..47b2a0af649 100644 --- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java +++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java @@ -19,18 +19,22 @@ package com.android.settings.fuelgauge; import android.app.Activity; import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; -import android.os.BatteryStats; +import android.os.BatteryConsumer; +import android.os.BatteryUsageStats; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; +import android.os.SystemBatteryConsumer; +import android.os.UidBatteryConsumer; +import android.os.UserBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; -import android.util.Log; import android.util.SparseArray; import androidx.annotation.VisibleForTesting; @@ -38,9 +42,6 @@ import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceScreen; -import com.android.internal.os.BatterySipper; -import com.android.internal.os.BatterySipper.DrainType; -import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.PowerProfile; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -65,35 +66,57 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro static final boolean USE_FAKE_DATA = false; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 20; private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10; - private static final int STATS_TYPE = BatteryStats.STATS_SINCE_CHARGED; private final String mPreferenceKey; @VisibleForTesting PreferenceGroup mAppListGroup; - private BatteryStatsHelper mBatteryStatsHelper; + private BatteryUsageStats mBatteryUsageStats; private ArrayMap mPreferenceCache; @VisibleForTesting BatteryUtils mBatteryUtils; - private UserManager mUserManager; - private SettingsActivity mActivity; - private InstrumentedPreferenceFragment mFragment; + private final UserManager mUserManager; + private final PackageManager mPackageManager; + private final SettingsActivity mActivity; + private final InstrumentedPreferenceFragment mFragment; private Context mPrefContext; - private Handler mHandler = new Handler(Looper.getMainLooper()) { + /** + * Battery attribution list configuration. + */ + public interface Config { + /** + * Returns true if the attribution list should be shown. + */ + boolean shouldShowBatteryAttributionList(Context context); + } + + @VisibleForTesting + static Config sConfig = new Config() { + @Override + public boolean shouldShowBatteryAttributionList(Context context) { + if (USE_FAKE_DATA) { + return true; + } + + PowerProfile powerProfile = new PowerProfile(context); + return powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL) + >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP; + } + }; + + private final Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case BatteryEntry.MSG_UPDATE_NAME_ICON: BatteryEntry entry = (BatteryEntry) msg.obj; - PowerGaugePreference pgp = - (PowerGaugePreference) mAppListGroup.findPreference( - Integer.toString(entry.sipper.uidObj.getUid())); + PowerGaugePreference pgp = mAppListGroup.findPreference(entry.getKey()); if (pgp != null) { - final int userId = UserHandle.getUserId(entry.sipper.getUid()); + final int userId = UserHandle.getUserId(entry.getUid()); final UserHandle userHandle = new UserHandle(userId); pgp.setIcon(mUserManager.getBadgedIconForUser(entry.getIcon(), userHandle)); pgp.setTitle(entry.name); - if (entry.sipper.drainType == DrainType.APP) { + if (entry.isAppEntry()) { pgp.setContentDescription(entry.name); } } @@ -121,6 +144,7 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro mPreferenceKey = preferenceKey; mBatteryUtils = BatteryUtils.getInstance(context); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); + mPackageManager = context.getPackageManager(); mActivity = activity; mFragment = fragment; } @@ -160,78 +184,63 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro if (preference instanceof PowerGaugePreference) { PowerGaugePreference pgp = (PowerGaugePreference) preference; BatteryEntry entry = pgp.getInfo(); - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, - mFragment, mBatteryStatsHelper, STATS_TYPE, entry, pgp.getPercent()); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, + mFragment, entry, pgp.getPercent()); return true; } return false; } - public void refreshAppListGroup(BatteryStatsHelper statsHelper, boolean showAllApps) { + /** + * Refreshes the list of battery consumers using the supplied BatteryUsageStats. + */ + public void refreshAppListGroup(BatteryUsageStats batteryUsageStats, boolean showAllApps) { if (!isAvailable()) { return; } - mBatteryStatsHelper = statsHelper; + mBatteryUsageStats = USE_FAKE_DATA ? getFakeStats() : batteryUsageStats; mAppListGroup.setTitle(R.string.power_usage_list_summary); - final PowerProfile powerProfile = statsHelper.getPowerProfile(); - final BatteryStats stats = statsHelper.getStats(); - final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL); boolean addedSome = false; - final int dischargeAmount = USE_FAKE_DATA ? 5000 - : stats != null ? stats.getDischargeAmount(STATS_TYPE) : 0; cacheRemoveAllPrefs(mAppListGroup); mAppListGroup.setOrderingAsAdded(false); - if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) { - final List usageList = getCoalescedUsageList( - USE_FAKE_DATA ? getFakeStats() : statsHelper.getUsageList()); - double hiddenPowerMah = showAllApps ? 0 : - mBatteryUtils.removeHiddenBatterySippers(usageList); - mBatteryUtils.sortUsageList(usageList); - + if (sConfig.shouldShowBatteryAttributionList(mContext)) { + final int dischargePercentage = getDischargePercentage(batteryUsageStats); + final List usageList = getCoalescedUsageList(showAllApps); + final double totalPower = batteryUsageStats.getConsumedPower(); final int numSippers = usageList.size(); for (int i = 0; i < numSippers; i++) { - final BatterySipper sipper = usageList.get(i); - double totalPower = USE_FAKE_DATA ? 4000 : statsHelper.getTotalPower(); + final BatteryEntry entry = usageList.get(i); final double percentOfTotal = mBatteryUtils.calculateBatteryPercent( - sipper.totalPowerMah, totalPower, hiddenPowerMah, dischargeAmount); + entry.getConsumedPower(), totalPower, dischargePercentage); if (((int) (percentOfTotal + .5)) < 1) { continue; } - if (shouldHideSipper(sipper)) { - continue; - } - final UserHandle userHandle = new UserHandle(UserHandle.getUserId(sipper.getUid())); - final BatteryEntry entry = new BatteryEntry(mActivity, mHandler, mUserManager, - sipper, null); + + final UserHandle userHandle = new UserHandle(UserHandle.getUserId(entry.getUid())); final Drawable badgedIcon = mUserManager.getBadgedIconForUser(entry.getIcon(), userHandle); final CharSequence contentDescription = mUserManager.getBadgedLabelForUser( - entry.getLabel(), - userHandle); + entry.getLabel(), userHandle); - final String key = extractKeyFromSipper(sipper); + final String key = entry.getKey(); PowerGaugePreference pref = (PowerGaugePreference) getCachedPreference(key); if (pref == null) { pref = new PowerGaugePreference(mPrefContext, badgedIcon, contentDescription, entry); pref.setKey(key); } - sipper.percent = percentOfTotal; + entry.percent = percentOfTotal; pref.setTitle(entry.getLabel()); pref.setOrder(i + 1); pref.setPercent(percentOfTotal); pref.shouldShowAnomalyIcon(false); - if (sipper.usageTimeMs == 0 && sipper.drainType == DrainType.APP) { - sipper.usageTimeMs = mBatteryUtils.getProcessTimeMs( - BatteryUtils.StatusType.FOREGROUND, sipper.uidObj, STATS_TYPE); - } - setUsageSummary(pref, sipper); + setUsageSummary(pref, entry); addedSome = true; mAppListGroup.addPreference(pref); if (mAppListGroup.getPreferenceCount() - getCachedCount() @@ -248,6 +257,14 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro BatteryEntry.startRequestQueue(); } + private int getDischargePercentage(BatteryUsageStats batteryUsageStats) { + int dischargePercentage = batteryUsageStats.getDischargePercentage(); + if (dischargePercentage < 0) { + dischargePercentage = 0; + } + return dischargePercentage; + } + /** * We want to coalesce some UIDs. For example, dex2oat runs under a shared gid that * exists for all users of the same app. We detect this case and merge the power use @@ -255,129 +272,102 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro * * @return A sorted list of apps using power. */ - private List getCoalescedUsageList(final List sippers) { - final SparseArray uidList = new SparseArray<>(); + private List getCoalescedUsageList(boolean showAllApps) { + final SparseArray batteryEntryList = new SparseArray<>(); - final ArrayList results = new ArrayList<>(); - final int numSippers = sippers.size(); - for (int i = 0; i < numSippers; i++) { - BatterySipper sipper = sippers.get(i); - if (sipper.getUid() > 0) { - int realUid = sipper.getUid(); + final ArrayList results = new ArrayList<>(); + final List uidBatteryConsumers = + mBatteryUsageStats.getUidBatteryConsumers(); + for (int i = 0, size = uidBatteryConsumers.size(); i < size; i++) { + final UidBatteryConsumer consumer = uidBatteryConsumers.get(i); + int realUid = consumer.getUid(); - // Check if this UID is a shared GID. If so, we combine it with the OWNER's - // actual app UID. - if (isSharedGid(sipper.getUid())) { - realUid = UserHandle.getUid(UserHandle.USER_SYSTEM, - UserHandle.getAppIdFromSharedAppGid(sipper.getUid())); - } + // Check if this UID is a shared GID. If so, we combine it with the OWNER's + // actual app UID. + if (isSharedGid(consumer.getUid())) { + realUid = UserHandle.getUid(UserHandle.USER_SYSTEM, + UserHandle.getAppIdFromSharedAppGid(consumer.getUid())); + } - // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc). - if (isSystemUid(realUid) - && !"mediaserver".equals(sipper.packageWithHighestDrain)) { - // Use the system UID for all UIDs running in their own sandbox that - // are not apps. We exclude mediaserver because we already are expected to - // report that as a separate item. - realUid = Process.SYSTEM_UID; - } + // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc). + if (isSystemUid(realUid) + && !"mediaserver".equals(consumer.getPackageWithHighestDrain())) { + // Use the system UID for all UIDs running in their own sandbox that + // are not apps. We exclude mediaserver because we already are expected to + // report that as a separate item. + realUid = Process.SYSTEM_UID; + } - if (realUid != sipper.getUid()) { - // Replace the BatterySipper with a new one with the real UID set. - BatterySipper newSipper = new BatterySipper(sipper.drainType, - new FakeUid(realUid), 0.0); - newSipper.add(sipper); - newSipper.packageWithHighestDrain = sipper.packageWithHighestDrain; - newSipper.mPackages = sipper.mPackages; - sipper = newSipper; - } + final String[] packages = mPackageManager.getPackagesForUid(consumer.getUid()); + if (mBatteryUtils.shouldHideUidBatteryConsumerUnconditionally(consumer, packages)) { + continue; + } - int index = uidList.indexOfKey(realUid); - if (index < 0) { - // New entry. - uidList.put(realUid, sipper); - } else { - // Combine BatterySippers if we already have one with this UID. - final BatterySipper existingSipper = uidList.valueAt(index); - existingSipper.add(sipper); - if (existingSipper.packageWithHighestDrain == null - && sipper.packageWithHighestDrain != null) { - existingSipper.packageWithHighestDrain = sipper.packageWithHighestDrain; - } + final boolean isHidden = mBatteryUtils.shouldHideUidBatteryConsumer(consumer, packages); + if (isHidden && !showAllApps) { + continue; + } - final int existingPackageLen = existingSipper.mPackages != null ? - existingSipper.mPackages.length : 0; - final int newPackageLen = sipper.mPackages != null ? - sipper.mPackages.length : 0; - if (newPackageLen > 0) { - String[] newPackages = new String[existingPackageLen + newPackageLen]; - if (existingPackageLen > 0) { - System.arraycopy(existingSipper.mPackages, 0, newPackages, 0, - existingPackageLen); - } - System.arraycopy(sipper.mPackages, 0, newPackages, existingPackageLen, - newPackageLen); - existingSipper.mPackages = newPackages; - } - } + final int index = batteryEntryList.indexOfKey(realUid); + if (index < 0) { + // New entry. + batteryEntryList.put(realUid, new BatteryEntry(mActivity, mHandler, mUserManager, + consumer, isHidden, packages, null)); } else { - results.add(sipper); + // Combine BatterySippers if we already have one with this UID. + final BatteryEntry existingSipper = batteryEntryList.valueAt(index); + existingSipper.add(consumer); } } - final int numUidSippers = uidList.size(); + final List systemBatteryConsumers = + mBatteryUsageStats.getSystemBatteryConsumers(); + for (int i = 0, size = systemBatteryConsumers.size(); i < size; i++) { + final SystemBatteryConsumer consumer = systemBatteryConsumers.get(i); + if (!showAllApps && mBatteryUtils.shouldHideSystemBatteryConsumer(consumer)) { + continue; + } + + results.add(new BatteryEntry(mActivity, mHandler, mUserManager, + consumer, /* isHidden */ true, null, null)); + } + + if (showAllApps) { + final List userBatteryConsumers = + mBatteryUsageStats.getUserBatteryConsumers(); + for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) { + final UserBatteryConsumer consumer = userBatteryConsumers.get(i); + results.add(new BatteryEntry(mActivity, mHandler, mUserManager, + consumer, /* isHidden */ true, null, null)); + } + } + + final int numUidSippers = batteryEntryList.size(); + for (int i = 0; i < numUidSippers; i++) { - results.add(uidList.valueAt(i)); + results.add(batteryEntryList.valueAt(i)); } // The sort order must have changed, so re-sort based on total power use. - mBatteryUtils.sortUsageList(results); + results.sort(BatteryEntry.COMPARATOR); return results; } @VisibleForTesting - void setUsageSummary(Preference preference, BatterySipper sipper) { + void setUsageSummary(Preference preference, BatteryEntry entry) { // Only show summary when usage time is longer than one minute - final long usageTimeMs = sipper.usageTimeMs; - if (shouldShowSummary(sipper) && usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) { + final long usageTimeMs = entry.getTimeInForegroundMs(); + if (shouldShowSummary(entry) && usageTimeMs >= DateUtils.MINUTE_IN_MILLIS) { final CharSequence timeSequence = StringUtil.formatElapsedTime(mContext, usageTimeMs, false); preference.setSummary( - (sipper.drainType != DrainType.APP || mBatteryUtils.shouldHideSipper(sipper)) + entry.isHidden() ? timeSequence : TextUtils.expandTemplate(mContext.getText(R.string.battery_used_for), timeSequence)); } } - @VisibleForTesting - boolean shouldHideSipper(BatterySipper sipper) { - // Don't show over-counted, unaccounted and hidden system module in any condition - return sipper.drainType == BatterySipper.DrainType.OVERCOUNTED - || sipper.drainType == BatterySipper.DrainType.UNACCOUNTED - || mBatteryUtils.isHiddenSystemModule(sipper) || sipper.getUid() < 0; - } - - @VisibleForTesting - String extractKeyFromSipper(BatterySipper sipper) { - if (sipper.uidObj != null) { - return extractKeyFromUid(sipper.getUid()); - } else if (sipper.drainType == DrainType.USER) { - return sipper.drainType.toString() + sipper.userId; - } else if (sipper.drainType != DrainType.APP) { - return sipper.drainType.toString(); - } else if (sipper.getPackages() != null) { - return TextUtils.concat(sipper.getPackages()).toString(); - } else { - Log.w(TAG, "Inappropriate BatterySipper without uid and package names: " + sipper); - return "-1"; - } - } - - @VisibleForTesting - String extractKeyFromUid(int uid) { - return Integer.toString(uid); - } - private void cacheRemoveAllPrefs(PreferenceGroup group) { mPreferenceCache = new ArrayMap<>(); final int N = group.getPreferenceCount(); @@ -390,12 +380,12 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro } } - private boolean shouldShowSummary(BatterySipper sipper) { + private boolean shouldShowSummary(BatteryEntry entry) { final CharSequence[] allowlistPackages = mContext.getResources() .getTextArray(R.array.allowlist_hide_summary_in_battery_usage); - final String target = sipper.packageWithHighestDrain; + final String target = entry.getDefaultPackageName(); - for (CharSequence packageName: allowlistPackages) { + for (CharSequence packageName : allowlistPackages) { if (TextUtils.equals(target, packageName)) { return false; } @@ -412,39 +402,54 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro return appUid >= Process.SYSTEM_UID && appUid < Process.FIRST_APPLICATION_UID; } - private static List getFakeStats() { - ArrayList stats = new ArrayList<>(); - float use = 5; - for (DrainType type : DrainType.values()) { - if (type == DrainType.APP) { - continue; - } - stats.add(new BatterySipper(type, null, use)); + private BatteryUsageStats getFakeStats() { + BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(0, 0) + .setDischargePercentage(100); + + float use = 500; + for (@SystemBatteryConsumer.DrainType int drainType : new int[]{ + SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY, + SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH, + SystemBatteryConsumer.DRAIN_TYPE_CAMERA, + SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT, + SystemBatteryConsumer.DRAIN_TYPE_IDLE, + SystemBatteryConsumer.DRAIN_TYPE_MEMORY, + SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO, + SystemBatteryConsumer.DRAIN_TYPE_PHONE, + SystemBatteryConsumer.DRAIN_TYPE_SCREEN, + SystemBatteryConsumer.DRAIN_TYPE_WIFI, + }) { + builder.getOrCreateSystemBatteryConsumerBuilder(drainType) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, use); use += 5; } + + use = 450; for (int i = 0; i < 100; i++) { - stats.add(new BatterySipper(DrainType.APP, - new FakeUid(Process.FIRST_APPLICATION_UID + i), use)); + builder.getOrCreateUidBatteryConsumerBuilder( + new FakeUid(Process.FIRST_APPLICATION_UID + i)) + .setTimeInStateMs(BatteryConsumer.TIME_COMPONENT_USAGE, 10000 + i * 1000) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, use); + use += 1; } - stats.add(new BatterySipper(DrainType.APP, - new FakeUid(0), use)); // Simulate dex2oat process. - BatterySipper sipper = new BatterySipper(DrainType.APP, - new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID)), 10.0f); - sipper.packageWithHighestDrain = "dex2oat"; - stats.add(sipper); + builder.getOrCreateUidBatteryConsumerBuilder(new FakeUid(Process.FIRST_APPLICATION_UID)) + .setTimeInStateMs(BatteryConsumer.TIME_COMPONENT_USAGE, 100000) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, 1000.0) + .setPackageWithHighestDrain("dex2oat"); - sipper = new BatterySipper(DrainType.APP, - new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID + 1)), 10.0f); - sipper.packageWithHighestDrain = "dex2oat"; - stats.add(sipper); + builder.getOrCreateUidBatteryConsumerBuilder(new FakeUid(Process.FIRST_APPLICATION_UID + 1)) + .setTimeInStateMs(BatteryConsumer.TIME_COMPONENT_USAGE, 100000) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, 1000.0) + .setPackageWithHighestDrain("dex2oat"); - sipper = new BatterySipper(DrainType.APP, - new FakeUid(UserHandle.getSharedAppGid(Process.LOG_UID)), 9.0f); - stats.add(sipper); + builder.getOrCreateUidBatteryConsumerBuilder( + new FakeUid(UserHandle.getSharedAppGid(Process.LOG_UID))) + .setTimeInStateMs(BatteryConsumer.TIME_COMPONENT_USAGE, 100000) + .setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, 900.0); - return stats; + return builder.build(); } private Preference getCachedPreference(String key) { diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java index d533c80ceec..9fafefd154b 100644 --- a/src/com/android/settings/fuelgauge/BatteryEntry.java +++ b/src/com/android/settings/fuelgauge/BatteryEntry.java @@ -25,19 +25,24 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; +import android.os.BatteryConsumer; import android.os.Handler; import android.os.Process; import android.os.RemoteException; +import android.os.SystemBatteryConsumer; import android.os.UidBatteryConsumer; +import android.os.UserBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; -import com.android.internal.os.BatterySipper; +import androidx.annotation.NonNull; + import com.android.settings.R; import com.android.settingslib.Utils; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.Locale; @@ -52,9 +57,9 @@ public class BatteryEntry { private static final String TAG = "BatteryEntry"; private static final String PACKAGE_SYSTEM = "android"; - static final HashMap sUidCache = new HashMap(); + static final HashMap sUidCache = new HashMap<>(); - static final ArrayList mRequestQueue = new ArrayList(); + static final ArrayList sRequestQueue = new ArrayList(); static Handler sHandler; static Locale sCurrentLocale = null; @@ -74,15 +79,14 @@ public class BatteryEntry { public void run() { while (true) { BatteryEntry be; - synchronized (mRequestQueue) { - if (mRequestQueue.isEmpty() || mAbort) { + synchronized (sRequestQueue) { + if (sRequestQueue.isEmpty() || mAbort) { if (sHandler != null) { sHandler.sendEmptyMessage(MSG_REPORT_FULLY_DRAWN); } - mRequestQueue.clear(); return; } - be = mRequestQueue.remove(0); + be = sRequestQueue.remove(0); } be.loadNameAndIcon(); } @@ -93,25 +97,26 @@ public class BatteryEntry { public static void startRequestQueue() { if (sHandler != null) { - synchronized (mRequestQueue) { - if (!mRequestQueue.isEmpty()) { + synchronized (sRequestQueue) { + if (!sRequestQueue.isEmpty()) { if (mRequestThread != null) { mRequestThread.abort(); } mRequestThread = new NameAndIconLoader(); mRequestThread.setPriority(Thread.MIN_PRIORITY); mRequestThread.start(); - mRequestQueue.notify(); + sRequestQueue.notify(); } } } } public static void stopRequestQueue() { - synchronized (mRequestQueue) { + synchronized (sRequestQueue) { if (mRequestThread != null) { mRequestThread.abort(); mRequestThread = null; + sRequestQueue.clear(); sHandler = null; } } @@ -121,14 +126,19 @@ public class BatteryEntry { sUidCache.clear(); } - public final Context context; - public final BatterySipper sipper; - public final UidBatteryConsumer uidBatteryConsumer; + public static final Comparator COMPARATOR = + (a, b) -> Double.compare(b.getConsumedPower(), a.getConsumedPower()); + + private final Context mContext; + private final BatteryConsumer mBatteryConsumer; + private final boolean mIsHidden; public String name; public Drawable icon; public int iconId; // For passing to the detail screen. - public String defaultPackageName; + public double percent; + private String mDefaultPackageName; + private double mConsumedPower; static class UidToDetail { String name; @@ -136,123 +146,100 @@ public class BatteryEntry { Drawable icon; } - public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper, - UidBatteryConsumer uidBatteryConsumer) { + public BatteryEntry(Context context, Handler handler, UserManager um, + @NonNull BatteryConsumer batteryConsumer, boolean isHidden, String[] packages, + String packageName) { sHandler = handler; - this.context = context; - this.sipper = sipper; - this.uidBatteryConsumer = uidBatteryConsumer; + mContext = context; + mBatteryConsumer = batteryConsumer; + mIsHidden = isHidden; + mDefaultPackageName = packageName; + mConsumedPower = batteryConsumer.getConsumedPower(); - // 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(); + if (batteryConsumer instanceof UidBatteryConsumer) { + UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer; 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]; + if (mDefaultPackageName == null) { + // Apps should only have one package + if (packages != null && packages.length == 1) { + mDefaultPackageName = packages[0]; + } else { + mDefaultPackageName = uidBatteryConsumer.getPackageWithHighestDrain(); + } + } + if (mDefaultPackageName != null) { + PackageManager pm = context.getPackageManager(); try { ApplicationInfo appInfo = - pm.getApplicationInfo(defaultPackageName, 0 /* no flags */); + pm.getApplicationInfo(mDefaultPackageName, 0 /* no flags */); name = pm.getApplicationLabel(appInfo).toString(); } catch (NameNotFoundException e) { Log.d(TAG, "PackageManager failed to retrieve ApplicationInfo for: " - + defaultPackageName); - name = defaultPackageName; + + mDefaultPackageName); + name = mDefaultPackageName; } } - if ((name == null || iconId == 0) && uid != 0) { - getQuickNameIconForUid(uid); - } + getQuickNameIconForUid(uid, packages); return; + } else if (batteryConsumer instanceof SystemBatteryConsumer) { + switch(((SystemBatteryConsumer) batteryConsumer).getDrainType()) { + case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY: + name = context.getResources().getString(R.string.ambient_display_screen_title); + iconId = R.drawable.ic_settings_aod; + break; + case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH: + name = context.getResources().getString(R.string.power_bluetooth); + iconId = com.android.internal.R.drawable.ic_settings_bluetooth; + break; + case SystemBatteryConsumer.DRAIN_TYPE_CAMERA: + name = context.getResources().getString(R.string.power_camera); + iconId = R.drawable.ic_settings_camera; + break; + case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO: + name = context.getResources().getString(R.string.power_cell); + iconId = R.drawable.ic_cellular_1_bar; + break; + case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT: + name = context.getResources().getString(R.string.power_flashlight); + iconId = R.drawable.ic_settings_display; + break; + case SystemBatteryConsumer.DRAIN_TYPE_PHONE: + name = context.getResources().getString(R.string.power_phone); + iconId = R.drawable.ic_settings_voice_calls; + break; + case SystemBatteryConsumer.DRAIN_TYPE_SCREEN: + name = context.getResources().getString(R.string.power_screen); + iconId = R.drawable.ic_settings_display; + break; + case SystemBatteryConsumer.DRAIN_TYPE_WIFI: + name = context.getResources().getString(R.string.power_wifi); + iconId = R.drawable.ic_settings_wireless; + break; + case SystemBatteryConsumer.DRAIN_TYPE_IDLE: + case SystemBatteryConsumer.DRAIN_TYPE_MEMORY: + name = context.getResources().getString(R.string.power_idle); + iconId = R.drawable.ic_settings_phone_idle; + break; + case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM: + name = null; + iconId = R.drawable.ic_power_system; + break; + } + } else if (batteryConsumer instanceof UserBatteryConsumer) { + UserInfo info = um.getUserInfo(((UserBatteryConsumer) batteryConsumer).getUserId()); + if (info != null) { + icon = Utils.getUserIcon(context, um, info); + name = Utils.getUserLabel(context, info); + } else { + icon = null; + name = context.getResources().getString( + R.string.running_process_item_removed_user_label); + } } - switch (sipper.drainType) { - case IDLE: - name = context.getResources().getString(R.string.power_idle); - iconId = R.drawable.ic_settings_phone_idle; - break; - case CELL: - name = context.getResources().getString(R.string.power_cell); - iconId = R.drawable.ic_cellular_1_bar; - break; - case PHONE: - name = context.getResources().getString(R.string.power_phone); - iconId = R.drawable.ic_settings_voice_calls; - break; - case WIFI: - name = context.getResources().getString(R.string.power_wifi); - iconId = R.drawable.ic_settings_wireless; - break; - case BLUETOOTH: - name = context.getResources().getString(R.string.power_bluetooth); - iconId = com.android.internal.R.drawable.ic_settings_bluetooth; - break; - case SCREEN: - name = context.getResources().getString(R.string.power_screen); - iconId = R.drawable.ic_settings_display; - break; - case FLASHLIGHT: - name = context.getResources().getString(R.string.power_flashlight); - iconId = R.drawable.ic_settings_display; - break; - case APP: - PackageManager pm = context.getPackageManager(); - sipper.mPackages = pm.getPackagesForUid(sipper.uidObj.getUid()); - // Apps should only have one package - if (sipper.mPackages == null || sipper.mPackages.length != 1) { - name = sipper.packageWithHighestDrain; - } else { - defaultPackageName = pm.getPackagesForUid(sipper.uidObj.getUid())[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; - } - } - break; - case USER: { - UserInfo info = um.getUserInfo(sipper.userId); - if (info != null) { - icon = Utils.getUserIcon(context, um, info); - name = Utils.getUserLabel(context, info); - } else { - icon = null; - name = context.getResources().getString( - R.string.running_process_item_removed_user_label); - } - } break; - case UNACCOUNTED: - name = context.getResources().getString(R.string.power_unaccounted); - iconId = R.drawable.ic_android; - break; - case OVERCOUNTED: - name = context.getResources().getString(R.string.power_overcounted); - iconId = R.drawable.ic_android; - break; - case CAMERA: - name = context.getResources().getString(R.string.power_camera); - iconId = R.drawable.ic_settings_camera; - break; - case AMBIENT_DISPLAY: - name = context.getResources().getString(R.string.ambient_display_screen_title); - iconId = R.drawable.ic_settings_aod; - break; - } - if (iconId > 0) { + if (iconId != 0) { icon = context.getDrawable(iconId); } - if ((name == null || iconId == 0) && this.sipper.uidObj != null) { - getQuickNameIconForUid(this.sipper.uidObj.getUid()); - } } public Drawable getIcon() { @@ -266,7 +253,7 @@ public class BatteryEntry { return name; } - void getQuickNameIconForUid(final int uid) { + void getQuickNameIconForUid(final int uid, final String[] packages) { // Locale sync to system config in Settings final Locale locale = Locale.getDefault(); if (sCurrentLocale != locale) { @@ -277,28 +264,29 @@ public class BatteryEntry { final String uidString = Integer.toString(uid); if (sUidCache.containsKey(uidString)) { UidToDetail utd = sUidCache.get(uidString); - defaultPackageName = utd.packageName; + mDefaultPackageName = utd.packageName; name = utd.name; icon = utd.icon; return; } - PackageManager pm = context.getPackageManager(); - icon = pm.getDefaultActivityIcon(); - if (pm.getPackagesForUid(uid) == null) { + + if (packages == null || packages.length == 0) { if (uid == 0) { - name = context.getResources().getString(R.string.process_kernel_label); + name = mContext.getResources().getString(R.string.process_kernel_label); } else if ("mediaserver".equals(name)) { - name = context.getResources().getString(R.string.process_mediaserver_label); + name = mContext.getResources().getString(R.string.process_mediaserver_label); } else if ("dex2oat".equals(name)) { - name = context.getResources().getString(R.string.process_dex2oat_label); + name = mContext.getResources().getString(R.string.process_dex2oat_label); } iconId = R.drawable.ic_power_system; - icon = context.getDrawable(iconId); + icon = mContext.getDrawable(iconId); + } else { + icon = mContext.getPackageManager().getDefaultActivityIcon(); } if (sHandler != null) { - synchronized (mRequestQueue) { - mRequestQueue.add(this); + synchronized (sRequestQueue) { + sRequestQueue.add(this); } } } @@ -308,17 +296,19 @@ public class BatteryEntry { */ public void loadNameAndIcon() { // Bail out if the current sipper is not an App sipper. - if (sipper.uidObj == null) { + final int uid = getUid(); + if (uid == 0 || uid == Process.INVALID_UID) { return; } - PackageManager pm = context.getPackageManager(); - final int uid = sipper.uidObj.getUid(); - if (sipper.mPackages == null) { - sipper.mPackages = pm.getPackagesForUid(uid); + final PackageManager pm = mContext.getPackageManager(); + final String[] packages; + if (uid == Process.SYSTEM_UID) { + packages = new String[]{PACKAGE_SYSTEM}; + } else { + packages = pm.getPackagesForUid(uid); } - final String[] packages = extractPackagesFromSipper(sipper); if (packages != null) { String[] packageLabels = new String[packages.length]; System.arraycopy(packages, 0, packageLabels, 0, packages.length); @@ -340,7 +330,7 @@ public class BatteryEntry { packageLabels[i] = label.toString(); } if (ai.icon != 0) { - defaultPackageName = packages[i]; + mDefaultPackageName = packages[i]; icon = ai.loadIcon(pm); break; } @@ -368,7 +358,7 @@ public class BatteryEntry { if (nm != null) { name = nm.toString(); if (pi.applicationInfo.icon != 0) { - defaultPackageName = pkgName; + mDefaultPackageName = pkgName; icon = pi.applicationInfo.loadIcon(pm); } break; @@ -394,17 +384,113 @@ public class BatteryEntry { UidToDetail utd = new UidToDetail(); utd.name = name; utd.icon = icon; - utd.packageName = defaultPackageName; + utd.packageName = mDefaultPackageName; + sUidCache.put(uidString, utd); if (sHandler != null) { sHandler.sendMessage(sHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this)); } } - String[] extractPackagesFromSipper(BatterySipper sipper) { - // Only use system package if uid is system uid, so it could find a consistent name and icon - return sipper.getUid() == Process.SYSTEM_UID - ? new String[]{PACKAGE_SYSTEM} - : sipper.mPackages; + /** + * Returns a string that uniquely identifies this battery consumer. + */ + public String getKey() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return Integer.toString(((UidBatteryConsumer) mBatteryConsumer).getUid()); + } else if (mBatteryConsumer instanceof SystemBatteryConsumer) { + return "S|" + ((SystemBatteryConsumer) mBatteryConsumer).getDrainType(); + } else if (mBatteryConsumer instanceof UserBatteryConsumer) { + return "U|" + ((UserBatteryConsumer) mBatteryConsumer).getUserId(); + } else { + Log.w(TAG, "Unsupported BatteryConsumer: " + mBatteryConsumer); + return ""; + } + } + + /** + * Returns true if the entry is hidden from the battery usage summary list. + */ + public boolean isHidden() { + return mIsHidden; + } + + /** + * Returns true if this entry describes an app (UID) + */ + public boolean isAppEntry() { + return mBatteryConsumer instanceof UidBatteryConsumer; + } + + /** + * Returns true if this entry describes a User. + */ + public boolean isUserEntry() { + if (mBatteryConsumer instanceof UserBatteryConsumer) { + return true; + } + return false; + } + + /** + * Returns the package name that should be used to represent the UID described + * by this entry. + */ + public String getDefaultPackageName() { + return mDefaultPackageName; + } + + /** + * Returns the UID of the app described by this entry. + */ + public int getUid() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getUid(); + } else { + return Process.INVALID_UID; + } + } + + /** + * Returns foreground foreground time (in milliseconds) that is attributed to this entry. + */ + public long getTimeInForegroundMs() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs( + UidBatteryConsumer.STATE_FOREGROUND); + } else { + return mBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE); + } + } + + /** + * Returns background activity time (in milliseconds) that is attributed to this entry. + */ + public long getTimeInBackgroundMs() { + if (mBatteryConsumer instanceof UidBatteryConsumer) { + return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs( + UidBatteryConsumer.STATE_BACKGROUND); + } else { + return 0; + } + } + + /** + * Returns total amount of power (in milli-amp-hours) that is attributed to this entry. + */ + public double getConsumedPower() { + return mConsumedPower; + } + + /** + * Adds the consumed power of the supplied BatteryConsumer to this entry. Also + * uses its package with highest drain, if necessary. + */ + public void add(BatteryConsumer batteryConsumer) { + mConsumedPower += batteryConsumer.getConsumedPower(); + if (mDefaultPackageName == null && batteryConsumer instanceof UidBatteryConsumer) { + mDefaultPackageName = + ((UidBatteryConsumer) batteryConsumer).getPackageWithHighestDrain(); + } } } diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java index 8c0ab46a347..d3633b1b92e 100644 --- a/src/com/android/settings/fuelgauge/BatteryUtils.java +++ b/src/com/android/settings/fuelgauge/BatteryUtils.java @@ -30,12 +30,12 @@ import android.os.BatteryUsageStatsQuery; import android.os.Build; import android.os.Bundle; import android.os.Process; +import android.os.SystemBatteryConsumer; import android.os.SystemClock; +import android.os.UidBatteryConsumer; import android.os.UserHandle; import android.os.UserManager; -import android.text.format.DateUtils; import android.util.Log; -import android.util.SparseLongArray; import androidx.annotation.IntDef; import androidx.annotation.Nullable; @@ -61,8 +61,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; import java.time.Instant; -import java.util.Collections; -import java.util.Comparator; import java.util.List; /** @@ -88,6 +86,7 @@ public class BatteryUtils { private static final String TAG = "BatteryUtils"; private static final int MIN_POWER_THRESHOLD_MILLI_AMP = 5; + private static final double MIN_POWER_THRESHOLD_MILLI_AMP_HOURS = 0.002; private static final int SECONDS_IN_HOUR = 60 * 60; private static BatteryUtils sInstance; @@ -173,77 +172,6 @@ public class BatteryUtils { + PowerUtil.convertUsToMs(getForegroundServiceTotalTimeUs(uid, rawRealTimeUs)); } - /** - * Remove the {@link BatterySipper} that we should hide and smear the screen usage based on - * foreground activity time. - * - * @param sippers sipper list that need to check and remove - * @return the total power of the hidden items of {@link BatterySipper} - * for proportional smearing - */ - public double removeHiddenBatterySippers(List sippers) { - double proportionalSmearPowerMah = 0; - BatterySipper screenSipper = null; - for (int i = sippers.size() - 1; i >= 0; i--) { - final BatterySipper sipper = sippers.get(i); - if (shouldHideSipper(sipper)) { - sippers.remove(i); - if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED - && sipper.drainType != BatterySipper.DrainType.SCREEN - && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED - && sipper.drainType != BatterySipper.DrainType.BLUETOOTH - && sipper.drainType != BatterySipper.DrainType.WIFI - && sipper.drainType != BatterySipper.DrainType.IDLE - && !isHiddenSystemModule(sipper)) { - // Don't add it if it is overcounted, unaccounted, wifi, bluetooth, screen - // or hidden system modules - proportionalSmearPowerMah += sipper.totalPowerMah; - } - } - - if (sipper.drainType == BatterySipper.DrainType.SCREEN) { - screenSipper = sipper; - } - } - - smearScreenBatterySipper(sippers, screenSipper); - - return proportionalSmearPowerMah; - } - - /** - * Smear the screen on power usage among {@code sippers}, based on ratio of foreground activity - * time. - */ - @VisibleForTesting - void smearScreenBatterySipper(List sippers, BatterySipper screenSipper) { - long totalActivityTimeMs = 0; - final SparseLongArray activityTimeArray = new SparseLongArray(); - for (int i = 0, size = sippers.size(); i < size; i++) { - final BatteryStats.Uid uid = sippers.get(i).uidObj; - if (uid != null) { - final long timeMs = getProcessTimeMs(StatusType.SCREEN_USAGE, uid, - BatteryStats.STATS_SINCE_CHARGED); - activityTimeArray.put(uid.getUid(), timeMs); - totalActivityTimeMs += timeMs; - } - } - - if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) { - if (screenSipper == null) { - Log.e(TAG, "screen sipper is null even when app screen time is not zero"); - return; - } - - final double screenPowerMah = screenSipper.totalPowerMah; - for (int i = 0, size = sippers.size(); i < size; i++) { - final BatterySipper sipper = sippers.get(i); - sipper.totalPowerMah += screenPowerMah * activityTimeArray.get(sipper.getUid(), 0) - / totalActivityTimeMs; - } - } - } - /** * Check whether we should hide the battery sipper. */ @@ -263,6 +191,42 @@ public class BatteryUtils { || isHiddenSystemModule(sipper); } + /** + * Returns true if the specified battery consumer should be excluded from the summary + * battery consumption list. + */ + public boolean shouldHideUidBatteryConsumer(UidBatteryConsumer consumer, String[] packages) { + return consumer.getConsumedPower() < MIN_POWER_THRESHOLD_MILLI_AMP_HOURS + || mPowerUsageFeatureProvider.isTypeSystem(consumer.getUid(), packages) + || shouldHideUidBatteryConsumerUnconditionally(consumer, packages); + } + + /** + * Returns true if the specified battery consumer should be excluded from + * battery consumption lists, either short or full. + */ + boolean shouldHideUidBatteryConsumerUnconditionally(UidBatteryConsumer consumer, + String[] packages) { + return consumer.getUid() < 0 || isHiddenSystemModule(packages); + } + + /** + * Returns true if the specified battery consumer should be excluded from the summary + * battery consumption list. + */ + public boolean shouldHideSystemBatteryConsumer(SystemBatteryConsumer consumer) { + switch (consumer.getDrainType()) { + case SystemBatteryConsumer.DRAIN_TYPE_IDLE: + case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO: + case SystemBatteryConsumer.DRAIN_TYPE_SCREEN: + case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH: + case SystemBatteryConsumer.DRAIN_TYPE_WIFI: + return true; + default: + return consumer.getConsumedPower() < MIN_POWER_THRESHOLD_MILLI_AMP_HOURS; + } + } + /** * Return {@code true} if one of packages in {@code sipper} is hidden system modules */ @@ -271,14 +235,20 @@ public class BatteryUtils { return false; } sipper.mPackages = mPackageManager.getPackagesForUid(sipper.getUid()); - if (sipper.mPackages != null) { - for (int i = 0, length = sipper.mPackages.length; i < length; i++) { - if (AppUtils.isHiddenSystemModule(mContext, sipper.mPackages[i])) { + return isHiddenSystemModule(sipper.mPackages); + } + + /** + * Returns true if one the specified packages belongs to a hidden system module. + */ + public boolean isHiddenSystemModule(String[] packages) { + if (packages != null) { + for (int i = 0, length = packages.length; i < length; i++) { + if (AppUtils.isHiddenSystemModule(mContext, packages[i])) { return true; } } } - return false; } @@ -287,19 +257,17 @@ public class BatteryUtils { * * @param powerUsageMah power used by the app * @param totalPowerMah total power used in the system - * @param hiddenPowerMah power used by no-actionable app that we want to hide, i.e. Screen, - * Android OS. * @param dischargeAmount The discharge amount calculated by {@link BatteryStats} * @return A percentage value scaled by {@paramref dischargeAmount} * @see BatteryStats#getDischargeAmount(int) */ public double calculateBatteryPercent(double powerUsageMah, double totalPowerMah, - double hiddenPowerMah, int dischargeAmount) { + int dischargeAmount) { if (totalPowerMah == 0) { return 0; } - return (powerUsageMah / (totalPowerMah - hiddenPowerMah)) * dischargeAmount; + return (powerUsageMah / totalPowerMah) * dischargeAmount; } /** @@ -365,18 +333,6 @@ public class BatteryUtils { return mode == AppOpsManager.MODE_IGNORED || mode == AppOpsManager.MODE_ERRORED; } - /** - * Sort the {@code usageList} based on {@link BatterySipper#totalPowerMah} - */ - public void sortUsageList(List usageList) { - Collections.sort(usageList, new Comparator() { - @Override - public int compare(BatterySipper a, BatterySipper b) { - return Double.compare(b.totalPowerMah, a.totalPowerMah); - } - }); - } - /** * Calculate the time since last full charge, including the device off time * @@ -390,18 +346,6 @@ public class BatteryUtils { } - /** - * Calculate the screen usage time since last full charge. - * - * @param batteryStatsHelper utility class that contains the screen usage data - * @return time in millis - */ - public long calculateScreenUsageTime(BatteryStatsHelper batteryStatsHelper) { - final BatterySipper sipper = findBatterySipperByType( - batteryStatsHelper.getUsageList(), BatterySipper.DrainType.SCREEN); - return sipper != null ? sipper.usageTimeMs : 0; - } - public static void logRuntime(String tag, String message, long startTime) { Log.d(tag, message + ": " + (System.currentTimeMillis() - startTime) + "ms"); } @@ -526,20 +470,6 @@ public class BatteryUtils { return estimate; } - /** - * Find the {@link BatterySipper} with the corresponding {@link BatterySipper.DrainType} - */ - public BatterySipper findBatterySipperByType(List usageList, - BatterySipper.DrainType type) { - for (int i = 0, size = usageList.size(); i < size; i++) { - final BatterySipper sipper = usageList.get(i); - if (sipper.drainType == type) { - return sipper; - } - } - return null; - } - private boolean isDataCorrupted() { return mPackageManager == null || mAppOpsManager == null; } @@ -674,4 +604,3 @@ public class BatteryUtils { return -1L; } } - diff --git a/src/com/android/settings/fuelgauge/FakeUid.java b/src/com/android/settings/fuelgauge/FakeUid.java index 4bb98ed5f8c..b49fb107dc2 100644 --- a/src/com/android/settings/fuelgauge/FakeUid.java +++ b/src/com/android/settings/fuelgauge/FakeUid.java @@ -356,7 +356,7 @@ public class FakeUid extends Uid { } @Override - public long getScreenOnMeasuredBatteryConsumptionUC() { + public long getBluetoothMeasuredBatteryConsumptionUC() { return 0; } @@ -365,6 +365,16 @@ public class FakeUid extends Uid { return 0; } + @Override + public long getScreenOnMeasuredBatteryConsumptionUC() { + return 0; + } + + @Override + public long getWifiMeasuredBatteryConsumptionUC() { + return 0; + } + @Override public long[] getCustomConsumerMeasuredBatteryConsumptionUC() { return null; diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index 86e52d9555f..9279e5d3ad6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -50,7 +50,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { @VisibleForTesting BatteryHistoryPreference mHistPref; - private BatteryUtils mBatteryUtils; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; private BatteryAppListPreferenceController mBatteryAppListPreferenceController; @VisibleForTesting @@ -64,7 +63,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { mHistPref = (BatteryHistoryPreference) findPreference(KEY_BATTERY_GRAPH); mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) .getPowerUsageFeatureProvider(context); - mBatteryUtils = BatteryUtils.getInstance(context); // init the summary so other preferences won't have unnecessary move updateHistPrefSummary(context); @@ -155,7 +153,7 @@ public class PowerUsageAdvanced extends PowerUsageBase { updatePreference(mHistPref); updateHistPrefSummary(context); - mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper, mShowAllApps); + mBatteryAppListPreferenceController.refreshAppListGroup(mBatteryUsageStats, mShowAllApps); } private void updateHistPrefSummary(Context context) { diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java index 4f292dddacc..6a22ed4691a 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java +++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProvider.java @@ -58,6 +58,11 @@ public interface PowerUsageFeatureProvider { */ boolean isTypeSystem(BatterySipper sipper); + /** + * Check whether it is type system + */ + boolean isTypeSystem(int uid, String[] packages); + /** * Check whether the toggle for power accounting is enabled */ diff --git a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java index ab71c97e141..cb83d80cee6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java +++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java @@ -65,6 +65,21 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider return false; } + @Override + public boolean isTypeSystem(int uid, String[] packages) { + // Classify all the sippers to type system if the range of uid is 0...FIRST_APPLICATION_UID + if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) { + return true; + } else if (packages != null) { + for (final String packageName : packages) { + if (ArrayUtils.contains(PACKAGES_SYSTEM, packageName)) { + return true; + } + } + } + return false; + } + @Override public boolean isLocationSettingEnabled(String[] packages) { return false; diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java index 928ae52532c..6c102fb5d4d 100644 --- a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java +++ b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java @@ -86,7 +86,7 @@ public class HighUsageDetector implements BatteryTipDetector { sipper1.totalSmearedPowerMah)); for (BatterySipper batterySipper : batterySippers) { final double percent = mBatteryUtils.calculateBatteryPercent( - batterySipper.totalSmearedPowerMah, totalPower, 0, dischargeAmount); + batterySipper.totalSmearedPowerMah, totalPower, dischargeAmount); if ((percent + 0.5f < 1f) || mBatteryUtils.shouldHideSipper(batterySipper)) { // Don't show it if we should hide or usage percentage is lower than 1% continue; diff --git a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java index 4c0ddc9aa91..9c936b9c08e 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/CellularDataConditionController.java @@ -19,7 +19,6 @@ package com.android.settings.homepage.contextualcards.conditional; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; -import android.net.ConnectivityManager; import android.telephony.PhoneStateListener; import android.telephony.PreciseDataConnectionState; import android.telephony.SubscriptionManager; @@ -39,7 +38,6 @@ public class CellularDataConditionController implements ConditionalCardControlle private final Context mAppContext; private final ConditionManager mConditionManager; private final GlobalSettingsChangeListener mDefaultDataSubscriptionIdListener; - private final ConnectivityManager mConnectivityManager; private int mSubId; private TelephonyManager mTelephonyManager; @@ -63,8 +61,6 @@ public class CellularDataConditionController implements ConditionalCardControlle } } }; - mConnectivityManager = appContext.getSystemService( - ConnectivityManager.class); } @Override @@ -74,7 +70,7 @@ public class CellularDataConditionController implements ConditionalCardControlle @Override public boolean isDisplayable() { - if (!mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) + if (!mTelephonyManager.isDataCapable() || mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_READY) { return false; } diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java index 38b7c4a9e92..bdf2d2b8e89 100644 --- a/src/com/android/settings/location/LocationPersonalSettings.java +++ b/src/com/android/settings/location/LocationPersonalSettings.java @@ -53,6 +53,7 @@ public class LocationPersonalSettings extends DashboardFragment { // STOPSHIP(b/180533061): resolve the personal/work location services issue before we can // ship. use(LocationFooterPreferenceController.class).init(this); + use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE); final RecentLocationAccessPreferenceController controller = use( diff --git a/src/com/android/settings/location/LocationServicesPreferenceController.java b/src/com/android/settings/location/LocationServicesPreferenceController.java index f7a338840f2..53150a827b3 100644 --- a/src/com/android/settings/location/LocationServicesPreferenceController.java +++ b/src/com/android/settings/location/LocationServicesPreferenceController.java @@ -17,8 +17,6 @@ package com.android.settings.location; import android.content.Context; -import android.net.wifi.WifiManager; -import android.provider.Settings; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; @@ -28,29 +26,8 @@ import com.android.settings.core.BasePreferenceController; */ public class LocationServicesPreferenceController extends BasePreferenceController { - private final WifiManager mWifiManager; - public LocationServicesPreferenceController(Context context, String key) { super(context, key); - mWifiManager = context.getSystemService(WifiManager.class); - } - - @Override - public CharSequence getSummary() { - final boolean wifiScanOn = mWifiManager.isScanAlwaysAvailable(); - final boolean bleScanOn = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1; - int resId; - if (wifiScanOn && bleScanOn) { - resId = R.string.scanning_status_text_wifi_on_ble_on; - } else if (wifiScanOn && !bleScanOn) { - resId = R.string.scanning_status_text_wifi_on_ble_off; - } else if (!wifiScanOn && bleScanOn) { - resId = R.string.scanning_status_text_wifi_off_ble_on; - } else { - resId = R.string.scanning_status_text_wifi_off_ble_off; - } - return mContext.getString(resId); } @AvailabilityStatus diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index d58ad5b5ca2..bb971bff057 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -83,6 +83,7 @@ public class LocationSettings extends DashboardFragment { use(AppLocationPermissionPreferenceController.class).init(this); use(RecentLocationAccessPreferenceController.class).init(this); + use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); use(LocationFooterPreferenceController.class).init(this); use(LocationForWorkPreferenceController.class).init(this); use(LocationInjectedServicesForWorkPreferenceController.class).init(this); diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java index 18936fd4897..67830758007 100644 --- a/src/com/android/settings/location/LocationWorkProfileSettings.java +++ b/src/com/android/settings/location/LocationWorkProfileSettings.java @@ -52,6 +52,7 @@ public class LocationWorkProfileSettings extends DashboardFragment { use(AppLocationPermissionPreferenceController.class).init(this); use(LocationFooterPreferenceController.class).init(this); use(LocationForWorkPreferenceController.class).init(this); + use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE); final RecentLocationAccessPreferenceController controller = use( diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java index 383fbeaafd9..97de4a7f9a4 100644 --- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java +++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java @@ -17,6 +17,7 @@ import static android.Manifest.permission_group.LOCATION; import android.content.Context; import android.content.Intent; +import android.icu.text.RelativeDateTimeFormatter; import android.os.UserHandle; import android.os.UserManager; @@ -29,6 +30,7 @@ import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.profileselector.ProfileSelectFragment; import com.android.settingslib.location.RecentLocationAccesses; +import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.AppPreference; import java.util.ArrayList; @@ -113,7 +115,8 @@ public class RecentLocationAccessPreferenceController extends LocationBasePrefer @Override public void onLocationModeChanged(int mode, boolean restricted) { - mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode)); + boolean enabled = mLocationEnabler.isEnabled(mode); + mCategoryRecentLocationRequests.setVisible(enabled); } /** @@ -133,6 +136,9 @@ public class RecentLocationAccessPreferenceController extends LocationBasePrefer final AppPreference pref = new AppPreference(prefContext); pref.setIcon(access.icon); pref.setTitle(access.label); + pref.setSummary(StringUtil.formatRelativeTime(prefContext, + System.currentTimeMillis() - access.accessFinishTime, false, + RelativeDateTimeFormatter.Style.SHORT)); pref.setOnPreferenceClickListener(new PackageEntryClickedListener( fragment.getContext(), access.packageName, access.userHandle)); return pref; diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java new file mode 100644 index 00000000000..68cde637eeb --- /dev/null +++ b/src/com/android/settings/location/RecentLocationAccessSeeAllButtonPreferenceController.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 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.location; + +import android.content.Context; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +/** + * Preference controller that handles the "See All" button for recent location access. + */ +public class RecentLocationAccessSeeAllButtonPreferenceController extends + LocationBasePreferenceController { + + private Preference mPreference; + + /** + * Constructor of {@link RecentLocationAccessSeeAllButtonPreferenceController}. + */ + public RecentLocationAccessSeeAllButtonPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void onLocationModeChanged(int mode, boolean restricted) { + boolean enabled = mLocationEnabler.isEnabled(mode); + mPreference.setVisible(enabled); + } +} diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java index c147ee7722d..a05092dcdbd 100644 --- a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java +++ b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java @@ -37,7 +37,7 @@ public class RecentLocationAccessSeeAllPreferenceController extends LocationBasePreferenceController { private PreferenceScreen mCategoryAllRecentLocationAccess; - private RecentLocationAccesses mRecentLocationAccesses; + private final RecentLocationAccesses mRecentLocationAccesses; private boolean mShowSystem = false; private Preference mPreference; private int mType = ProfileSelectFragment.ProfileType.ALL; diff --git a/src/com/android/settings/network/InternetPreferenceController.java b/src/com/android/settings/network/InternetPreferenceController.java index f64ed30b2c5..a6c857467c1 100644 --- a/src/com/android/settings/network/InternetPreferenceController.java +++ b/src/com/android/settings/network/InternetPreferenceController.java @@ -65,7 +65,7 @@ public class InternetPreferenceController extends AbstractPreferenceController i @VisibleForTesting static Map sIconMap = new HashMap<>(); static { - sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_unavailable); + sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_airplane); sIconMap.put(INTERNET_NETWORKS_AVAILABLE, R.drawable.ic_no_internet_available); sIconMap.put(INTERNET_WIFI, R.drawable.ic_wifi_signal_4); sIconMap.put(INTERNET_CELLULAR, R.drawable.ic_network_cell); diff --git a/src/com/android/settings/network/MobileNetworkPreferenceController.java b/src/com/android/settings/network/MobileNetworkPreferenceController.java index b968438df26..527a632d706 100644 --- a/src/com/android/settings/network/MobileNetworkPreferenceController.java +++ b/src/com/android/settings/network/MobileNetworkPreferenceController.java @@ -28,6 +28,7 @@ import android.os.UserManager; import android.provider.Settings; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import androidx.annotation.VisibleForTesting; @@ -55,7 +56,7 @@ public class MobileNetworkPreferenceController extends AbstractPreferenceControl private final UserManager mUserManager; private Preference mPreference; @VisibleForTesting - PhoneStateListener mPhoneStateListener; + MobileNetworkTelephonyCallback mTelephonyCallback; private BroadcastReceiver mAirplanModeChangedReceiver; @@ -97,18 +98,22 @@ public class MobileNetworkPreferenceController extends AbstractPreferenceControl return KEY_MOBILE_NETWORK_SETTINGS; } + class MobileNetworkTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.ServiceStateListener { + @Override + public void onServiceStateChanged(ServiceState serviceState) { + updateState(mPreference); + } + } + @OnLifecycleEvent(Event.ON_START) public void onStart() { if (isAvailable()) { - if (mPhoneStateListener == null) { - mPhoneStateListener = new PhoneStateListener() { - @Override - public void onServiceStateChanged(ServiceState serviceState) { - updateState(mPreference); - } - }; + if (mTelephonyCallback == null) { + mTelephonyCallback = new MobileNetworkTelephonyCallback(); } - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); + mTelephonyManager.registerTelephonyCallback( + mContext.getMainExecutor(), mTelephonyCallback); } if (mAirplanModeChangedReceiver != null) { mContext.registerReceiver(mAirplanModeChangedReceiver, @@ -118,8 +123,8 @@ public class MobileNetworkPreferenceController extends AbstractPreferenceControl @OnLifecycleEvent(Event.ON_STOP) public void onStop() { - if (mPhoneStateListener != null) { - mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); + if (mTelephonyCallback != null) { + mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); } if (mAirplanModeChangedReceiver != null) { mContext.unregisterReceiver(mAirplanModeChangedReceiver); diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java index ea29a1d796d..822aad05f49 100644 --- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java +++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java @@ -160,7 +160,7 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreferenceCompat final Context context = getContext(); final ContentResolver contentResolver = context.getContentResolver(); - mMode = ConnectivityManager.getPrivateDnsMode(contentResolver); + mMode = ConnectivityManager.getPrivateDnsMode(context); mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname); mEditText.addTextChangedListener(this); diff --git a/src/com/android/settings/network/PrivateDnsPreferenceController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java index 31360408bdd..4aa92f4e500 100644 --- a/src/com/android/settings/network/PrivateDnsPreferenceController.java +++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java @@ -118,7 +118,7 @@ public class PrivateDnsPreferenceController extends BasePreferenceController public CharSequence getSummary() { final Resources res = mContext.getResources(); final ContentResolver cr = mContext.getContentResolver(); - final String mode = ConnectivityManager.getPrivateDnsMode(cr); + final String mode = ConnectivityManager.getPrivateDnsMode(mContext); final LinkProperties lp = mLatestLinkProperties; final List dnses = (lp == null) ? null : lp.getValidatedPrivateDnsServers(); final boolean dnsesResolved = !ArrayUtils.isEmpty(dnses); diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java index c2b1fc4f453..1f1cb37c996 100644 --- a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java +++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java @@ -20,11 +20,11 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; -import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.ims.ImsMmTelManager; import android.util.Log; @@ -53,7 +53,7 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc @VisibleForTesting Preference mPreference; - private PhoneCallStateListener mPhoneStateListener; + private PhoneCallStateTelephonyCallback mTelephonyCallback; private boolean mShow5gLimitedDialog; boolean mIsNrEnabledFromCarrierConfig; private boolean mHas5gCapability; @@ -72,8 +72,8 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc } public Enhanced4gBasePreferenceController init(int subId) { - if (mPhoneStateListener == null) { - mPhoneStateListener = new PhoneCallStateListener(); + if (mTelephonyCallback == null) { + mTelephonyCallback = new PhoneCallStateTelephonyCallback(); } if (mSubId == subId) { @@ -134,18 +134,18 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc @Override public void onStart() { - if (!isModeMatched() || (mPhoneStateListener == null)) { + if (!isModeMatched() || (mTelephonyCallback == null)) { return; } - mPhoneStateListener.register(mContext, mSubId); + mTelephonyCallback.register(mContext, mSubId); } @Override public void onStop() { - if (mPhoneStateListener == null) { + if (mTelephonyCallback == null) { return; } - mPhoneStateListener.unregister(); + mTelephonyCallback.unregister(); } @Override @@ -218,16 +218,13 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL); } - private class PhoneCallStateListener extends PhoneStateListener { - - PhoneCallStateListener() { - super(Looper.getMainLooper()); - } + private class PhoneCallStateTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.CallStateListener { private TelephonyManager mTelephonyManager; @Override - public void onCallStateChanged(int state, String incomingNumber) { + public void onCallStateChanged(int state) { mCallState = state; updateState(mPreference); } @@ -240,7 +237,8 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc // assign current call state so that it helps to show correct preference state even // before first onCallStateChanged() by initial registration. mCallState = mTelephonyManager.getCallState(subId); - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE); + mTelephonyManager.registerTelephonyCallback( + mContext.getMainExecutor(), mTelephonyCallback); final long supportedRadioBitmask = mTelephonyManager.getSupportedRadioAccessFamily(); mHas5gCapability = @@ -250,7 +248,7 @@ public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenc public void unregister() { mCallState = null; if (mTelephonyManager != null) { - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(this); } } } diff --git a/src/com/android/settings/network/telephony/SignalStrengthListener.java b/src/com/android/settings/network/telephony/SignalStrengthListener.java index 0e29a45fb5b..8d7304dd70d 100644 --- a/src/com/android/settings/network/telephony/SignalStrengthListener.java +++ b/src/com/android/settings/network/telephony/SignalStrengthListener.java @@ -19,9 +19,12 @@ package com.android.settings.network.telephony; import android.content.Context; import android.telephony.PhoneStateListener; import android.telephony.SignalStrength; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.util.ArraySet; +import androidx.annotation.VisibleForTesting; + import com.google.common.collect.Sets; import java.util.Map; @@ -34,7 +37,9 @@ public class SignalStrengthListener { private TelephonyManager mBaseTelephonyManager; private Callback mCallback; - private Map mListeners; + private Context mContext; + @VisibleForTesting + Map mTelephonyCallbacks; public interface Callback { void onSignalStrengthChanged(); @@ -43,20 +48,21 @@ public class SignalStrengthListener { public SignalStrengthListener(Context context, Callback callback) { mBaseTelephonyManager = context.getSystemService(TelephonyManager.class); mCallback = callback; - mListeners = new TreeMap<>(); + mContext = context; + mTelephonyCallbacks = new TreeMap<>(); } /** Resumes listening for signal strength changes for the set of ids from the last call to * {@link #updateSubscriptionIds(Set)} */ public void resume() { - for (int subId : mListeners.keySet()) { + for (int subId : mTelephonyCallbacks.keySet()) { startListening(subId); } } /** Pauses listening for signal strength changes */ public void pause() { - for (int subId : mListeners.keySet()) { + for (int subId : mTelephonyCallbacks.keySet()) { stopListening(subId); } } @@ -64,30 +70,36 @@ public class SignalStrengthListener { /** Updates the set of ids we want to be listening for, beginning to listen for any new ids and * stopping listening for any ids not contained in the new set */ public void updateSubscriptionIds(Set ids) { - Set currentIds = new ArraySet<>(mListeners.keySet()); + Set currentIds = new ArraySet<>(mTelephonyCallbacks.keySet()); for (int idToRemove : Sets.difference(currentIds, ids)) { stopListening(idToRemove); - mListeners.remove(idToRemove); + mTelephonyCallbacks.remove(idToRemove); } for (int idToAdd : Sets.difference(ids, currentIds)) { - PhoneStateListener listener = new PhoneStateListener() { - @Override - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - mCallback.onSignalStrengthChanged(); - } - }; - mListeners.put(idToAdd, listener); + SignalStrengthTelephonyCallback telephonyCallback = + new SignalStrengthTelephonyCallback(); + mTelephonyCallbacks.put(idToAdd, telephonyCallback); startListening(idToAdd); } } + @VisibleForTesting + class SignalStrengthTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.SignalStrengthsListener { + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + mCallback.onSignalStrengthChanged(); + } + } + private void startListening(int subId) { TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId); - mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mgr.registerTelephonyCallback( + mContext.getMainExecutor(), mTelephonyCallbacks.get(subId)); } private void stopListening(int subId) { TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId); - mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_NONE); + mgr.unregisterTelephonyCallback(mTelephonyCallbacks.get(subId)); } } diff --git a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java index fa8b47fba41..b3421f43bdf 100644 --- a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java @@ -17,11 +17,11 @@ 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.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.ims.ImsMmTelManager; import android.util.Log; @@ -50,7 +50,7 @@ public class VideoCallingPreferenceController extends TelephonyTogglePreferenceC private Preference mPreference; private CarrierConfigManager mCarrierConfigManager; - private PhoneCallStateListener mPhoneStateListener; + private PhoneTelephonyCallback mTelephonyCallback; @VisibleForTesting Integer mCallState; private MobileDataEnabledListener mDataContentObserver; @@ -59,7 +59,7 @@ public class VideoCallingPreferenceController extends TelephonyTogglePreferenceC super(context, key); mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); mDataContentObserver = new MobileDataEnabledListener(context, this); - mPhoneStateListener = new PhoneCallStateListener(); + mTelephonyCallback = new PhoneTelephonyCallback(); } @Override @@ -78,13 +78,13 @@ public class VideoCallingPreferenceController extends TelephonyTogglePreferenceC @Override public void onStart() { - mPhoneStateListener.register(mContext, mSubId); + mTelephonyCallback.register(mContext, mSubId); mDataContentObserver.start(mSubId); } @Override public void onStop() { - mPhoneStateListener.unregister(); + mTelephonyCallback.unregister(); mDataContentObserver.stop(); } @@ -163,16 +163,13 @@ public class VideoCallingPreferenceController extends TelephonyTogglePreferenceC updateState(mPreference); } - private class PhoneCallStateListener extends PhoneStateListener { - - PhoneCallStateListener() { - super(Looper.getMainLooper()); - } + private class PhoneTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.CallStateListener { private TelephonyManager mTelephonyManager; @Override - public void onCallStateChanged(int state, String incomingNumber) { + public void onCallStateChanged(int state) { mCallState = state; updateState(mPreference); } @@ -185,12 +182,12 @@ public class VideoCallingPreferenceController extends TelephonyTogglePreferenceC // assign current call state so that it helps to show correct preference state even // before first onCallStateChanged() by initial registration. mCallState = mTelephonyManager.getCallState(subId); - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE); + mTelephonyManager.registerTelephonyCallback(context.getMainExecutor(), this); } public void unregister() { mCallState = null; - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(this); } } diff --git a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java index 94a5999c0a6..2d7ba38a801 100644 --- a/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/WifiCallingPreferenceController.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.os.Looper; import android.os.PersistableBundle; import android.provider.Settings; import android.telecom.PhoneAccountHandle; @@ -28,6 +27,7 @@ import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.ims.ImsMmTelManager; import android.util.Log; @@ -60,13 +60,13 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont private ImsMmTelManager mImsMmTelManager; @VisibleForTesting PhoneAccountHandle mSimCallManager; - private PhoneCallStateListener mPhoneStateListener; + private PhoneTelephonyCallback mTelephonyCallback; private Preference mPreference; public WifiCallingPreferenceController(Context context, String key) { super(context, key); mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class); - mPhoneStateListener = new PhoneCallStateListener(); + mTelephonyCallback = new PhoneTelephonyCallback(); } @Override @@ -79,12 +79,12 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont @Override public void onStart() { - mPhoneStateListener.register(mContext, mSubId); + mTelephonyCallback.register(mContext, mSubId); } @Override public void onStop() { - mPhoneStateListener.unregister(); + mTelephonyCallback.unregister(); } @Override @@ -195,16 +195,13 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont } - private class PhoneCallStateListener extends PhoneStateListener { - - PhoneCallStateListener() { - super(Looper.getMainLooper()); - } + private class PhoneTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.CallStateListener { private TelephonyManager mTelephonyManager; @Override - public void onCallStateChanged(int state, String incomingNumber) { + public void onCallStateChanged(int state) { mCallState = state; updateState(mPreference); } @@ -214,12 +211,12 @@ public class WifiCallingPreferenceController extends TelephonyBasePreferenceCont // assign current call state so that it helps to show correct preference state even // before first onCallStateChanged() by initial registration. mCallState = mTelephonyManager.getCallState(subId); - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE); + mTelephonyManager.registerTelephonyCallback(context.getMainExecutor(), this); } public void unregister() { mCallState = null; - mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE); + mTelephonyManager.unregisterTelephonyCallback(this); } } } diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java index bab0d5f7f07..5396be5ba5e 100644 --- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java +++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java @@ -46,10 +46,10 @@ import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.SubSettingLauncher; import com.android.settings.notification.app.AppNotificationSettings; import com.android.settings.widget.PrimarySwitchPreference; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.utils.StringUtil; +import com.android.settingslib.widget.TwoTargetPreference; import java.util.ArrayList; import java.util.Calendar; diff --git a/src/com/android/settings/notification/app/RecentConversationPreference.java b/src/com/android/settings/notification/app/RecentConversationPreference.java index 49e2c023272..167fdd61650 100644 --- a/src/com/android/settings/notification/app/RecentConversationPreference.java +++ b/src/com/android/settings/notification/app/RecentConversationPreference.java @@ -21,7 +21,7 @@ import android.view.View; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settingslib.TwoTargetPreference; +import com.android.settingslib.widget.TwoTargetPreference; import com.google.common.annotations.VisibleForTesting; diff --git a/src/com/android/settings/notification/zen/ZenRulePreference.java b/src/com/android/settings/notification/zen/ZenRulePreference.java index 1f1283d90c9..b8c8354eb3f 100644 --- a/src/com/android/settings/notification/zen/ZenRulePreference.java +++ b/src/com/android/settings/notification/zen/ZenRulePreference.java @@ -33,8 +33,8 @@ import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settings.utils.ManagedServiceSettings; import com.android.settings.utils.ZenServiceListing; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.widget.TwoTargetPreference; import java.util.Map; diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java index 21352b7b978..19b6c5457d7 100755 --- a/src/com/android/settings/wfd/WifiDisplaySettings.java +++ b/src/com/android/settings/wfd/WifiDisplaySettings.java @@ -64,9 +64,9 @@ import com.android.internal.app.MediaRouteDialogPresenter; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.search.Indexable; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.widget.TwoTargetPreference; /** * The Settings screen for WifiDisplay configuration and connection management. diff --git a/src/com/android/settings/widget/PrimaryCheckBoxPreference.java b/src/com/android/settings/widget/PrimaryCheckBoxPreference.java index a784d5da971..c90f1983482 100644 --- a/src/com/android/settings/widget/PrimaryCheckBoxPreference.java +++ b/src/com/android/settings/widget/PrimaryCheckBoxPreference.java @@ -25,7 +25,7 @@ import android.widget.CheckBox; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settingslib.TwoTargetPreference; +import com.android.settingslib.widget.TwoTargetPreference; /** * A custom preference that provides inline checkbox. It has a mandatory field for title, and diff --git a/src/com/android/settings/widget/SettingsMainSwitchBar.java b/src/com/android/settings/widget/SettingsMainSwitchBar.java index 733be0a6f6a..ce2dde59f19 100644 --- a/src/com/android/settings/widget/SettingsMainSwitchBar.java +++ b/src/com/android/settings/widget/SettingsMainSwitchBar.java @@ -84,9 +84,8 @@ public class SettingsMainSwitchBar extends MainSwitchBar { } /** - * If admin is not null, disables the text and switch but keeps the view clickable. - * Otherwise, calls setEnabled which will enables the entire view including - * the text and switch. + * If admin is not null, disables the text and switch but keeps the view clickable (unless the + * switch is disabled for other reasons). Otherwise, calls setEnabled. */ public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) { mEnforcedAdmin = admin; @@ -101,7 +100,7 @@ public class SettingsMainSwitchBar extends MainSwitchBar { mDisabledByAdmin = false; mSwitch.setVisibility(View.VISIBLE); mRestrictedIcon.setVisibility(View.GONE); - setEnabled(true); + setEnabled(isEnabled()); } } diff --git a/src/com/android/settings/widget/SettingsMainSwitchPreference.java b/src/com/android/settings/widget/SettingsMainSwitchPreference.java index 80a0021e44e..f627e31cc2d 100644 --- a/src/com/android/settings/widget/SettingsMainSwitchPreference.java +++ b/src/com/android/settings/widget/SettingsMainSwitchPreference.java @@ -186,6 +186,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference { * Enable or disable the text and switch. */ public void setSwitchBarEnabled(boolean enabled) { + setEnabled(enabled); if (mMainSwitchBar != null) { mMainSwitchBar.setEnabled(enabled); } diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java index 024c1c3303d..de64b911111 100644 --- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java +++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java @@ -29,6 +29,7 @@ import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.telephony.ims.ImsManager; import android.telephony.ims.ImsMmTelManager; @@ -102,7 +103,10 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment private ProvisioningManager mProvisioningManager; private TelephonyManager mTelephonyManager; - private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { + private final PhoneTelephonyCallback mTelephonyCallback = new PhoneTelephonyCallback(); + + private class PhoneTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.CallStateListener { /* * Enable/disable controls when in/out of a call and depending on * TTY mode and TTY support over VoLTE. @@ -110,7 +114,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment * java.lang.String) */ @Override - public void onCallStateChanged(int state, String incomingNumber) { + public void onCallStateChanged(int state) { final SettingsActivity activity = (SettingsActivity) getActivity(); final boolean isNonTtyOrTtyOnVolteEnabled = queryImsState(WifiCallingSettingsForSub.this.mSubId).isAllowUserControl(); @@ -149,7 +153,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment && isCallStateIdle); } } - }; + } /* * Launch carrier emergency address managemnent activity @@ -398,7 +402,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment res.getStringArray(R.array.wifi_calling_mode_summaries_without_wifi_only)); } - // NOTE: Buttons will be enabled/disabled in mPhoneStateListener + // NOTE: Buttons will be enabled/disabled in mTelephonyCallback final WifiCallingQueryImsState queryIms = queryImsState(mSubId); final boolean wfcEnabled = queryIms.isEnabledByUser() && queryIms.isAllowUserControl(); @@ -416,16 +420,16 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment updateBody(); + final Context context = getActivity(); if (queryImsState(mSubId).isWifiCallingSupported()) { - getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener, - PhoneStateListener.LISTEN_CALL_STATE); + getTelephonyManagerForSub(mSubId).registerTelephonyCallback( + context.getMainExecutor(), mTelephonyCallback); mSwitchBar.addOnSwitchChangeListener(this); mValidListener = true; } - final Context context = getActivity(); context.registerReceiver(mIntentReceiver, mIntentFilter); final Intent intent = getActivity().getIntent(); @@ -446,8 +450,7 @@ public class WifiCallingSettingsForSub extends SettingsPreferenceFragment if (mValidListener) { mValidListener = false; - getTelephonyManagerForSub(mSubId).listen(mPhoneStateListener, - PhoneStateListener.LISTEN_NONE); + getTelephonyManagerForSub(mSubId).unregisterTelephonyCallback(mTelephonyCallback); mSwitchBar.removeOnSwitchChangeListener(this); } diff --git a/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java index 6c5b9f2323f..5ac5c6626aa 100644 --- a/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java +++ b/tests/robotests/src/com/android/settings/AirplaneModeEnablerTest.java @@ -57,7 +57,7 @@ public final class AirplaneModeEnablerTest { ShadowSettings.setAirplaneMode(true); - mAirplaneModeEnabler.mPhoneStateListener.onRadioPowerStateChanged( + mAirplaneModeEnabler.mTelephonyCallback.onRadioPowerStateChanged( TelephonyManager.RADIO_POWER_OFF); verify(mAirplaneModeChangedListener, times(1)).onAirplaneModeChanged(true); diff --git a/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java b/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java index 6ed266f7604..8725a0c168c 100644 --- a/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/accounts/ProviderPreferenceTest.java @@ -16,7 +16,7 @@ package com.android.settings.accounts; -import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM; +import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM; import static com.google.common.truth.Truth.assertThat; 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 c735452732a..440ad044087 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppBatteryPreferenceControllerTest.java @@ -152,7 +152,7 @@ public class AppBatteryPreferenceControllerTest { mController.mBatteryUsageStats = mBatteryUsageStats; mController.mUidBatteryConsumer = mUidBatteryConsumer; doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(), - anyDouble(), anyDouble(), anyInt()); + anyDouble(), anyInt()); doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList(); mController.displayPreference(mScreen); diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java index 31c00ecdc6e..e78a3942728 100644 --- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceControllerTest.java @@ -16,7 +16,7 @@ package com.android.settings.applications.defaultapps; -import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM; +import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -28,8 +28,8 @@ import android.os.UserManager; import androidx.preference.Preference; import com.android.settings.R; -import com.android.settingslib.TwoTargetPreference; import com.android.settingslib.applications.DefaultAppInfo; +import com.android.settingslib.widget.TwoTargetPreference; import org.junit.Before; import org.junit.Test; diff --git a/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java b/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java index 3fdb7b4d256..861b4e395fa 100644 --- a/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/BillingCycleSettingsTest.java @@ -36,8 +36,8 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Resources; -import android.net.ConnectivityManager; import android.net.NetworkPolicyManager; import android.os.Bundle; @@ -72,9 +72,9 @@ public class BillingCycleSettingsTest { @Mock private NetworkPolicyEditor mNetworkPolicyEditor; @Mock - private ConnectivityManager mConnectivityManager; - @Mock private NetworkPolicyManager mNetworkPolicyManager; + @Mock + private PackageManager mMockPackageManager; private Context mContext; @Mock @@ -157,9 +157,8 @@ public class BillingCycleSettingsTest { .onCreatePreferences(any(Bundle.class), nullable(String.class)); when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE)) .thenReturn(mNetworkPolicyManager); - when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)) - .thenReturn(mConnectivityManager); - when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true); + when(mContext.getPackageManager()).thenReturn(mMockPackageManager); + when(mMockPackageManager.hasSystemFeature(any())).thenReturn(true); final SwitchPreference preference = mock(SwitchPreference.class); when(billingCycleSettings.findPreference(anyString())).thenReturn(preference); diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java index 4a5bc700b1d..6a7f2374380 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java @@ -16,13 +16,14 @@ package com.android.settings.datausage; -import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.content.pm.PackageManager.FEATURE_WIFI; import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -31,7 +32,7 @@ import static org.mockito.Mockito.when; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.net.ConnectivityManager; +import android.content.pm.PackageManager; import android.net.NetworkTemplate; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -104,7 +105,7 @@ public class DataUsageSummaryPreferenceControllerTest { @Mock private TelephonyManager mTelephonyManager; @Mock - private ConnectivityManager mConnectivityManager; + private PackageManager mPm; private DataUsageInfoController mDataInfoController; @@ -138,10 +139,9 @@ public class DataUsageSummaryPreferenceControllerTest { doReturn(mTelephonyManager).when(mActivity).getSystemService(TelephonyManager.class); doReturn(mTelephonyManager).when(mTelephonyManager) .createForSubscriptionId(mDefaultSubscriptionId); - when(mActivity.getSystemService(Context.CONNECTIVITY_SERVICE)) - .thenReturn(mConnectivityManager); + doReturn(mPm).when(mActivity).getPackageManager(); + doReturn(false).when(mPm).hasSystemFeature(eq(FEATURE_WIFI)); doReturn(TelephonyManager.SIM_STATE_READY).when(mTelephonyManager).getSimState(); - when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false); mController = spy(new DataUsageSummaryPreferenceController( mDataUsageController, @@ -363,7 +363,7 @@ public class DataUsageSummaryPreferenceControllerTest { final int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; mController.init(subscriptionId); mController.mDataUsageController = mDataUsageController; - when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(true); + doReturn(true).when(mPm).hasSystemFeature(eq(FEATURE_WIFI)); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java index 21f9d1a3ab3..a465d742356 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java @@ -18,14 +18,15 @@ package com.android.settings.datausage; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.robolectric.Shadows.shadowOf; import android.app.usage.NetworkStatsManager; import android.content.Context; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.telephony.TelephonyManager; import android.util.DataUnit; @@ -38,12 +39,11 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowApplication; +import org.robolectric.shadows.ShadowPackageManager; @RunWith(RobolectricTestRunner.class) public final class DataUsageUtilsTest { - @Mock - private ConnectivityManager mManager; @Mock private TelephonyManager mTelephonyManager; @Mock @@ -56,21 +56,20 @@ public final class DataUsageUtilsTest { MockitoAnnotations.initMocks(this); final ShadowApplication shadowContext = ShadowApplication.getInstance(); mContext = RuntimeEnvironment.application; - shadowContext.setSystemService(Context.CONNECTIVITY_SERVICE, mManager); shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager); shadowContext.setSystemService(Context.NETWORK_STATS_SERVICE, mNetworkStatsManager); } @Test public void mobileDataStatus_whenNetworkIsSupported() { - when(mManager.isNetworkSupported(anyInt())).thenReturn(true); + when(mTelephonyManager.isDataCapable()).thenReturn(true); final boolean hasMobileData = DataUsageUtils.hasMobileData(mContext); assertThat(hasMobileData).isTrue(); } @Test public void mobileDataStatus_whenNetworkIsNotSupported() { - when(mManager.isNetworkSupported(anyInt())).thenReturn(false); + when(mTelephonyManager.isDataCapable()).thenReturn(false); final boolean hasMobileData = DataUsageUtils.hasMobileData(mContext); assertThat(hasMobileData).isFalse(); } @@ -85,7 +84,8 @@ public final class DataUsageUtilsTest { @Test public void hasEthernet_shouldQueryEthernetSummaryForUser() throws Exception { - when(mManager.isNetworkSupported(anyInt())).thenReturn(true); + ShadowPackageManager pm = shadowOf(RuntimeEnvironment.application.getPackageManager()); + pm.setSystemFeature(PackageManager.FEATURE_ETHERNET, true); final String subscriber = "TestSub"; when(mTelephonyManager.getSubscriberId()).thenReturn(subscriber); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 8eeac8d26b0..dd1a0e1adc8 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -47,7 +47,6 @@ import androidx.loader.app.LoaderManager; import androidx.preference.Preference; import androidx.recyclerview.widget.RecyclerView; -import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.R; import com.android.settings.SettingsActivity; @@ -114,12 +113,8 @@ public class AdvancedPowerUsageDetailTest { @Mock private BatteryEntry mBatteryEntry; @Mock - private BatterySipper mBatterySipper; - @Mock private BatteryStatsHelper mBatteryStatsHelper; @Mock - private BatteryStats.Uid mUid; - @Mock private PackageManager mPackageManager; @Mock private AppOpsManager mAppOpsManager; @@ -140,6 +135,7 @@ public class AdvancedPowerUsageDetailTest { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + when(mContext.getPackageName()).thenReturn("foo"); FakeFeatureFactory.setupForTest(); mFragment = spy(new AdvancedPowerUsageDetail()); @@ -168,19 +164,11 @@ public class AdvancedPowerUsageDetailTest { doReturn(mEntityHeaderController).when(mEntityHeaderController) .setSummary(nullable(String.class)); - doReturn(UID).when(mBatterySipper).getUid(); + when(mBatteryEntry.getUid()).thenReturn(UID); when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL); - doReturn(BACKGROUND_TIME_US).when(mUid).getProcessStateTime( - eq(BatteryStats.Uid.PROCESS_STATE_BACKGROUND), anyLong(), anyInt()); - doReturn(PROCSTATE_TOP_TIME_US).when(mUid).getProcessStateTime( - eq(BatteryStats.Uid.PROCESS_STATE_TOP), anyLong(), anyInt()); - doReturn(mForegroundActivityTimer).when(mUid).getForegroundActivityTimer(); - doReturn(FOREGROUND_ACTIVITY_TIME_US).when(mForegroundActivityTimer) - .getTotalTimeLocked(anyLong(), anyInt()); - ReflectionHelpers.setField(mBatteryEntry, "sipper", mBatterySipper); + when(mBatteryEntry.getTimeInBackgroundMs()).thenReturn(BACKGROUND_TIME_MS); + when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(FOREGROUND_TIME_MS); mBatteryEntry.iconId = ICON_ID; - mBatterySipper.uidObj = mUid; - mBatterySipper.drainType = BatterySipper.DrainType.APP; mFragment.mHeaderPreference = mHeaderPreference; mFragment.mState = mState; @@ -200,6 +188,7 @@ public class AdvancedPowerUsageDetailTest { Answer callable = invocation -> { mBundle = captor.getValue().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); + System.out.println("mBundle = " + mBundle); return null; }; doAnswer(callable).when(mActivity).startActivityAsUser(captor.capture(), @@ -262,8 +251,8 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_hasBasicData() { - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, + mBatteryEntry, USAGE_PERCENT); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)) @@ -274,29 +263,12 @@ public class AdvancedPowerUsageDetailTest { .isEqualTo(USAGE_PERCENT); } - @Test - public void testStartBatteryDetailPage_typeNotApp_hasBasicData() { - mBatterySipper.drainType = BatterySipper.DrainType.PHONE; - mBatterySipper.usageTimeMs = PHONE_FOREGROUND_TIME_MS; - - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); - - assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); - assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME)) - .isEqualTo(PHONE_FOREGROUND_TIME_MS); - assertThat(mBundle.getLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME)) - .isEqualTo(PHONE_BACKGROUND_TIME_MS); - assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_POWER_USAGE_PERCENT)) - .isEqualTo(USAGE_PERCENT); - } - @Test public void testStartBatteryDetailPage_NormalApp() { - mBatterySipper.mPackages = PACKAGE_NAME; - mBatteryEntry.defaultPackageName = PACKAGE_NAME[0]; - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); + when(mBatteryEntry.getDefaultPackageName()).thenReturn(PACKAGE_NAME[0]); + + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, + mBatteryEntry, USAGE_PERCENT); assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)).isEqualTo( PACKAGE_NAME[0]); @@ -304,9 +276,10 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_SystemApp() { - mBatterySipper.mPackages = null; - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); + when(mBatteryEntry.getDefaultPackageName()).thenReturn(null); + + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, + mBatteryEntry, USAGE_PERCENT); assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_LABEL)).isEqualTo(APP_LABEL); assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_ICON_ID)).isEqualTo(ICON_ID); @@ -316,23 +289,22 @@ public class AdvancedPowerUsageDetailTest { @Test public void testStartBatteryDetailPage_WorkApp() { final int appUid = 1010019; - mBatterySipper.mPackages = PACKAGE_NAME; - doReturn(appUid).when(mBatterySipper).getUid(); - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); + doReturn(appUid).when(mBatteryEntry).getUid(); + + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, + mBatteryEntry, USAGE_PERCENT); verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(10))); } @Test public void testStartBatteryDetailPage_typeUser_startByCurrentUser() { - mBatterySipper.drainType = BatterySipper.DrainType.USER; - mBatterySipper.userId = 10; + when(mBatteryEntry.isUserEntry()).thenReturn(true); final int currentUser = 20; ShadowActivityManager.setCurrentUser(currentUser); - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); + AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, + mBatteryEntry, USAGE_PERCENT); verify(mActivity).startActivityAsUser(any(Intent.class), eq(new UserHandle(currentUser))); } @@ -364,18 +336,6 @@ public class AdvancedPowerUsageDetailTest { assertThat(mBundle.getInt(AdvancedPowerUsageDetail.EXTRA_UID)).isEqualTo(UID); } - @Test - public void testStartBatteryDetailPage_defaultPackageNull_chooseFromBatterySipper() { - mBatteryEntry.defaultPackageName = null; - mBatteryEntry.sipper.mPackages = PACKAGE_NAME; - - AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mBatteryUtils, mFragment, - mBatteryStatsHelper, 0, mBatteryEntry, USAGE_PERCENT); - - assertThat(mBundle.getString(AdvancedPowerUsageDetail.EXTRA_PACKAGE_NAME)) - .isEqualTo(PACKAGE_NAME[0]); - } - @Test public void testInitPreference_hasCorrectSummary() { Bundle bundle = new Bundle(4); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java index 28655f32946..1faa75fb700 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryAppListPreferenceControllerTest.java @@ -20,21 +20,16 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.PackageManager; -import android.os.BatteryStats; import android.os.UserManager; -import android.text.TextUtils; import android.text.format.DateUtils; import androidx.preference.PreferenceGroup; -import com.android.internal.os.BatterySipper; -import com.android.internal.os.BatteryStatsImpl; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.core.InstrumentedPreferenceFragment; @@ -51,12 +46,8 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class BatteryAppListPreferenceControllerTest { - private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"}; private static final String KEY_APP_LIST = "app_list"; - private static final int UID = 123; - @Mock - private BatterySipper mNormalBatterySipper; @Mock private SettingsActivity mSettingsActivity; @Mock @@ -69,6 +60,8 @@ public class BatteryAppListPreferenceControllerTest { private PackageManager mPackageManager; @Mock private UserManager mUserManager; + @Mock + private BatteryEntry mBatteryEntry; private Context mContext; private PowerGaugePreference mPreference; @@ -87,137 +80,67 @@ public class BatteryAppListPreferenceControllerTest { FakeFeatureFactory.setupForTest(); mPreference = new PowerGaugePreference(mContext); - when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES); - when(mNormalBatterySipper.getUid()).thenReturn(UID); - mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; - mNormalBatterySipper.uidObj = mock(BatteryStats.Uid.class); mPreferenceController = new BatteryAppListPreferenceController(mContext, KEY_APP_LIST, null, mSettingsActivity, mFragment); mPreferenceController.mBatteryUtils = mBatteryUtils; mPreferenceController.mAppListGroup = mAppListGroup; - } - @Test - public void testExtractKeyFromSipper_typeAPPUidObjectNull_returnPackageNames() { - mNormalBatterySipper.uidObj = null; - mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; - - final String key = mPreferenceController.extractKeyFromSipper(mNormalBatterySipper); - assertThat(key).isEqualTo(TextUtils.concat(mNormalBatterySipper.getPackages()).toString()); - } - - @Test - public void testExtractKeyFromSipper_typeOther_returnDrainType() { - mNormalBatterySipper.uidObj = null; - mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH; - - final String key = mPreferenceController.extractKeyFromSipper(mNormalBatterySipper); - assertThat(key).isEqualTo(mNormalBatterySipper.drainType.toString()); - } - - @Test - public void testExtractKeyFromSipper_typeUser_returnDrainTypeWithUserId() { - mNormalBatterySipper.uidObj = null; - mNormalBatterySipper.drainType = BatterySipper.DrainType.USER; - mNormalBatterySipper.userId = 2; - - final String key = mPreferenceController.extractKeyFromSipper(mNormalBatterySipper); - assertThat(key).isEqualTo("USER2"); - } - - @Test - public void testExtractKeyFromSipper_typeAPPUidObjectNotNull_returnUid() { - mNormalBatterySipper.uidObj = new BatteryStatsImpl.Uid(new BatteryStatsImpl(), UID); - mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; - - final String key = mPreferenceController.extractKeyFromSipper(mNormalBatterySipper); - assertThat(key).isEqualTo(Integer.toString(mNormalBatterySipper.getUid())); + BatteryAppListPreferenceController.sConfig = + new BatteryAppListPreferenceController.Config() { + @Override + public boolean shouldShowBatteryAttributionList(Context context) { + return true; + } + }; } @Test public void testSetUsageSummary_timeLessThanOneMinute_DoNotSetSummary() { - mNormalBatterySipper.usageTimeMs = 59 * DateUtils.SECOND_IN_MILLIS; + when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(59 * DateUtils.SECOND_IN_MILLIS); - mPreferenceController.setUsageSummary(mPreference, mNormalBatterySipper); + mPreferenceController.setUsageSummary(mPreference, mBatteryEntry); assertThat(mPreference.getSummary()).isNull(); } @Test public void testSetUsageSummary_timeMoreThanOneMinute_normalApp_setScreenSummary() { - mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS; + when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(2 * DateUtils.MINUTE_IN_MILLIS); doReturn(mContext.getText(R.string.battery_used_for)).when(mFragment).getText( R.string.battery_used_for); doReturn(mContext).when(mFragment).getContext(); - mPreferenceController.setUsageSummary(mPreference, mNormalBatterySipper); + mPreferenceController.setUsageSummary(mPreference, mBatteryEntry); assertThat(mPreference.getSummary().toString()).isEqualTo("Used for 2 min"); } @Test public void testSetUsageSummary_timeMoreThanOneMinute_GoogleApp_shouldNotSetScreenSummary() { - mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS; - mNormalBatterySipper.packageWithHighestDrain = "com.google.android.googlequicksearchbox"; + when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(2 * DateUtils.MINUTE_IN_MILLIS); + when(mBatteryEntry.getDefaultPackageName()) + .thenReturn("com.google.android.googlequicksearchbox"); doReturn(mContext.getText(R.string.battery_used_for)).when(mFragment).getText( R.string.battery_used_for); doReturn(mContext).when(mFragment).getContext(); - mPreferenceController.setUsageSummary(mPreference, mNormalBatterySipper); + mPreferenceController.setUsageSummary(mPreference, mBatteryEntry); assertThat(mPreference.getSummary()).isNull(); } @Test public void testSetUsageSummary_timeMoreThanOneMinute_hiddenApp_setUsedSummary() { - mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS; - doReturn(true).when(mBatteryUtils).shouldHideSipper(mNormalBatterySipper); + when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(2 * DateUtils.MINUTE_IN_MILLIS); + when(mBatteryEntry.isHidden()).thenReturn(true); + doReturn(mContext).when(mFragment).getContext(); - mPreferenceController.setUsageSummary(mPreference, mNormalBatterySipper); + mPreferenceController.setUsageSummary(mPreference, mBatteryEntry); assertThat(mPreference.getSummary().toString()).isEqualTo("2 min"); } - @Test - public void testSetUsageSummary_timeMoreThanOneMinute_notApp_setUsedSummary() { - mNormalBatterySipper.usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS; - mNormalBatterySipper.drainType = BatterySipper.DrainType.PHONE; - doReturn(mContext).when(mFragment).getContext(); - - mPreferenceController.setUsageSummary(mPreference, mNormalBatterySipper); - - assertThat(mPreference.getSummary().toString()).isEqualTo("2 min"); - } - - @Test - public void testShouldHideSipper_typeOvercounted_returnTrue() { - mNormalBatterySipper.drainType = BatterySipper.DrainType.OVERCOUNTED; - - assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isTrue(); - } - - @Test - public void testShouldHideSipper_typeUnaccounted_returnTrue() { - mNormalBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED; - - assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isTrue(); - } - - @Test - public void testShouldHideSipper_typeNormal_returnFalse() { - mNormalBatterySipper.drainType = BatterySipper.DrainType.APP; - - assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isFalse(); - } - - @Test - public void testShouldHideSipper_hiddenSystemModule_returnTrue() { - when(mBatteryUtils.isHiddenSystemModule(mNormalBatterySipper)).thenReturn(true); - - assertThat(mPreferenceController.shouldHideSipper(mNormalBatterySipper)).isTrue(); - } - @Test public void testNeverUseFakeData() { assertThat(BatteryAppListPreferenceController.USE_FAKE_DATA).isFalse(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java index e40b27067cc..6858579479b 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java @@ -17,6 +17,9 @@ package com.android.settings.fuelgauge; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -24,18 +27,21 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.BatteryConsumer; import android.os.Handler; import android.os.Process; +import android.os.SystemBatteryConsumer; +import android.os.UidBatteryConsumer; +import android.os.UserBatteryConsumer; import android.os.UserManager; -import com.android.internal.os.BatterySipper; -import com.android.internal.os.BatterySipper.DrainType; import com.android.settings.R; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -50,121 +56,153 @@ public class BatteryEntryTest { private static final int APP_UID = 123; private static final int SYSTEM_UID = Process.SYSTEM_UID; private static final String APP_DEFAULT_PACKAGE_NAME = "com.android.test"; - private static final String APP_LABEL = "Test App Name"; + private static final String LABEL_PREFIX = "Label for "; private static final String HIGH_DRAIN_PACKAGE = "com.android.test.screen"; private static final String ANDROID_PACKAGE = "android"; - private static final String[] SYSTEM_PACKAGES = {HIGH_DRAIN_PACKAGE, ANDROID_PACKAGE}; @Rule public MockitoRule mocks = MockitoJUnit.rule(); - @Mock private Context mockContext; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mMockContext; @Mock private Handler mockHandler; @Mock private PackageManager mockPackageManager; @Mock private UserManager mockUserManager; + @Mock private UidBatteryConsumer mUidBatteryConsumer; + @Mock private SystemBatteryConsumer mSystemBatteryConsumer; @Before public void stubContextToReturnMockPackageManager() { - when(mockContext.getPackageManager()).thenReturn(mockPackageManager); + when(mMockContext.getPackageManager()).thenReturn(mockPackageManager); } @Before public void stubPackageManagerToReturnAppPackageAndName() throws NameNotFoundException { - when(mockPackageManager.getPackagesForUid(APP_UID)) - .thenReturn(new String[] {APP_DEFAULT_PACKAGE_NAME}); - - ApplicationInfo appInfo = mock(ApplicationInfo.class); - when(mockPackageManager.getApplicationInfo(APP_DEFAULT_PACKAGE_NAME, 0 /* no flags */)) - .thenReturn(appInfo); - when(mockPackageManager.getApplicationLabel(appInfo)).thenReturn(APP_LABEL); + when(mockPackageManager.getApplicationInfo(anyString(), eq(0) /* no flags */)) + .thenAnswer(invocation -> { + ApplicationInfo info = new ApplicationInfo(); + info.packageName = invocation.getArgument(0); + return info; + }); + when(mockPackageManager.getApplicationLabel(any(ApplicationInfo.class))) + .thenAnswer(invocation -> LABEL_PREFIX + + ((ApplicationInfo) invocation.getArgument(0)).packageName); } - private BatteryEntry createBatteryEntryForApp() { - return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForApp(), - null); + private BatteryEntry createBatteryEntryForApp(String[] packages, String packageName, + String highDrainPackage) { + UidBatteryConsumer consumer = mock(UidBatteryConsumer.class); + when(consumer.getUid()).thenReturn(APP_UID); + when(consumer.getPackageWithHighestDrain()).thenReturn(highDrainPackage); + return new BatteryEntry(mMockContext, mockHandler, mockUserManager, + consumer, false, packages, packageName); } - private BatterySipper createSipperForApp() { - BatterySipper sipper = - new BatterySipper(DrainType.APP, new FakeUid(APP_UID), 0 /* power use */); - sipper.packageWithHighestDrain = HIGH_DRAIN_PACKAGE; - return sipper; + private BatteryEntry createSystemBatteryEntry(int drainType) { + SystemBatteryConsumer consumer = mock(SystemBatteryConsumer.class); + when(consumer.getDrainType()).thenReturn(drainType); + return new BatteryEntry(mMockContext, mockHandler, mockUserManager, + consumer, false, null, null); } - private BatteryEntry createBatteryEntryForSystem() { - return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem(), - null); - } - - private BatterySipper createSipperForSystem() { - BatterySipper sipper = - new BatterySipper(DrainType.APP, new FakeUid(SYSTEM_UID), 0 /* power use */); - sipper.packageWithHighestDrain = HIGH_DRAIN_PACKAGE; - sipper.mPackages = SYSTEM_PACKAGES; - return sipper; + private BatteryEntry createUserBatteryConsumer(int userId) { + UserBatteryConsumer consumer = mock(UserBatteryConsumer.class); + when(consumer.getUserId()).thenReturn(userId); + return new BatteryEntry(mMockContext, mockHandler, mockUserManager, + consumer, false, null, null); } @Test public void batteryEntryForApp_shouldSetDefaultPackageNameAndLabel() throws Exception { - BatteryEntry entry = createBatteryEntryForApp(); + BatteryEntry entry = createBatteryEntryForApp(null, APP_DEFAULT_PACKAGE_NAME, + HIGH_DRAIN_PACKAGE); - assertThat(entry.defaultPackageName).isEqualTo(APP_DEFAULT_PACKAGE_NAME); - assertThat(entry.getLabel()).isEqualTo(APP_LABEL); + assertThat(entry.getDefaultPackageName()).isEqualTo(APP_DEFAULT_PACKAGE_NAME); + assertThat(entry.getLabel()).isEqualTo(LABEL_PREFIX + APP_DEFAULT_PACKAGE_NAME); } @Test public void batteryEntryForApp_shouldSetLabelAsPackageName_whenPackageCannotBeFound() - throws Exception { - when(mockPackageManager.getApplicationInfo(APP_DEFAULT_PACKAGE_NAME, 0 /* no flags */)) - .thenThrow(new NameNotFoundException()); + throws Exception { + when(mockPackageManager.getApplicationInfo(APP_DEFAULT_PACKAGE_NAME, 0 /* no flags */)) + .thenThrow(new NameNotFoundException()); - BatteryEntry entry = createBatteryEntryForApp(); + BatteryEntry entry = createBatteryEntryForApp(null, APP_DEFAULT_PACKAGE_NAME, null); - assertThat(entry.getLabel()).isEqualTo(APP_DEFAULT_PACKAGE_NAME); + assertThat(entry.getLabel()).isEqualTo(APP_DEFAULT_PACKAGE_NAME); } @Test public void batteryEntryForApp_shouldSetHighestDrainPackage_whenPackagesCannotBeFoundForUid() { when(mockPackageManager.getPackagesForUid(APP_UID)).thenReturn(null); - BatteryEntry entry = createBatteryEntryForApp(); + BatteryEntry entry = createBatteryEntryForApp(null, null, HIGH_DRAIN_PACKAGE); - assertThat(entry.getLabel()).isEqualTo(HIGH_DRAIN_PACKAGE); + assertThat(entry.getLabel()).isEqualTo(LABEL_PREFIX + HIGH_DRAIN_PACKAGE); } @Test public void batteryEntryForApp_shouldSetHighestDrainPackage_whenMultiplePackagesFoundForUid() { - when(mockPackageManager.getPackagesForUid(APP_UID)) - .thenReturn(new String[] {APP_DEFAULT_PACKAGE_NAME, "package2", "package3"}); + BatteryEntry entry = createBatteryEntryForApp( + new String[] {APP_DEFAULT_PACKAGE_NAME, "package2", "package3"}, null, + HIGH_DRAIN_PACKAGE); - BatteryEntry entry = createBatteryEntryForApp(); - - assertThat(entry.getLabel()).isEqualTo(HIGH_DRAIN_PACKAGE); + assertThat(entry.getLabel()).isEqualTo(LABEL_PREFIX + HIGH_DRAIN_PACKAGE); } @Test public void batteryEntryForAOD_containCorrectInfo() { - final BatterySipper batterySipper = mock(BatterySipper.class); - batterySipper.drainType = DrainType.AMBIENT_DISPLAY; + final SystemBatteryConsumer systemBatteryConsumer = mock(SystemBatteryConsumer.class); + when(systemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY); final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, - mockUserManager, batterySipper, null); + mockUserManager, systemBatteryConsumer, false, null, null); assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod); assertThat(entry.name).isEqualTo("Ambient display"); } @Test - public void extractPackageFromSipper_systemSipper_returnSystemPackage() { - BatteryEntry entry = createBatteryEntryForSystem(); + public void getTimeInForegroundMs_app() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, mUidBatteryConsumer, false, null, null); - assertThat(entry.extractPackagesFromSipper(entry.sipper)) - .isEqualTo(new String[] {ANDROID_PACKAGE}); + when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND)) + .thenReturn(100L); + + assertThat(entry.getTimeInForegroundMs()).isEqualTo(100L); } @Test - public void extractPackageFromSipper_normalSipper_returnDefaultPackage() { - BatteryEntry entry = createBatteryEntryForApp(); + public void getTimeInForegroundMs_systemConsumer() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, mSystemBatteryConsumer, false, null, null); - assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(entry.sipper.mPackages); + when(mSystemBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) + .thenReturn(100L); + + assertThat(entry.getTimeInForegroundMs()).isEqualTo(100L); + } + + @Test + public void getTimeInBackgroundMs_app() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, mUidBatteryConsumer, false, null, null); + + when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) + .thenReturn(100L); + + assertThat(entry.getTimeInBackgroundMs()).isEqualTo(100L); + } + + @Test + public void getTimeInBackgroundMs_systemConsumer() { + final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler, + mockUserManager, mSystemBatteryConsumer, false, null, null); + + when(mSystemBatteryConsumer.getUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE)) + .thenReturn(100L); + + assertThat(entry.getTimeInBackgroundMs()).isEqualTo(0); } @Test @@ -176,7 +214,29 @@ public class BatteryEntryTest { assertThat(BatteryEntry.sUidCache).isNotEmpty(); Locale.setDefault(new Locale("zh_TW")); - createBatteryEntryForApp(); + createBatteryEntryForApp(null, null, HIGH_DRAIN_PACKAGE); assertThat(BatteryEntry.sUidCache).isEmpty(); // check if cache is clear } + + @Test + public void getKey_UidBatteryConsumer() { + final BatteryEntry entry = createBatteryEntryForApp(null, null, null); + final String key = entry.getKey(); + assertThat(key).isEqualTo("123"); + } + + @Test + public void getKey_SystemBatteryConsumer_returnDrainType() { + final BatteryEntry entry = + createSystemBatteryEntry(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH); + final String key = entry.getKey(); + assertThat(key).isEqualTo("S|2"); + } + + @Test + public void getKey_UserBatteryConsumer_returnUserId() { + final BatteryEntry entry = createUserBatteryConsumer(2); + final String key = entry.getKey(); + assertThat(key).isEqualTo("U|2"); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java index c8fdf8c9562..2d22a12a7e8 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java @@ -28,11 +28,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -52,9 +49,9 @@ import android.os.BatteryStatsManager; import android.os.Build; import android.os.Bundle; import android.os.Process; +import android.os.SystemBatteryConsumer; import android.os.SystemClock; import android.os.UserManager; -import android.text.format.DateUtils; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; @@ -91,8 +88,6 @@ public class BatteryUtilsTest { private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT; private static final long TIME_STATE_FOREGROUND = 3000 * UNIT; private static final long TIME_STATE_BACKGROUND = 6000 * UNIT; - private static final long TIME_FOREGROUND_ZERO = 0; - private static final long TIME_FOREGROUND = 100 * DateUtils.MINUTE_IN_MILLIS; 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; @@ -106,13 +101,11 @@ public class BatteryUtilsTest { private static final double BATTERY_SYSTEM_USAGE = 600; private static final double BATTERY_OVERACCOUNTED_USAGE = 500; private static final double BATTERY_UNACCOUNTED_USAGE = 700; - private static final double BATTERY_APP_USAGE = 100; private static final double BATTERY_WIFI_USAGE = 200; private static final double BATTERY_BLUETOOTH_USAGE = 300; private static final double TOTAL_BATTERY_USAGE = 1000; - private static final double HIDDEN_USAGE = 200; private static final int DISCHARGE_AMOUNT = 80; - private static final double PERCENT_SYSTEM_USAGE = 60; + private static final double PERCENT_SYSTEM_USAGE = 48; private static final double PRECISION = 0.001; private static final int SDK_VERSION = Build.VERSION_CODES.L; private static final String PACKAGE_NAME = "com.android.app"; @@ -127,6 +120,8 @@ public class BatteryUtilsTest { @Mock private BatteryStats.Timer mTimer; @Mock + private SystemBatteryConsumer mSystemBatteryConsumer; + @Mock private BatterySipper mNormalBatterySipper; @Mock private BatterySipper mWifiBatterySipper; @@ -291,23 +286,54 @@ public class BatteryUtilsTest { } @Test - public void testRemoveHiddenBatterySippers_ContainsHiddenSippers_RemoveAndReturnValue() { - final List sippers = new ArrayList<>(); - sippers.add(mNormalBatterySipper); - sippers.add(mScreenBatterySipper); - sippers.add(mSystemBatterySipper); - sippers.add(mOvercountedBatterySipper); - sippers.add(mUnaccountedBatterySipper); - sippers.add(mWifiBatterySipper); - sippers.add(mBluetoothBatterySipper); - sippers.add(mIdleBatterySipper); - when(mProvider.isTypeSystem(mSystemBatterySipper)).thenReturn(true); - doNothing().when(mBatteryUtils).smearScreenBatterySipper(any(), any()); + public void testShouldHideSystemConsumer_TypeIdle_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_IDLE); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } - final double totalUsage = mBatteryUtils.removeHiddenBatterySippers(sippers); + @Test + public void testShouldHideSystemConsumer_TypeMobileRadio_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } - assertThat(sippers).containsExactly(mNormalBatterySipper); - assertThat(totalUsage).isWithin(PRECISION).of(BATTERY_SYSTEM_USAGE); + @Test + public void testShouldHideSystemConsumer_TypeScreen_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_SCREEN); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } + + @Test + public void testShouldHideSystemConsumer_TypeBluetooth_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } + + @Test + public void testShouldHideSystemConsumer_TypeWifi_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_WIFI); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } + + @Test + public void testShouldHideSystemConsumer_LowPower_ReturnTrue() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT); + when(mSystemBatteryConsumer.getConsumedPower()).thenReturn(0.0005); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue(); + } + + @Test + public void testShouldHideSystemConsumer_HighPower_ReturnFalse() { + when(mSystemBatteryConsumer.getDrainType()) + .thenReturn(SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT); + when(mSystemBatteryConsumer.getConsumedPower()).thenReturn(0.5); + assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isFalse(); } @Test @@ -388,68 +414,16 @@ public class BatteryUtilsTest { @Test public void testCalculateBatteryPercent() { assertThat(mBatteryUtils.calculateBatteryPercent(BATTERY_SYSTEM_USAGE, TOTAL_BATTERY_USAGE, - HIDDEN_USAGE, DISCHARGE_AMOUNT)) + DISCHARGE_AMOUNT)) .isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE); } - @Test - public void testSmearScreenBatterySipper() { - final BatterySipper sipperNull = createTestSmearBatterySipper(TIME_FOREGROUND_ZERO, - BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */); - final BatterySipper sipperBg = createTestSmearBatterySipper(TIME_FOREGROUND_ZERO, - BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */); - final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND, - BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */); - final BatterySipper sipperFg2 = createTestSmearBatterySipper(TIME_FOREGROUND, - BATTERY_APP_USAGE, 3 /* uid */, false /* isUidNull */); - - final List sippers = new ArrayList<>(); - sippers.add(sipperNull); - sippers.add(sipperBg); - sippers.add(sipperFg); - sippers.add(sipperFg2); - - mBatteryUtils.smearScreenBatterySipper(sippers, mScreenBatterySipper); - - assertThat(sipperNull.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE); - assertThat(sipperBg.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE); - assertThat(sipperFg.totalPowerMah).isWithin(PRECISION).of( - BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE / 2); - assertThat(sipperFg2.totalPowerMah).isWithin(PRECISION).of( - BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE / 2); - } - - @Test - public void testSmearScreenBatterySipper_screenSipperNull_shouldNotCrash() { - final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND, - BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */); - - final List sippers = new ArrayList<>(); - sippers.add(sipperFg); - - // Shouldn't crash - mBatteryUtils.smearScreenBatterySipper(sippers, null /* screenSipper */); - } - @Test public void testCalculateRunningTimeBasedOnStatsType() { assertThat(mBatteryUtils.calculateRunningTimeBasedOnStatsType(mBatteryStatsHelper, BatteryStats.STATS_SINCE_CHARGED)).isEqualTo(TIME_SINCE_LAST_FULL_CHARGE_MS); } - @Test - public void testSortUsageList() { - final List sippers = new ArrayList<>(); - sippers.add(mNormalBatterySipper); - sippers.add(mScreenBatterySipper); - sippers.add(mSystemBatterySipper); - - mBatteryUtils.sortUsageList(sippers); - - assertThat(sippers).containsExactly(mNormalBatterySipper, mSystemBatterySipper, - mScreenBatterySipper); - } - @Test public void testCalculateLastFullChargeTime() { final long currentTimeMs = System.currentTimeMillis(); @@ -509,23 +483,6 @@ public class BatteryUtilsTest { .isFalse(); } - private BatterySipper createTestSmearBatterySipper( - long topTime, double totalPowerMah, int uidCode, boolean isUidNull) { - final BatterySipper sipper = mock(BatterySipper.class); - sipper.drainType = BatterySipper.DrainType.APP; - sipper.totalPowerMah = totalPowerMah; - doReturn(uidCode).when(sipper).getUid(); - if (!isUidNull) { - final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS); - doReturn(topTime).when(mBatteryUtils).getProcessTimeMs( - eq(BatteryUtils.StatusType.SCREEN_USAGE), eq(uid), anyInt()); - doReturn(uidCode).when(uid).getUid(); - sipper.uidObj = uid; - } - - return sipper; - } - @Test public void testInitBatteryStatsHelper_init() { mBatteryUtils.initBatteryStatsHelper(mBatteryStatsHelper, mBundle, mUserManager); @@ -535,30 +492,6 @@ public class BatteryUtilsTest { mUserManager.getUserProfiles()); } - @Test - public void testFindBatterySipperByType_findTypeScreen() { - BatterySipper sipper = mBatteryUtils.findBatterySipperByType(mUsageList, - BatterySipper.DrainType.SCREEN); - - assertThat(sipper).isSameInstanceAs(mScreenBatterySipper); - } - - @Test - public void testFindBatterySipperByType_findTypeApp() { - BatterySipper sipper = mBatteryUtils.findBatterySipperByType(mUsageList, - BatterySipper.DrainType.APP); - - assertThat(sipper).isSameInstanceAs(mNormalBatterySipper); - } - - @Test - public void testCalculateScreenUsageTime_returnCorrectTime() { - mScreenBatterySipper.usageTimeMs = TIME_EXPECTED_FOREGROUND; - - assertThat(mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper)).isEqualTo( - TIME_EXPECTED_FOREGROUND); - } - @Test public void testIsPreOApp_SdkLowerThanO_ReturnTrue() { assertThat(mBatteryUtils.isPreOApp(LOW_SDK_PACKAGE)).isTrue(); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java index 1ef288016b4..c9b1a00bbf5 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageAdvancedTest.java @@ -69,6 +69,14 @@ public class PowerUsageAdvancedTest { mFeatureFactory = FakeFeatureFactory.setupForTest(); when(mToggleAppsMenu.getItemId()).thenReturn(PowerUsageAdvanced.MENU_TOGGLE_APPS); + BatteryAppListPreferenceController.sConfig = + new BatteryAppListPreferenceController.Config() { + @Override + public boolean shouldShowBatteryAttributionList(Context context) { + return true; + } + }; + mFragment = spy(new PowerUsageAdvanced()); mFragment.onAttach(mContext); } diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java index 097ebaf5e85..1639bbae544 100644 --- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java @@ -32,7 +32,6 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; -import android.net.ConnectivityManager; import android.os.UserManager; import android.provider.Settings; import android.telephony.SubscriptionInfo; @@ -110,9 +109,7 @@ public class MobileNetworkSummaryControllerTest { @Test public void isAvailable_wifiOnlyMode_notAvailable() { - final ConnectivityManager cm = mock(ConnectivityManager.class); - when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false); - when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm); + when(mTelephonyManager.isDataCapable()).thenReturn(false); when(mUserManager.isAdminUser()).thenReturn(true); assertThat(mController.isAvailable()).isFalse(); @@ -120,11 +117,8 @@ public class MobileNetworkSummaryControllerTest { @Test public void isAvailable_secondaryUser_notAvailable() { - final ConnectivityManager cm = mock(ConnectivityManager.class); - when(cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true); - when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(cm); + when(mTelephonyManager.isDataCapable()).thenReturn(true); when(mUserManager.isAdminUser()).thenReturn(false); - assertThat(mController.isAvailable()).isFalse(); } diff --git a/tests/robotests/src/com/android/settings/network/telephony/SignalStrengthListenerTest.java b/tests/robotests/src/com/android/settings/network/telephony/SignalStrengthListenerTest.java index 406f3604faa..6abf8a022aa 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/SignalStrengthListenerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/SignalStrengthListenerTest.java @@ -16,13 +16,9 @@ package com.android.settings.network.telephony; -import static android.telephony.PhoneStateListener.LISTEN_NONE; -import static android.telephony.PhoneStateListener.LISTEN_SIGNAL_STRENGTHS; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -31,7 +27,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.telephony.PhoneStateListener; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import org.junit.Before; @@ -44,6 +40,8 @@ import org.mockito.internal.util.collections.Sets; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.concurrent.Executor; + @RunWith(RobolectricTestRunner.class) public class SignalStrengthListenerTest { private static final int SUB_ID_1 = 111; @@ -88,13 +86,19 @@ public class SignalStrengthListenerTest { @Test public void updateSubscriptionIds_beforeResume_startedListening() { mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_1, SUB_ID_2)); - ArgumentCaptor captor1 = ArgumentCaptor.forClass( - PhoneStateListener.class); - ArgumentCaptor captor2 = ArgumentCaptor.forClass( - PhoneStateListener.class); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager2).listen(captor2.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager3, never()).listen(any(), anyInt()); + ArgumentCaptor captor1 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); + ArgumentCaptor captor2 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); + + verify(mManager1).registerTelephonyCallback( + any(Executor.class), captor1.capture()); + verify(mManager2).registerTelephonyCallback( + any(Executor.class), captor2.capture()); + verify(mManager3, never()).registerTelephonyCallback(any(), any()); + assertThat(captor1.getValue()).isNotNull(); assertThat(captor2.getValue()).isNotNull(); @@ -105,46 +109,57 @@ public class SignalStrengthListenerTest { @Test public void updateSubscriptionIds_twoCalls_oneIdAdded() { mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_1, SUB_ID_2)); - verify(mManager1).listen(any(PhoneStateListener.class), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager2).listen(any(PhoneStateListener.class), eq(LISTEN_SIGNAL_STRENGTHS)); + + verify(mManager1).registerTelephonyCallback(any(Executor.class), + eq(mListener.mTelephonyCallbacks.get(SUB_ID_1))); + verify(mManager2).registerTelephonyCallback(any(Executor.class), + eq(mListener.mTelephonyCallbacks.get(SUB_ID_2))); mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_1, SUB_ID_2, SUB_ID_3)); - verify(mManager1, never()).listen(any(PhoneStateListener.class), eq(LISTEN_NONE)); - verify(mManager2, never()).listen(any(PhoneStateListener.class), eq(LISTEN_NONE)); - verify(mManager3).listen(any(PhoneStateListener.class), eq(LISTEN_SIGNAL_STRENGTHS)); + verify(mManager1, never()).unregisterTelephonyCallback( + mListener.mTelephonyCallbacks.get(SUB_ID_1)); + verify(mManager2, never()).unregisterTelephonyCallback( + mListener.mTelephonyCallbacks.get(SUB_ID_2)); + verify(mManager3).registerTelephonyCallback( + any(Executor.class), eq(mListener.mTelephonyCallbacks.get(SUB_ID_3))); } @Test public void updateSubscriptionIds_twoCalls_oneIdRemoved() { - ArgumentCaptor captor1 = ArgumentCaptor.forClass( - PhoneStateListener.class); + ArgumentCaptor captor1 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_1, SUB_ID_2)); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager2).listen(any(PhoneStateListener.class), eq(LISTEN_SIGNAL_STRENGTHS)); + verify(mManager1).registerTelephonyCallback(any(Executor.class), captor1.capture()); + verify(mManager2).registerTelephonyCallback( + any(Executor.class), any(TelephonyCallback.class)); mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_2)); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_NONE)); - verify(mManager2, never()).listen(any(PhoneStateListener.class), eq(LISTEN_NONE)); + verify(mManager1).unregisterTelephonyCallback(captor1.capture()); + verify(mManager2, never()).unregisterTelephonyCallback(any(TelephonyCallback.class)); // Make sure the correct listener was removed. assertThat(captor1.getAllValues().get(0) == captor1.getAllValues().get(1)).isTrue(); } @Test public void updateSubscriptionIds_twoCalls_twoIdsRemovedOneAdded() { - ArgumentCaptor captor1 = ArgumentCaptor.forClass( - PhoneStateListener.class); - ArgumentCaptor captor2 = ArgumentCaptor.forClass( - PhoneStateListener.class); + ArgumentCaptor captor1 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); + ArgumentCaptor captor2 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_1, SUB_ID_2)); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager2).listen(captor2.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); + verify(mManager1).registerTelephonyCallback(any(Executor.class), captor1.capture()); + verify(mManager2).registerTelephonyCallback(any(Executor.class), captor2.capture()); mListener.updateSubscriptionIds(Sets.newSet(SUB_ID_3)); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_NONE)); - verify(mManager2).listen(captor2.capture(), eq(LISTEN_NONE)); - verify(mManager3).listen(any(PhoneStateListener.class), eq(LISTEN_SIGNAL_STRENGTHS)); + verify(mManager1).unregisterTelephonyCallback(captor1.capture()); + verify(mManager2).unregisterTelephonyCallback(captor2.capture()); + verify(mManager3).registerTelephonyCallback( + any(Executor.class), any(TelephonyCallback.class)); // Make sure the correct listeners were removed. assertThat(captor1.getValue() != captor2.getValue()).isTrue(); assertThat(captor1.getAllValues().get(0) == captor1.getAllValues().get(1)).isTrue(); @@ -157,15 +172,19 @@ public class SignalStrengthListenerTest { mListener.pause(); mListener.resume(); - ArgumentCaptor captor1 = ArgumentCaptor.forClass( - PhoneStateListener.class); - ArgumentCaptor captor2 = ArgumentCaptor.forClass( - PhoneStateListener.class); - verify(mManager1, times(2)).listen(captor1.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager1).listen(captor1.capture(), eq(LISTEN_NONE)); + ArgumentCaptor captor1 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); + ArgumentCaptor captor2 = + ArgumentCaptor.forClass( + SignalStrengthListener.SignalStrengthTelephonyCallback.class); + verify(mManager1, times(2)).registerTelephonyCallback( + any(Executor.class), captor1.capture()); + verify(mManager1).unregisterTelephonyCallback(captor1.capture()); - verify(mManager2, times(2)).listen(captor2.capture(), eq(LISTEN_SIGNAL_STRENGTHS)); - verify(mManager2).listen(captor2.capture(), eq(LISTEN_NONE)); + verify(mManager2, times(2)).registerTelephonyCallback( + any(Executor.class), captor2.capture()); + verify(mManager2).unregisterTelephonyCallback(captor2.capture()); assertThat(captor1.getAllValues().get(0) == captor1.getAllValues().get(1)).isTrue(); assertThat(captor1.getAllValues().get(0) == captor1.getAllValues().get(2)).isTrue(); diff --git a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java index ae534d09fd4..dfe2bc05f2d 100644 --- a/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java @@ -48,7 +48,6 @@ import android.content.Context; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.CellSignalStrength; -import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; @@ -89,8 +88,6 @@ public class SimStatusDialogControllerTest { @Mock private ServiceState mServiceState; @Mock - private PhoneStateListener mPhoneStateListener; - @Mock private SignalStrength mSignalStrength; @Mock private CellSignalStrength mCellSignalStrengthCdma; @@ -150,7 +147,6 @@ public class SimStatusDialogControllerTest { doReturn(0).when(mCellSignalStrengthWcdma).getAsuLevel(); doReturn(null).when(mSignalStrength).getCellSignalStrengths(); - doReturn(mPhoneStateListener).when(mController).getPhoneStateListener(); doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt()); when(mTelephonyManager.getActiveModemCount()).thenReturn(MAX_PHONE_COUNT_SINGLE_SIM); diff --git a/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java index c540512c283..be3815d78c9 100644 --- a/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/MobileNetworkPreferenceControllerTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.net.ConnectivityManager; import android.os.Looper; import android.os.UserManager; import android.provider.Settings; @@ -63,8 +62,6 @@ public class MobileNetworkPreferenceControllerTest { @Mock private UserManager mUserManager; - @Mock - private ConnectivityManager mConnectivityManager; private PreferenceManager mPreferenceManager; private PreferenceScreen mScreen; @@ -82,7 +79,6 @@ public class MobileNetworkPreferenceControllerTest { when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); - when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); if (Looper.myLooper() == null) { Looper.prepare(); } @@ -98,8 +94,7 @@ public class MobileNetworkPreferenceControllerTest { @Test public void secondaryUser_prefIsNotAvailable() { when(mUserManager.isAdminUser()).thenReturn(false); - when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) - .thenReturn(true); + when(mTelephonyManager.isDataCapable()).thenReturn(true); mController = new MobileNetworkPreferenceController(mContext); assertThat(mController.isAvailable()).isFalse(); @@ -108,8 +103,7 @@ public class MobileNetworkPreferenceControllerTest { @Test public void wifiOnly_prefIsNotAvailable() { when(mUserManager.isAdminUser()).thenReturn(true); - when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) - .thenReturn(false); + when(mTelephonyManager.isDataCapable()).thenReturn(false); mController = new MobileNetworkPreferenceController(mContext); assertThat(mController.isAvailable()).isFalse(); @@ -124,13 +118,12 @@ public class MobileNetworkPreferenceControllerTest { mLifecycleRegistry.handleLifecycleEvent(Event.ON_START); verify(mController).onStart(); - verify(mTelephonyManager).listen(mController.mPhoneStateListener, - PhoneStateListener.LISTEN_SERVICE_STATE); + verify(mTelephonyManager).registerTelephonyCallback( + mContext.getMainExecutor(), mController.mTelephonyCallback); mLifecycleRegistry.handleLifecycleEvent(Event.ON_STOP); verify(mController).onStop(); - verify(mTelephonyManager).listen(mController.mPhoneStateListener, - PhoneStateListener.LISTEN_NONE); + verify(mTelephonyManager).unregisterTelephonyCallback(mController.mTelephonyCallback); } @Test @@ -148,12 +141,12 @@ public class MobileNetworkPreferenceControllerTest { mController.displayPreference(mScreen); mLifecycleRegistry.handleLifecycleEvent(Event.ON_START); verify(mController).onStart(); - verify(mTelephonyManager).listen(mController.mPhoneStateListener, - PhoneStateListener.LISTEN_SERVICE_STATE); + verify(mTelephonyManager).registerTelephonyCallback( + mContext.getMainExecutor(), mController.mTelephonyCallback); doReturn(testCarrierName).when(mController).getSummary(); - mController.mPhoneStateListener.onServiceStateChanged(null); + mController.mTelephonyCallback.onServiceStateChanged(null); // Carrier name should be set. Assert.assertEquals(mPreference.getSummary(), testCarrierName);