Snap for 7216111 from 036dc189b6 to sc-v2-release

Change-Id: Ie434dfa80dc130f06cc3574b828e055f1e39ad7c
This commit is contained in:
android-build-team Robot
2021-03-18 01:08:39 +00:00
63 changed files with 1092 additions and 1140 deletions

View File

@@ -0,0 +1,28 @@
<!--
Copyright (C) 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10c0.34,0 0.68,-0.02 1.01,-0.05V20h-1v-0.04c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96H13v-2H9.66c-0.09,-0.66 -0.16,-1.32 -0.16,-2s0.07,-1.35 0.16,-2H21.8C20.87,5.44 16.83,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56C16.43,5.07 17.96,6.35 18.92,8zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82C10.52,6.57 11.17,5.24 12,4.04zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2s0.06,1.34 0.14,2H4.26zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56C7.57,18.93 6.04,17.66 5.08,16zM8.03,8H5.08c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8z"
android:fillAlpha="0.3"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,19.3v-0.9l-3.37,-2.25v-2.47C18.63,13.3 18.35,13 18,13s-0.63,0.3 -0.63,0.68v2.47L14,18.4v0.9l3.37,-1.12v2.48l-0.84,0.68V22L18,21.55L19.47,22v-0.67l-0.84,-0.68v-2.48L22,19.3z"/>
</vector>

View File

@@ -1,28 +0,0 @@
<!--
Copyright (C) 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M2,12C2,6.48 6.47,2 11.99,2C17.52,2 22,6.48 22,12c0,0.34 -0.02,0.67 -0.05,1h-2.02c0.04,-0.33 0.07,-0.66 0.07,-1c0,-0.69 -0.1,-1.36 -0.26,-2h-3.38c0.08,0.66 0.14,1.32 0.14,2c0,0.34 -0.01,0.67 -0.04,1h-2.01c0.03,-0.33 0.05,-0.66 0.05,-1c0,-0.68 -0.07,-1.35 -0.16,-2H9.66c-0.09,0.65 -0.16,1.32 -0.16,2s0.07,1.34 0.16,2H13v2h-2.91c0.43,1.43 1.08,2.76 1.91,3.96V20h1v1.95C12.67,21.98 12.33,22 11.99,22C6.47,22 2,17.52 2,12zM15.97,8h2.95c-0.96,-1.65 -2.49,-2.93 -4.33,-3.56C15.19,5.55 15.65,6.75 15.97,8zM13.91,8C13.48,6.57 12.83,5.24 12,4.04c-0.83,1.2 -1.48,2.53 -1.91,3.96H13.91zM4,12c0,0.69 0.1,1.36 0.26,2h3.38c-0.08,-0.66 -0.14,-1.32 -0.14,-2s0.06,-1.34 0.14,-2H4.26C4.1,10.64 4,11.31 4,12zM8.03,16H5.08c0.96,1.66 2.49,2.93 4.33,3.56C8.81,18.45 8.35,17.25 8.03,16zM5.08,8h2.95c0.32,-1.25 0.78,-2.45 1.38,-3.56C7.57,5.07 6.04,6.34 5.08,8z"
android:fillAlpha="0.3"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
</vector>

View File

@@ -4041,7 +4041,7 @@
apps have access to location</item>
</plurals>
<!-- [CHAR LIMIT=50] Location settings screen, sub category for recent location access -->
<string name="location_category_recent_location_access">Past 24 hour access</string>
<string name="location_category_recent_location_access">Recent access</string>
<!-- Location settings screen, displayed when there're more than three recent location access apps [CHAR LIMIT=30] -->
<string name="location_recent_location_access_see_all">See all</string>
<!-- [CHAR LIMIT=30] Location settings screen, button to bring the user to view the details of recent location access -->
@@ -9687,7 +9687,7 @@
<string name="app_launch_domain_links_title">Opening links</string>
<string name="app_launch_open_domain_urls_title">Open supported links</string>
<!-- Preference title for Supported links open in this app. [CHAR LIMIT=60] -->
<string name="app_launch_top_intro_message">Supported links open in this app</string>
<string name="app_launch_top_intro_message">Allow web links to open in this app</string>
<!-- Preference title for Links to open in this app. [CHAR LIMIT=60] -->
<string name="app_launch_links_category">Links to open in this app</string>
@@ -10523,8 +10523,8 @@
associated with this device, including settings, permissions, corporate access,
network activity, and the device\'s location information.</string>
<!-- Shown in admin details page to warn user about policies the admin can set on a financed device. [CHAR LIMIT=NONE] -->
<string name="admin_financed_message">Your device admin may be able to access data associated
with this device and change this device\s settings.</string>
<string name="admin_financed_message">Your device administrator may be able to access data
associated with this device, manage apps, and change this device\s settings.</string>
<!-- Turn off a conditional state of the device (e.g. airplane mode, or hotspot) [CHAR LIMIT=30] -->
<string name="condition_turn_off">Turn off</string>

