Snap for 7216111 from 036dc189b6 to sc-v2-release
Change-Id: Ie434dfa80dc130f06cc3574b828e055f1e39ad7c
This commit is contained in:
28
res/drawable/ic_no_internet_airplane.xml
Normal file
28
res/drawable/ic_no_internet_airplane.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user