Merge "Don't crash if we get a onRemove() callback from Fingerprint" into oc-dev
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index c29453f..86e3b16 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -60,11 +60,11 @@
<Preference
android:key="encryption_and_credential"
android:title="@string/encryption_and_credential_settings_title"
+ android:summary="@string/encryption_and_credential_settings_summary"/>
android:fragment="com.android.settings.EncryptionAndCredential"/>
<Preference android:key="manage_trust_agents"
android:title="@string/manage_trust_agents"
- android:summary="@string/manage_trust_agents_summary"
android:persistent="false"
android:fragment="com.android.settings.TrustAgentSettings"/>
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index b7d2a73..a56889d 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -40,7 +40,6 @@
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.CarrierConfigManager;
@@ -65,7 +64,6 @@
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.search2.SearchFeatureProvider;
import com.android.settings.security.OwnerInfoPreferenceController;
import com.android.settings.security.SecurityFeatureProvider;
import com.android.settings.trustagent.TrustAgentManager;
@@ -102,7 +100,8 @@
private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
private static final String KEY_SECURITY_CATEGORY = "security_category";
- private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
+ @VisibleForTesting
+ static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
private static final String KEY_UNIFICATION = "unification";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
@@ -312,11 +311,12 @@
mIsAdmin = mUm.isAdminUser();
// Fingerprint and trust agents
+ int numberOfTrustAgent = 0;
PreferenceGroup securityCategory = (PreferenceGroup)
root.findPreference(KEY_SECURITY_CATEGORY);
if (securityCategory != null) {
maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
- addTrustAgentSettings(securityCategory);
+ numberOfTrustAgent = addTrustAgentSettings(securityCategory);
}
mVisiblePatternProfile =
@@ -351,11 +351,7 @@
final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
// Advanced Security features
- Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS);
- if (manageAgents != null && !mLockPatternUtils.isSecure(MY_USER_ID)) {
- manageAgents.setEnabled(false);
- manageAgents.setSummary(R.string.disabled_because_no_backup_security);
- }
+ initTrustAgentPreference(root, numberOfTrustAgent);
// The above preferences come and go based on security state, so we need to update
// the index. This call is expected to be fairly cheap, but we may want to do something
@@ -410,6 +406,23 @@
return root;
}
+ @VisibleForTesting
+ void initTrustAgentPreference(PreferenceScreen root, int numberOfTrustAgent) {
+ Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS);
+ if (manageAgents != null) {
+ if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
+ manageAgents.setEnabled(false);
+ manageAgents.setSummary(R.string.disabled_because_no_backup_security);
+ } else if (numberOfTrustAgent > 0) {
+ manageAgents.setSummary(getActivity().getResources().getQuantityString(
+ R.plurals.manage_trust_agents_summary_on,
+ numberOfTrustAgent, numberOfTrustAgent));
+ } else {
+ manageAgents.setSummary(R.string.manage_trust_agents_summary);
+ }
+ }
+ }
+
/*
* Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
* The preference must be a RestrictedPreference.
@@ -434,7 +447,8 @@
}
}
- private void addTrustAgentSettings(PreferenceGroup securityCategory) {
+ // Return the number of trust agents being added
+ private int addTrustAgentSettings(PreferenceGroup securityCategory) {
final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
ArrayList<TrustAgentComponentInfo> agents = getActiveTrustAgents(
getActivity(), mTrustAgentManager, mLockPatternUtils, mDPM);
@@ -459,6 +473,7 @@
trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
}
}
+ return agents.size();
}
/* Return true if a there is a Slot that has Icc.
diff --git a/src/com/android/settings/applications/AdvancedAppSettings.java b/src/com/android/settings/applications/AdvancedAppSettings.java
index e59f94b..caa9da1 100644
--- a/src/com/android/settings/applications/AdvancedAppSettings.java
+++ b/src/com/android/settings/applications/AdvancedAppSettings.java
@@ -15,9 +15,11 @@
*/
package com.android.settings.applications;
+import android.app.Activity;
import android.content.Context;
import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
@@ -29,6 +31,7 @@
import com.android.settings.applications.defaultapps.DefaultWorkPhonePreferenceController;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -78,4 +81,55 @@
return Arrays.asList(sir);
}
};
+
+ static class SummaryProvider implements SummaryLoader.SummaryProvider {
+
+ private final Context mContext;
+ private final SummaryLoader mSummaryLoader;
+ private final DefaultSmsPreferenceController mDefaultSmsPreferenceController;
+ private final DefaultBrowserPreferenceController mDefaultBrowserPreferenceController;
+ private final DefaultPhonePreferenceController mDefaultPhonePreferenceController;
+
+ public SummaryProvider(Context context, SummaryLoader summaryLoader) {
+ mContext = context;
+ mSummaryLoader = summaryLoader;
+ mDefaultSmsPreferenceController = new DefaultSmsPreferenceController(mContext);
+ mDefaultBrowserPreferenceController = new DefaultBrowserPreferenceController(mContext);
+ mDefaultPhonePreferenceController = new DefaultPhonePreferenceController(mContext);
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ if (!listening) {
+ return;
+ }
+ CharSequence summary = concatSummaryText(
+ mDefaultSmsPreferenceController.getDefaultAppLabel(),
+ mDefaultBrowserPreferenceController.getDefaultAppLabel());
+ summary = concatSummaryText(summary,
+ mDefaultPhonePreferenceController.getDefaultAppLabel());
+ if (!TextUtils.isEmpty(summary)) {
+ mSummaryLoader.setSummary(this, summary);
+ }
+ }
+
+ private CharSequence concatSummaryText(CharSequence summary1, CharSequence summary2) {
+ if (TextUtils.isEmpty(summary1)) {
+ return summary2;
+ }
+ if (TextUtils.isEmpty(summary2)) {
+ return summary1;
+ }
+ return mContext.getString(R.string.join_many_items_middle, summary1, summary2);
+ }
+ }
+
+ public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
+ new SummaryLoader.SummaryProviderFactory() {
+ @Override
+ public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
+ SummaryLoader summaryLoader) {
+ return new AdvancedAppSettings.SummaryProvider(activity, summaryLoader);
+ }
+ };
}
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 9967918..0623562 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -91,7 +91,6 @@
import com.android.settings.datausage.DataUsageSummary;
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.BatteryEntry;
-import com.android.settings.fuelgauge.PowerUsageDetail;
import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.NotificationBackend.AppRow;
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
index 93fc6a6..b53a335 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPreferenceController.java
@@ -49,10 +49,7 @@
@Override
public void updateState(Preference preference) {
final DefaultAppInfo app = getDefaultAppInfo();
- CharSequence defaultAppLabel = null;
- if (app != null) {
- defaultAppLabel = app.loadLabel();
- }
+ CharSequence defaultAppLabel = getDefaultAppLabel();
if (!TextUtils.isEmpty(defaultAppLabel)) {
preference.setSummary(defaultAppLabel);
} else {
@@ -84,4 +81,15 @@
//By default return null. It's up to subclasses to provide logic.
return null;
}
+
+ public CharSequence getDefaultAppLabel() {
+ if (!isAvailable()) {
+ return null;
+ }
+ final DefaultAppInfo app = getDefaultAppInfo();
+ if (app != null) {
+ return app.loadLabel();
+ }
+ return null;
+ }
}
diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
index 661fb5b..5c0f9a3 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
@@ -51,13 +51,9 @@
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- final DefaultAppInfo defaultApp = getDefaultAppInfo();
- final CharSequence defaultAppLabel = defaultApp != null ? defaultApp.loadLabel() : null;
- if (TextUtils.isEmpty(defaultAppLabel)) {
- final String onlyAppLabel = getOnlyAppLabel();
- if (!TextUtils.isEmpty(onlyAppLabel)) {
- preference.setSummary(onlyAppLabel);
- }
+ final CharSequence defaultAppLabel = getDefaultAppLabel();
+ if (!TextUtils.isEmpty(defaultAppLabel)) {
+ preference.setSummary(defaultAppLabel);
}
}
@@ -72,6 +68,19 @@
}
}
+ @Override
+ public CharSequence getDefaultAppLabel() {
+ if (!isAvailable()) {
+ return null;
+ }
+ final DefaultAppInfo defaultApp = getDefaultAppInfo();
+ final CharSequence defaultAppLabel = defaultApp != null ? defaultApp.loadLabel() : null;
+ if (!TextUtils.isEmpty(defaultAppLabel)) {
+ return defaultAppLabel;
+ }
+ return getOnlyAppLabel();
+ }
+
private List<ResolveInfo> getCandidates() {
return mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE, PackageManager.MATCH_ALL,
mUserId);
diff --git a/src/com/android/settings/connecteddevice/UsbModePreferenceController.java b/src/com/android/settings/connecteddevice/UsbModePreferenceController.java
index 6c1a28b..a98f068 100644
--- a/src/com/android/settings/connecteddevice/UsbModePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/UsbModePreferenceController.java
@@ -20,6 +20,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbManager;
+import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
@@ -77,34 +78,19 @@
mUsbReceiver.register();
}
- public static int getSummary(int mode) {
+ @VisibleForTesting
+ int getSummary(int mode) {
switch (mode) {
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
- return R.string.usb_use_charging_only_desc;
+ return R.string.usb_summary_charging_only;
case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
- return R.string.usb_use_power_only_desc;
+ return R.string.usb_summary_power_only;
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
- return R.string.usb_use_file_transfers_desc;
+ return R.string.usb_summary_file_transfers;
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
- return R.string.usb_use_photo_transfers_desc;
+ return R.string.usb_summary_photo_transfers;
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
- return R.string.usb_use_MIDI_desc;
- }
- return 0;
- }
-
- public static int getTitle(int mode) {
- switch (mode) {
- case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
- return R.string.usb_use_charging_only;
- case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
- return R.string.usb_use_power_only;
- case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
- return R.string.usb_use_file_transfers;
- case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
- return R.string.usb_use_photo_transfers;
- case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
- return R.string.usb_use_MIDI;
+ return R.string.usb_summary_MIDI;
}
return 0;
}
@@ -117,7 +103,7 @@
if (preference != null) {
if (mUsbReceiver.isConnected()) {
preference.setEnabled(true);
- preference.setSummary(getTitle(mode));
+ preference.setSummary(getSummary(mode));
} else {
preference.setSummary(R.string.disconnected);
preference.setEnabled(false);
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index d1bb9d6..caac95f 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -76,8 +76,8 @@
import com.android.settings.deviceinfo.StorageSettings;
import com.android.settings.display.NightDisplaySettings;
import com.android.settings.enterprise.EnterprisePrivacySettings;
+import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.BatterySaverSettings;
-import com.android.settings.fuelgauge.PowerUsageDetail;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.gestures.AssistGestureSettings;
import com.android.settings.gestures.DoubleTapPowerSettings;
@@ -210,7 +210,7 @@
ZenModeEventRuleSettings.class.getName(),
ZenModeVisualInterruptionSettings.class.getName(),
ProcessStatsUi.class.getName(),
- PowerUsageDetail.class.getName(),
+ AdvancedPowerUsageDetail.class.getName(),
ProcessStatsSummary.class.getName(),
DrawOverlayDetails.class.getName(),
WriteSettingsDetails.class.getName(),
diff --git a/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java b/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java
index 5ac16d4..8ba3781 100644
--- a/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java
+++ b/src/com/android/settings/deviceinfo/UsbModeChooserActivity.java
@@ -31,6 +31,7 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -40,7 +41,6 @@
import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
-import com.android.settings.connecteddevice.UsbModePreferenceController;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -136,9 +136,9 @@
View v = mLayoutInflater.inflate(R.layout.restricted_radio_with_summary, container, false);
TextView titleView = (TextView) v.findViewById(android.R.id.title);
- titleView.setText(UsbModePreferenceController.getTitle(mode));
+ titleView.setText(getTitle(mode));
TextView summaryView = (TextView) v.findViewById(android.R.id.summary);
- summaryView.setText(UsbModePreferenceController.getSummary(mode));
+ updateSummary(summaryView, mode);
if (disallowedByAdmin) {
if (mEnforcedAdmin != null) {
@@ -178,4 +178,27 @@
}
}
+ @VisibleForTesting
+ static void updateSummary(TextView summaryView, int mode) {
+ if (mode == (UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE)) {
+ summaryView.setText(R.string.usb_use_power_only_desc);
+ }
+ }
+
+ @VisibleForTesting
+ static int getTitle(int mode) {
+ switch (mode) {
+ case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
+ return R.string.usb_use_charging_only;
+ case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
+ return R.string.usb_use_power_only;
+ case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
+ return R.string.usb_use_file_transfers;
+ case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
+ return R.string.usb_use_photo_transfers;
+ case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
+ return R.string.usb_use_MIDI;
+ }
+ return 0;
+ }
}
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 8be3b14..39b72cc 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -58,7 +58,6 @@
* 1. Detail battery usage information for app(i.e. usage time, usage amount)
* 2. Battery related controls for app(i.e uninstall, force stop)
*
- * This fragment will replace {@link PowerUsageDetail}
*/
public class AdvancedPowerUsageDetail extends PowerUsageBase implements
ButtonActionDialogFragment.AppButtonsDialogListener {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
deleted file mode 100644
index f0d0a10..0000000
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fuelgauge;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ApplicationErrorReport;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.UserHandle;
-import android.support.v14.preference.PreferenceFragment;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatterySipper.DrainType;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.internal.util.FastPrintWriter;
-import com.android.settings.AppHeader;
-import com.android.settings.DisplaySettings;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.Utils;
-import com.android.settings.applications.AppHeaderController;
-import com.android.settings.applications.InstalledAppDetails;
-import com.android.settings.applications.LayoutPreference;
-import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.core.PreferenceController;
-import com.android.settings.location.LocationSettings;
-import com.android.settings.network.NetworkDashboardFragment;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.wifi.WifiSettings;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO(b/35810915): Delete this page once ag/1971493 is done.
-public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickListener {
-
- // Note: Must match the sequence of the DrainType
- private static int[] sDrainTypeDesciptions = new int[] {
- R.string.battery_desc_standby,
- R.string.battery_desc_radio,
- R.string.battery_desc_voice,
- R.string.battery_desc_wifi,
- R.string.battery_desc_bluetooth,
- R.string.battery_desc_flashlight,
- R.string.battery_desc_display,
- R.string.battery_desc_apps,
- R.string.battery_desc_users,
- R.string.battery_desc_unaccounted,
- R.string.battery_desc_overcounted,
- R.string.battery_desc_camera,
- };
-
- public static void startBatteryDetailPage(SettingsActivity caller,
- PreferenceFragment fragment, BatteryStatsHelper helper, int statsType,
- BatteryEntry entry, boolean showLocationButton, boolean includeAppInfo) {
- // Initialize mStats if necessary.
- helper.getStats();
-
- final int dischargeAmount = helper.getStats().getDischargeAmount(statsType);
- Bundle args = new Bundle();
- args.putString(PowerUsageDetail.EXTRA_TITLE, entry.name);
- args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int)
- ((entry.sipper.totalPowerMah * dischargeAmount / helper.getTotalPower()) + .5));
- args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int)
- Math.ceil(entry.sipper.totalPowerMah * 100 / helper.getMaxPower()));
- args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, helper.getStatsPeriod());
- args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, entry.defaultPackageName);
- args.putInt(PowerUsageDetail.EXTRA_ICON_ID, entry.iconId);
- args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, entry.sipper.noCoveragePercent);
- if (entry.sipper.uidObj != null) {
- args.putInt(PowerUsageDetail.EXTRA_UID, entry.sipper.uidObj.getUid());
- }
- args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, entry.sipper.drainType);
- args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
- args.putBoolean(AppHeader.EXTRA_HIDE_INFO_BUTTON, !includeAppInfo);
-
- int userId = UserHandle.myUserId();
- int[] types;
- double[] values;
- switch (entry.sipper.drainType) {
- case APP:
- case USER:
- {
- BatteryStats.Uid uid = entry.sipper.uidObj;
- types = new int[] {
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_gps,
- R.string.usage_type_wifi_running,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_radio_active,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- R.string.usage_type_audio,
- R.string.usage_type_video,
- R.string.usage_type_camera,
- R.string.usage_type_flashlight,
- R.string.usage_type_computed_power,
- };
- values = new double[] {
- entry.sipper.cpuTimeMs,
- entry.sipper.cpuFgTimeMs,
- entry.sipper.wakeLockTimeMs,
- entry.sipper.gpsTimeMs,
- entry.sipper.wifiRunningTimeMs,
- entry.sipper.mobileRxPackets,
- entry.sipper.mobileTxPackets,
- entry.sipper.mobileActive,
- entry.sipper.wifiRxPackets,
- entry.sipper.wifiTxPackets,
- 0,
- 0,
- entry.sipper.cameraTimeMs,
- entry.sipper.flashlightTimeMs,
- entry.sipper.totalPowerMah,
- };
-
- if (entry.sipper.drainType == BatterySipper.DrainType.APP) {
- Writer result = new StringWriter();
- PrintWriter printWriter = new FastPrintWriter(result, false, 1024);
- helper.getStats().dumpLocked(caller, printWriter, "", helper.getStatsType(),
- uid.getUid());
- printWriter.flush();
- args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());
-
- result = new StringWriter();
- printWriter = new FastPrintWriter(result, false, 1024);
- helper.getStats().dumpCheckinLocked(caller, printWriter, helper.getStatsType(),
- uid.getUid());
- printWriter.flush();
- args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
- result.toString());
- if (uid.getUid() != 0) {
- userId = UserHandle.getUserId(uid.getUid());
- }
- }
- }
- break;
- case CELL:
- {
- types = new int[] {
- R.string.usage_type_on_time,
- R.string.usage_type_no_coverage,
- R.string.usage_type_radio_active,
- R.string.usage_type_computed_power,
- };
- values = new double[] {
- entry.sipper.usageTimeMs,
- entry.sipper.noCoveragePercent,
- entry.sipper.mobileActive,
- entry.sipper.totalPowerMah,
- };
- }
- break;
- case WIFI:
- {
- types = new int[] {
- R.string.usage_type_wifi_running,
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- R.string.usage_type_computed_power,
- };
- values = new double[] {
- entry.sipper.wifiRunningTimeMs,
- entry.sipper.cpuTimeMs,
- entry.sipper.cpuFgTimeMs,
- entry.sipper.wakeLockTimeMs,
- entry.sipper.mobileRxPackets,
- entry.sipper.mobileTxPackets,
- entry.sipper.wifiRxPackets,
- entry.sipper.wifiTxPackets,
- entry.sipper.totalPowerMah,
- };
- } break;
- case BLUETOOTH:
- {
- types = new int[] {
- R.string.usage_type_on_time,
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- R.string.usage_type_computed_power,
- };
- values = new double[] {
- entry.sipper.usageTimeMs,
- entry.sipper.cpuTimeMs,
- entry.sipper.cpuFgTimeMs,
- entry.sipper.wakeLockTimeMs,
- entry.sipper.mobileRxPackets,
- entry.sipper.mobileTxPackets,
- entry.sipper.wifiRxPackets,
- entry.sipper.wifiTxPackets,
- entry.sipper.totalPowerMah,
- };
- } break;
- case UNACCOUNTED:
- {
- types = new int[] {
- R.string.usage_type_total_battery_capacity,
- R.string.usage_type_computed_power,
- R.string.usage_type_actual_power,
- };
- values = new double[] {
- helper.getPowerProfile().getBatteryCapacity(),
- helper.getComputedPower(),
- helper.getMinDrainedPower(),
- };
- } break;
- case OVERCOUNTED:
- {
- types = new int[] {
- R.string.usage_type_total_battery_capacity,
- R.string.usage_type_computed_power,
- R.string.usage_type_actual_power,
- };
- values = new double[] {
- helper.getPowerProfile().getBatteryCapacity(),
- helper.getComputedPower(),
- helper.getMaxDrainedPower(),
- };
- } break;
- default:
- {
- types = new int[] {
- R.string.usage_type_on_time,
- R.string.usage_type_computed_power,
- };
- values = new double[] {
- entry.sipper.usageTimeMs,
- entry.sipper.totalPowerMah,
- };
- }
- }
- args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
- args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);
-
- caller.startPreferencePanelAsUser(fragment, PowerUsageDetail.class.getName(), args,
- R.string.details_title, null, new UserHandle(userId));
- }
-
- public static final int ACTION_DISPLAY_SETTINGS = 1;
- public static final int ACTION_WIFI_SETTINGS = 2;
- public static final int ACTION_BLUETOOTH_SETTINGS = 3;
- public static final int ACTION_WIRELESS_SETTINGS = 4;
- public static final int ACTION_APP_DETAILS = 5;
- public static final int ACTION_LOCATION_SETTINGS = 6;
- public static final int ACTION_FORCE_STOP = 7;
- public static final int ACTION_REPORT = 8;
-
- public static final int USAGE_SINCE_UNPLUGGED = 1;
- public static final int USAGE_SINCE_RESET = 2;
-
- public static final String EXTRA_TITLE = "title";
- public static final String EXTRA_PERCENT = "percent";
- public static final String EXTRA_GAUGE = "gauge";
- public static final String EXTRA_UID = "uid";
- public static final String EXTRA_USAGE_SINCE = "since";
- public static final String EXTRA_USAGE_DURATION = "duration";
- public static final String EXTRA_REPORT_DETAILS = "report_details";
- public static final String EXTRA_REPORT_CHECKIN_DETAILS = "report_checkin_details";
- public static final String EXTRA_DETAIL_TYPES = "types"; // Array of usage types (cpu, gps, etc)
- public static final String EXTRA_DETAIL_VALUES = "values"; // Array of doubles
- public static final String EXTRA_DRAIN_TYPE = "drainType"; // DrainType
- public static final String EXTRA_ICON_PACKAGE = "iconPackage"; // String
- public static final String EXTRA_NO_COVERAGE = "noCoverage";
- public static final String EXTRA_ICON_ID = "iconId"; // Int
- public static final String EXTRA_SHOW_LOCATION_BUTTON = "showLocationButton"; // Boolean
-
- private static final String TAG = "PowerUsageDetail";
-
- private static final String KEY_DETAILS_PARENT = "details_parent";
- private static final String KEY_CONTROLS_PARENT = "controls_parent";
- private static final String KEY_MESSAGES_PARENT = "messages_parent";
- private static final String KEY_PACKAGES_PARENT = "packages_parent";
- private static final String KEY_TWO_BUTTONS = "two_buttons";
- private static final String KEY_HIGH_POWER = "high_power";
-
- private PackageManager mPm;
- private DevicePolicyManager mDpm;
- private int[] mTypes;
- private int mUid;
- private double[] mValues;
- private Button mForceStopButton;
- private Button mReportButton;
- private BatterySipper.DrainType mDrainType;
- private double mNoCoverage; // Percentage of time that there was no coverage
- private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
-
- private PreferenceCategory mDetailsParent;
- private PreferenceCategory mControlsParent;
- private PreferenceCategory mMessagesParent;
- private PreferenceCategory mPackagesParent;
-
- private boolean mUsesGps;
- private boolean mShowLocationButton;
-
- private String[] mPackages;
-
- ApplicationInfo mApp;
- ComponentName mInstaller;
- private Preference mHighPower;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- Activity activity = getActivity();
- mPm = activity.getPackageManager();
- mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
-
- mDetailsParent = (PreferenceCategory) findPreference(KEY_DETAILS_PARENT);
- mControlsParent = (PreferenceCategory) findPreference(KEY_CONTROLS_PARENT);
- mMessagesParent = (PreferenceCategory) findPreference(KEY_MESSAGES_PARENT);
- mPackagesParent = (PreferenceCategory) findPreference(KEY_PACKAGES_PARENT);
-
- mPowerUsageFeatureProvider =
- FeatureFactory.getFactory(activity).getPowerUsageFeatureProvider(activity);
-
- createDetails();
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.FUELGAUGE_POWER_USAGE_DETAIL;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- checkForceStop();
- if (mHighPower != null) {
- mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
- }
-
- setupHeader();
- }
-
- @Override
- protected String getLogTag() {
- return TAG;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.power_usage_details;
- }
-
- @Override
- protected List<PreferenceController> getPreferenceControllers(Context context) {
- final List<PreferenceController> controllers = new ArrayList<>();
- final int uid = getArguments().getInt(EXTRA_UID, 0);
- controllers.add(new BackgroundActivityPreferenceController(context, uid));
-
- return controllers;
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (mHighPower != null) {
- mHighPower.setSummary(HighPowerDetail.getSummary(getActivity(), mApp.packageName));
- }
- }
-
- private void createDetails() {
- final Bundle args = getArguments();
- Context context = getActivity();
- mUid = args.getInt(EXTRA_UID, 0);
- mPackages = context.getPackageManager().getPackagesForUid(mUid);
- mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
- mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
- mShowLocationButton = args.getBoolean(EXTRA_SHOW_LOCATION_BUTTON);
-
- mTypes = args.getIntArray(EXTRA_DETAIL_TYPES);
- mValues = args.getDoubleArray(EXTRA_DETAIL_VALUES);
-
- LayoutPreference twoButtons = (LayoutPreference) findPreference(KEY_TWO_BUTTONS);
- mForceStopButton = (Button) twoButtons.findViewById(R.id.left_button);
- mReportButton = (Button) twoButtons.findViewById(R.id.right_button);
- mForceStopButton.setEnabled(false);
-
- if (mUid >= Process.FIRST_APPLICATION_UID) {
- mForceStopButton.setText(R.string.force_stop);
- mForceStopButton.setTag(ACTION_FORCE_STOP);
- mForceStopButton.setOnClickListener(this);
- mReportButton.setText(com.android.internal.R.string.report);
- mReportButton.setTag(ACTION_REPORT);
- mReportButton.setOnClickListener(this);
-
- if (mPackages != null && mPackages.length > 0) {
- try {
- mApp = context.getPackageManager().getApplicationInfo(
- mPackages[0], 0);
- } catch (NameNotFoundException e) {
- }
- } else {
- Log.d(TAG, "No packages!!");
- }
- // check if error reporting is enabled in secure settings
- int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
- android.provider.Settings.Global.SEND_ACTION_APP_ERROR, 0);
- if (enabled != 0) {
- if (mApp != null) {
- mInstaller = ApplicationErrorReport.getErrorReportReceiver(
- context, mPackages[0], mApp.flags);
- }
- mReportButton.setEnabled(mInstaller != null);
- } else {
- removePreference(KEY_TWO_BUTTONS);
- }
- if (mApp != null
- && PowerWhitelistBackend.getInstance().isWhitelisted(mApp.packageName)) {
- mHighPower = findPreference(KEY_HIGH_POWER);
- mHighPower.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- HighPowerDetail.show(PowerUsageDetail.this, mApp.packageName, 0, false);
- return true;
- }
- });
- } else {
- mControlsParent.removePreference(findPreference(KEY_HIGH_POWER));
- }
- } else {
- removePreference(KEY_TWO_BUTTONS);
- mControlsParent.removePreference(findPreference(KEY_HIGH_POWER));
- }
-
- refreshStats();
-
- fillDetailsSection();
- fillPackagesSection(mUid);
- fillControlsSection(mUid);
- fillMessagesSection(mUid);
- }
-
- private void setupHeader() {
- final Activity activity = getActivity();
- final Bundle args = getArguments();
- final String title = args.getString(EXTRA_TITLE);
- final int iconId = args.getInt(EXTRA_ICON_ID, 0);
- String pkg = args.getString(EXTRA_ICON_PACKAGE);
- Drawable appIcon = null;
- int uid = -1;
- final PackageManager pm = activity.getPackageManager();
-
- if (!TextUtils.isEmpty(pkg)) {
- try {
- ApplicationInfo ai = pm.getPackageInfo(pkg, 0).applicationInfo;
- if (ai != null) {
- appIcon = ai.loadIcon(pm);
- uid = ai.uid;
- }
- } catch (NameNotFoundException nnfe) {
- // Use default icon
- }
- } else if (iconId != 0) {
- appIcon = activity.getDrawable(iconId);
- }
- if (appIcon == null) {
- appIcon = activity.getPackageManager().getDefaultActivityIcon();
- }
-
- if (pkg == null && mPackages != null) {
- pkg = mPackages[0];
- }
- final PreferenceScreen screen = getPreferenceScreen();
- final Preference appHeaderPref =
- findPreference(AppHeaderController.PREF_KEY_APP_HEADER);
- if (appHeaderPref != null) {
- return;
- }
- final Preference pref = FeatureFactory.getFactory(activity)
- .getApplicationFeatureProvider(activity)
- .newAppHeaderController(this, null /* appHeader */)
- .setIcon(appIcon)
- .setLabel(title)
- .setPackageName(pkg)
- .setUid(uid)
- .setButtonActions(AppHeaderController.ActionType.ACTION_APP_INFO,
- AppHeaderController.ActionType.ACTION_NONE)
- .done(getPrefContext());
- screen.addPreference(pref);
- }
-
- @Override
- public void onClick(View v) {
- doAction((Integer) v.getTag());
- }
-
- // utility method used to start sub activity
- private void startApplicationDetailsActivity() {
- // start new fragment to display extended information
- Bundle args = new Bundle();
- args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackages[0]);
-
- SettingsActivity sa = (SettingsActivity) getActivity();
- sa.startPreferencePanel(this, InstalledAppDetails.class.getName(), args,
- R.string.application_info_label, null, null, 0);
- }
-
- private void doAction(int action) {
- SettingsActivity sa = (SettingsActivity)getActivity();
- switch (action) {
- case ACTION_DISPLAY_SETTINGS:
- sa.startPreferencePanel(this, DisplaySettings.class.getName(), null,
- R.string.display_settings_title, null, null, 0);
- break;
- case ACTION_WIFI_SETTINGS:
- sa.startPreferencePanel(this, WifiSettings.class.getName(), null,
- R.string.wifi_settings, null, null, 0);
- break;
- case ACTION_BLUETOOTH_SETTINGS:
- sa.startPreferencePanel(this, BluetoothSettings.class.getName(), null,
- R.string.bluetooth_settings, null, null, 0);
- break;
- case ACTION_WIRELESS_SETTINGS:
- sa.startPreferencePanel(this, NetworkDashboardFragment.class.getName(), null,
- R.string.radio_controls_title, null, null, 0);
- break;
- case ACTION_APP_DETAILS:
- startApplicationDetailsActivity();
- break;
- case ACTION_LOCATION_SETTINGS:
- sa.startPreferencePanel(this, LocationSettings.class.getName(), null,
- R.string.location_settings_title, null, null, 0);
- break;
- case ACTION_FORCE_STOP:
- killProcesses();
- break;
- case ACTION_REPORT:
- reportBatteryUse();
- break;
- }
- }
-
- private void fillDetailsSection() {
- if (mTypes != null && mValues != null) {
- for (int i = 0; i < mTypes.length; i++) {
- // Only add an item if the time is greater than zero
- if (mValues[i] <= 0) continue;
- final String label = getString(mTypes[i]);
- String value = null;
- switch (mTypes[i]) {
- case R.string.usage_type_data_recv:
- case R.string.usage_type_data_send:
- case R.string.usage_type_data_wifi_recv:
- case R.string.usage_type_data_wifi_send:
- final long packets = (long) (mValues[i]);
- value = Long.toString(packets);
- break;
- case R.string.usage_type_no_coverage:
- final int percentage = (int) Math.floor(mValues[i]);
- value = Utils.formatPercentage(percentage);
- break;
- case R.string.usage_type_total_battery_capacity:
- case R.string.usage_type_computed_power:
- case R.string.usage_type_actual_power:
- value = getActivity().getString(R.string.mah, (long)(mValues[i]));
- break;
- case R.string.usage_type_gps:
- mUsesGps = true;
- // Fall through
- default:
- value = Utils.formatElapsedTime(getActivity(), mValues[i], true);
- }
- addHorizontalPreference(mDetailsParent, label, value);
- }
- }
- }
-
- private void addHorizontalPreference(PreferenceCategory parent, CharSequence title,
- CharSequence summary) {
- Preference pref = new Preference(getPrefContext());
- pref.setLayoutResource(R.layout.horizontal_preference);
- pref.setTitle(title);
- pref.setSummary(summary);
- pref.setSelectable(false);
- parent.addPreference(pref);
- }
-
- private void fillControlsSection(int uid) {
- PackageManager pm = getActivity().getPackageManager();
- String[] packages = pm.getPackagesForUid(uid);
- PackageInfo pi = null;
- try {
- pi = packages != null ? pm.getPackageInfo(packages[0], 0) : null;
- } catch (NameNotFoundException nnfe) { /* Nothing */ }
- ApplicationInfo ai = pi != null? pi.applicationInfo : null;
-
- boolean removeHeader = true;
- switch (mDrainType) {
- case APP:
- // If it is a Java application and only one package is associated with the Uid
- if (packages != null && packages.length == 1) {
- addControl(R.string.battery_action_app_details,
- R.string.battery_sugg_apps_info, ACTION_APP_DETAILS);
- removeHeader = false;
- // If the application has a settings screen, jump to that
- // TODO:
- }
-
- // If power usage detail page is launched from location page, suppress "Location"
- // button to prevent circular loops.
- if (mUsesGps && mShowLocationButton
- && mPowerUsageFeatureProvider.isLocationSettingEnabled(packages)) {
- addControl(R.string.location_settings_title,
- R.string.battery_sugg_apps_gps, ACTION_LOCATION_SETTINGS);
- removeHeader = false;
- }
- break;
- case SCREEN:
- addControl(R.string.display_settings,
- R.string.battery_sugg_display,
- ACTION_DISPLAY_SETTINGS);
- removeHeader = false;
- break;
- case WIFI:
- addControl(R.string.wifi_settings,
- R.string.battery_sugg_wifi,
- ACTION_WIFI_SETTINGS);
- removeHeader = false;
- break;
- case BLUETOOTH:
- addControl(R.string.bluetooth_settings,
- R.string.battery_sugg_bluetooth_basic,
- ACTION_BLUETOOTH_SETTINGS);
- removeHeader = false;
- break;
- case CELL:
- if (mNoCoverage > 10) {
- addControl(R.string.radio_controls_title,
- R.string.battery_sugg_radio,
- ACTION_WIRELESS_SETTINGS);
- removeHeader = false;
- }
- break;
- }
- if (removeHeader) {
- mControlsParent.setTitle(null);
- }
- }
-
- private void addControl(int pageSummary, int actionTitle, final int action) {
- Preference pref = new Preference(getPrefContext());
- pref.setTitle(actionTitle);
- pref.setLayoutResource(R.layout.horizontal_preference);
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- doAction(action);
- return true;
- }
- });
- mControlsParent.addPreference(pref);
- }
-
- private void fillMessagesSection(int uid) {
- boolean removeHeader = true;
- switch (mDrainType) {
- case UNACCOUNTED:
- addMessage(R.string.battery_msg_unaccounted);
- removeHeader = false;
- break;
- }
- if (removeHeader) {
- mMessagesParent.setTitle(null);
- }
- }
-
- private void addMessage(int message) {
- addHorizontalPreference(mMessagesParent, getString(message), null);
- }
-
- private void removePackagesSection() {
- getPreferenceScreen().removePreference(mPackagesParent);
- }
-
- private void killProcesses() {
- if (mPackages == null) return;
- ActivityManager am = (ActivityManager)getActivity().getSystemService(
- Context.ACTIVITY_SERVICE);
- final int userId = UserHandle.getUserId(mUid);
- for (int i = 0; i < mPackages.length; i++) {
- am.forceStopPackageAsUser(mPackages[i], userId);
- }
- checkForceStop();
- }
-
- private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
- }
- };
-
- private void checkForceStop() {
- if (mPackages == null || mUid < Process.FIRST_APPLICATION_UID) {
- mForceStopButton.setEnabled(false);
- return;
- }
- for (int i = 0; i < mPackages.length; i++) {
- if (mDpm.packageHasActiveAdmins(mPackages[i])) {
- mForceStopButton.setEnabled(false);
- return;
- }
- }
- for (int i = 0; i < mPackages.length; i++) {
- try {
- ApplicationInfo info = mPm.getApplicationInfo(mPackages[i], 0);
- if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
- mForceStopButton.setEnabled(true);
- break;
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
- Uri.fromParts("package", mPackages[0], null));
- intent.putExtra(Intent.EXTRA_PACKAGES, mPackages);
- intent.putExtra(Intent.EXTRA_UID, mUid);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mUid));
- getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
- Activity.RESULT_CANCELED, null, null);
- }
-
- private void reportBatteryUse() {
- if (mPackages == null) return;
-
- ApplicationErrorReport report = new ApplicationErrorReport();
- report.type = ApplicationErrorReport.TYPE_BATTERY;
- report.packageName = mPackages[0];
- report.installerPackageName = mInstaller.getPackageName();
- report.processName = mPackages[0];
- report.time = System.currentTimeMillis();
- report.systemApp = (mApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-
- final Bundle args = getArguments();
- ApplicationErrorReport.BatteryInfo batteryInfo = new ApplicationErrorReport.BatteryInfo();
- batteryInfo.usagePercent = args.getInt(EXTRA_PERCENT, 1);
- batteryInfo.durationMicros = args.getLong(EXTRA_USAGE_DURATION, 0);
- batteryInfo.usageDetails = args.getString(EXTRA_REPORT_DETAILS);
- batteryInfo.checkinDetails = args.getString(EXTRA_REPORT_CHECKIN_DETAILS);
- report.batteryInfo = batteryInfo;
-
- Intent result = new Intent(Intent.ACTION_APP_ERROR);
- result.setComponent(mInstaller);
- result.putExtra(Intent.EXTRA_BUG_REPORT, report);
- result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(result);
- }
-
- private void fillPackagesSection(int uid) {
- if (uid < 1) {
- removePackagesSection();
- return;
- }
- if (mPackages == null || mPackages.length < 2) {
- removePackagesSection();
- return;
- }
-
- PackageManager pm = getPackageManager();
- // Convert package names to user-facing labels where possible
- for (int i = 0; i < mPackages.length; i++) {
- try {
- ApplicationInfo ai = pm.getApplicationInfo(mPackages[i], 0);
- CharSequence label = ai.loadLabel(pm);
- if (label != null) {
- mPackages[i] = label.toString();
- }
- addHorizontalPreference(mPackagesParent, mPackages[i], null);
- } catch (NameNotFoundException e) {
- }
- }
- }
-}
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index f8cedc1..f7882ae 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -50,7 +50,6 @@
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.BatterySaverSettings;
import com.android.settings.fuelgauge.PowerUsageAdvanced;
-import com.android.settings.fuelgauge.PowerUsageDetail;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.gestures.AssistGestureSettings;
import com.android.settings.gestures.DoubleTapPowerSettings;
@@ -126,7 +125,6 @@
addIndex(StorageSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_storage);
addIndex(PowerUsageSummary.class,
R.xml.power_usage_summary, R.drawable.ic_settings_battery);
- addIndex(PowerUsageDetail.class, NO_DATA_RES_ID, R.drawable.ic_settings_battery);
addIndex(PowerUsageAdvanced.class, NO_DATA_RES_ID, R.drawable.ic_settings_battery);
addIndex(BatterySaverSettings.class,
R.xml.battery_saver_settings, R.drawable.ic_settings_battery);
diff --git a/tests/app/src/com/android/settings/DisplaySettingsTest.java b/tests/app/src/com/android/settings/DisplaySettingsTest.java
new file mode 100644
index 0000000..888b7fd
--- /dev/null
+++ b/tests/app/src/com/android/settings/DisplaySettingsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 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;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DisplaySettingsTest {
+
+ private Instrumentation mInstrumentation;
+ private Context mContext;
+ private UiDevice mDevice;
+
+ @Before
+ public void setUp() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mContext = mInstrumentation.getTargetContext();
+ mDevice = UiDevice.getInstance(mInstrumentation);
+ }
+
+ @Test
+ public void launchBrightnessLevel_shouldNotCrash() {
+ mInstrumentation.startActivitySync(
+ new Intent(mContext, DisplaySettings.class));
+ onView(withText(mContext.getString(R.string.brightness))).perform(click());
+ // should not crash
+ mDevice.pressBack(); // dismiss the brightness dialog
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
index 03a8f94..91111a8 100644
--- a/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/SecuritySettingsTest.java
@@ -16,13 +16,17 @@
package com.android.settings;
+import android.app.Activity;
import android.content.Context;
import android.content.IContentProvider;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowSecureSettings;
@@ -39,13 +43,17 @@
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
import java.util.Map;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -121,7 +129,6 @@
verify(mContext).getString(R.string.security_dashboard_summary);
}
-
@Test
public void testGetPackageVerifierSummary_nullInput() {
assertThat(mSummaryProvider.getPackageVerifierSummary(null)).isNull();
@@ -155,4 +162,28 @@
assertThat(mSummaryProvider.getPackageVerifierSummary(mDashboardCategory))
.isEqualTo(MOCK_SUMMARY);
}
+
+ @Test
+ public void testInitTrustAgentPreference_secure_shouldSetSummaryToNumberOfTrustAgent() {
+ final Preference preference = mock(Preference.class);
+ final PreferenceScreen screen = mock(PreferenceScreen.class);
+ when(screen.findPreference(SecuritySettings.KEY_MANAGE_TRUST_AGENTS))
+ .thenReturn(preference);
+ final LockPatternUtils utils = mock(LockPatternUtils.class);
+ when(utils.isSecure(anyInt())).thenReturn(true);
+ final Context context = ShadowApplication.getInstance().getApplicationContext();
+ final Activity activity = mock(Activity.class);
+ when(activity.getResources()).thenReturn(context.getResources());
+ final SecuritySettings securitySettings = spy(new SecuritySettings());
+ when(securitySettings.getActivity()).thenReturn(activity);
+
+ ReflectionHelpers.setField(securitySettings, "mLockPatternUtils", utils);
+
+ securitySettings.initTrustAgentPreference(screen, 0);
+ verify(preference).setSummary(R.string.manage_trust_agents_summary);
+
+ securitySettings.initTrustAgentPreference(screen, 2);
+ verify(preference).setSummary(context.getResources().getQuantityString(
+ R.plurals.manage_trust_agents_summary_on, 2, 2));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java b/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
index b8f3fc4..bedb0a5 100644
--- a/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AdvancedAppSettingsTest.java
@@ -22,22 +22,30 @@
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
+import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
+import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
+import com.android.settings.dashboard.SummaryLoader;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AdvancedAppSettingsTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
private AdvancedAppSettings mFragment;
@@ -46,8 +54,9 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mFragment = new AdvancedAppSettings();
- mFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
+ mFragment.onAttach(mContext);
}
@Test
@@ -56,4 +65,75 @@
R.xml.app_default_settings);
}
+ @Test
+ public void setListening_shouldUpdateSummary() {
+ final SummaryLoader summaryLoader = mock(SummaryLoader.class);
+ final AdvancedAppSettings.SummaryProvider summaryProvider =
+ new AdvancedAppSettings.SummaryProvider(mContext, summaryLoader);
+ final DefaultSmsPreferenceController defaultSms =
+ mock(DefaultSmsPreferenceController.class);
+ final DefaultBrowserPreferenceController defaultBrowser =
+ mock(DefaultBrowserPreferenceController.class);
+ final DefaultPhonePreferenceController defaultPhone =
+ mock(DefaultPhonePreferenceController.class);
+ ReflectionHelpers.setField(summaryProvider, "mDefaultSmsPreferenceController", defaultSms);
+ ReflectionHelpers.setField(
+ summaryProvider, "mDefaultBrowserPreferenceController", defaultBrowser);
+ ReflectionHelpers.setField(
+ summaryProvider, "mDefaultPhonePreferenceController", defaultPhone);
+
+ // all available
+ when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1");
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1");
+ when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1");
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Sms1, Browser1, Phone1");
+
+ // 2 available
+ when(defaultSms.getDefaultAppLabel()).thenReturn(null);
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1");
+ when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1");
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Browser1, Phone1");
+
+ when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1");
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn(null);
+ when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1");
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Sms1, Phone1");
+
+ when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1");
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1");
+ when(defaultPhone.getDefaultAppLabel()).thenReturn(null);
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Sms1, Browser1");
+
+ // 1 available
+ when(defaultSms.getDefaultAppLabel()).thenReturn(null);
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn("Browser1");
+ when(defaultPhone.getDefaultAppLabel()).thenReturn(null);
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Browser1");
+
+ when(defaultSms.getDefaultAppLabel()).thenReturn("Sms1");
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn(null);
+ when(defaultPhone.getDefaultAppLabel()).thenReturn(null);
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Sms1");
+
+ when(defaultSms.getDefaultAppLabel()).thenReturn(null);
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn(null);
+ when(defaultPhone.getDefaultAppLabel()).thenReturn("Phone1");
+ summaryProvider.setListening(true);
+ verify(summaryLoader).setSummary(summaryProvider, "Phone1");
+
+ // None available
+ when(defaultSms.getDefaultAppLabel()).thenReturn(null);
+ when(defaultBrowser.getDefaultAppLabel()).thenReturn(null);
+ when(defaultPhone.getDefaultAppLabel()).thenReturn(null);
+ summaryProvider.setListening(true);
+ verify(summaryLoader, never()).setSummary(summaryProvider, eq(anyString()));
+
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java
index 8b6e900..4b84b0f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/UsbModePreferenceControllerTest.java
@@ -48,62 +48,32 @@
@Test
public void testGetSummary_chargeDevice() {
- assertThat(UsbModePreferenceController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[0]))
- .isEqualTo(R.string.usb_use_charging_only_desc);
+ assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[0]))
+ .isEqualTo(R.string.usb_summary_charging_only);
}
@Test
public void testGetSummary_supplyPower() {
- assertThat(UsbModePreferenceController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[1]))
- .isEqualTo(R.string.usb_use_power_only_desc);
+ assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[1]))
+ .isEqualTo(R.string.usb_summary_power_only);
}
@Test
public void testGetSummary_TransferFiles() {
- assertThat(UsbModePreferenceController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[2]))
- .isEqualTo(R.string.usb_use_file_transfers_desc);
+ assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[2]))
+ .isEqualTo(R.string.usb_summary_file_transfers);
}
@Test
public void testGetSummary_TransferPhoto() {
- assertThat(UsbModePreferenceController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[3]))
- .isEqualTo(R.string.usb_use_photo_transfers_desc);
+ assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[3]))
+ .isEqualTo(R.string.usb_summary_photo_transfers);
}
@Test
public void testGetSummary_MIDI() {
- assertThat(UsbModePreferenceController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[4]))
- .isEqualTo(R.string.usb_use_MIDI_desc);
- }
-
- @Test
- public void testGetTitle_chargeDevice() {
- assertThat(UsbModePreferenceController.getTitle(UsbModeChooserActivity.DEFAULT_MODES[0]))
- .isEqualTo(R.string.usb_use_charging_only);
- }
-
- @Test
- public void testGetTitle_supplyPower() {
- assertThat(UsbModePreferenceController.getTitle(UsbModeChooserActivity.DEFAULT_MODES[1]))
- .isEqualTo(R.string.usb_use_power_only);
- }
-
- @Test
- public void testGetTitle_TransferFiles() {
- assertThat(UsbModePreferenceController.getTitle(UsbModeChooserActivity.DEFAULT_MODES[2]))
- .isEqualTo(R.string.usb_use_file_transfers);
- }
-
- @Test
- public void testGetTitle_TransferPhoto() {
- assertThat(UsbModePreferenceController.getTitle(UsbModeChooserActivity.DEFAULT_MODES[3]))
- .isEqualTo(R.string.usb_use_photo_transfers);
- }
-
- @Test
- public void testGetTitle_MIDI() {
- assertThat(UsbModePreferenceController.getTitle(UsbModeChooserActivity.DEFAULT_MODES[4]))
- .isEqualTo(R.string.usb_use_MIDI);
+ assertThat(mController.getSummary(UsbModeChooserActivity.DEFAULT_MODES[4]))
+ .isEqualTo(R.string.usb_summary_MIDI);
}
@Test
@@ -131,7 +101,7 @@
mContext.sendStickyBroadcast(intent);
assertThat(preference.getSummary()).isEqualTo(
- mContext.getString(R.string.usb_use_charging_only));
+ mContext.getString(R.string.usb_summary_charging_only));
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java b/tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java
new file mode 100644
index 0000000..d9c474d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/UsbModeChooserActivityTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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.deviceinfo;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.widget.TextView;
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class UsbModeChooserActivityTest {
+
+ @Mock
+ private TextView mTextView;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void updateSummary_chargeDevice_shouldNotSetSummary() {
+ UsbModeChooserActivity.updateSummary(mTextView, UsbModeChooserActivity.DEFAULT_MODES[0]);
+ verify(mTextView, never()).setText(anyInt());
+ }
+
+ @Test
+ public void updateSummary_supplyPower_shouldSetSummary() {
+ UsbModeChooserActivity.updateSummary(mTextView, UsbModeChooserActivity.DEFAULT_MODES[1]);
+ verify(mTextView).setText(R.string.usb_use_power_only_desc);
+ }
+
+ @Test
+ public void updateSummary_transferFiles_shouldNotSetSummary() {
+ UsbModeChooserActivity.updateSummary(mTextView, UsbModeChooserActivity.DEFAULT_MODES[2]);
+ verify(mTextView, never()).setText(anyInt());
+ }
+
+ @Test
+ public void updateSummary_transferPhoto_shouldNotSetSummary() {
+ UsbModeChooserActivity.updateSummary(mTextView, UsbModeChooserActivity.DEFAULT_MODES[3]);
+ verify(mTextView, never()).setText(anyInt());
+ }
+
+ @Test
+ public void updateSummary_MIDI_shouldNotSetSummary() {
+ UsbModeChooserActivity.updateSummary(mTextView, UsbModeChooserActivity.DEFAULT_MODES[4]);
+ verify(mTextView, never()).setText(anyInt());
+ }
+
+ @Test
+ public void getTitle_shouldReturnCorrectTitle() {
+ assertThat(UsbModeChooserActivity.getTitle(UsbModeChooserActivity.DEFAULT_MODES[0]))
+ .isEqualTo(R.string.usb_use_charging_only);
+
+ assertThat(UsbModeChooserActivity.getTitle(UsbModeChooserActivity.DEFAULT_MODES[1]))
+ .isEqualTo(R.string.usb_use_power_only);
+
+ assertThat(UsbModeChooserActivity.getTitle(UsbModeChooserActivity.DEFAULT_MODES[2]))
+ .isEqualTo(R.string.usb_use_file_transfers);
+
+ assertThat(UsbModeChooserActivity.getTitle(UsbModeChooserActivity.DEFAULT_MODES[3]))
+ .isEqualTo(R.string.usb_use_photo_transfers);
+
+ assertThat(UsbModeChooserActivity.getTitle(UsbModeChooserActivity.DEFAULT_MODES[4]))
+ .isEqualTo(R.string.usb_use_MIDI);
+ }
+
+}
\ No newline at end of file