View File

@@ -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"/>
<PreferenceCategory

View File

@@ -33,6 +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.location.RecentLocationAccessSeeAllButtonPreferenceController"
settings:searchable="false"/>
<!-- This preference category gets removed if new_recent_location_ui is disabled -->

View File

@@ -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"/>

View File

@@ -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) {

View File

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

View File

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

View File

@@ -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<BatterySipper> 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 {

View File

@@ -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 {

View File

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

View File

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

View File

@@ -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

View File

@@ -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,

View File

@@ -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<String, Preference> 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<BatterySipper> 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<BatteryEntry> 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<BatterySipper> getCoalescedUsageList(final List<BatterySipper> sippers) {
final SparseArray<BatterySipper> uidList = new SparseArray<>();
private List<BatteryEntry> getCoalescedUsageList(boolean showAllApps) {
final SparseArray<BatteryEntry> batteryEntryList = new SparseArray<>();
final ArrayList<BatterySipper> 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<BatteryEntry> results = new ArrayList<>();
final List<UidBatteryConsumer> 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<SystemBatteryConsumer> 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<UserBatteryConsumer> 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<BatterySipper> getFakeStats() {
ArrayList<BatterySipper> 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) {

View File

@@ -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<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>();
static final HashMap<String, UidToDetail> sUidCache = new HashMap<>();
static final ArrayList<BatteryEntry> mRequestQueue = new ArrayList<BatteryEntry>();
static final ArrayList<BatteryEntry> sRequestQueue = new ArrayList<BatteryEntry>();
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<BatteryEntry> 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();
}
}
}

View File

@@ -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<BatterySipper> 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<BatterySipper> 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<BatterySipper> usageList) {
Collections.sort(usageList, new Comparator<BatterySipper>() {
@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<BatterySipper> 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;
}
}

View File

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

View File

@@ -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) {

View File

@@ -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
*/

View File

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

View File

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

View File

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

View File

@@ -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(

View File

@@ -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

View File

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

View File

@@ -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(

View File

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

View File

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

View File

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

View File

@@ -65,7 +65,7 @@ public class InternetPreferenceController extends AbstractPreferenceController i
@VisibleForTesting
static Map<Integer, Integer> 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);

View File

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

View File

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

View File

@@ -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<InetAddress> dnses = (lp == null) ? null : lp.getValidatedPrivateDnsServers();
final boolean dnsesResolved = !ArrayUtils.isEmpty(dnses);

View File

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

View File

@@ -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<Integer, PhoneStateListener> mListeners;
private Context mContext;
@VisibleForTesting
Map<Integer, SignalStrengthTelephonyCallback> 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<Integer> ids) {
Set<Integer> currentIds = new ArraySet<>(mListeners.keySet());
Set<Integer> 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));
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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.

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<PhoneStateListener> captor1 = ArgumentCaptor.forClass(
PhoneStateListener.class);
ArgumentCaptor<PhoneStateListener> 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<SignalStrengthListener.SignalStrengthTelephonyCallback> captor1 =
ArgumentCaptor.forClass(
SignalStrengthListener.SignalStrengthTelephonyCallback.class);
ArgumentCaptor<SignalStrengthListener.SignalStrengthTelephonyCallback> 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<PhoneStateListener> captor1 = ArgumentCaptor.forClass(
PhoneStateListener.class);
ArgumentCaptor<SignalStrengthListener.SignalStrengthTelephonyCallback> 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<PhoneStateListener> captor1 = ArgumentCaptor.forClass(
PhoneStateListener.class);
ArgumentCaptor<PhoneStateListener> captor2 = ArgumentCaptor.forClass(
PhoneStateListener.class);
ArgumentCaptor<SignalStrengthListener.SignalStrengthTelephonyCallback> captor1 =
ArgumentCaptor.forClass(
SignalStrengthListener.SignalStrengthTelephonyCallback.class);
ArgumentCaptor<SignalStrengthListener.SignalStrengthTelephonyCallback> 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<PhoneStateListener> captor1 = ArgumentCaptor.forClass(
PhoneStateListener.class);
ArgumentCaptor<PhoneStateListener> 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<SignalStrengthListener.SignalStrengthTelephonyCallback> captor1 =
ArgumentCaptor.forClass(
SignalStrengthListener.SignalStrengthTelephonyCallback.class);
ArgumentCaptor<SignalStrengthListener.SignalStrengthTelephonyCallback> 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();

View File

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

View File

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