Snap for 7333400 from deb2acc9b3 to sc-release

Change-Id: I470d46369f4b4c53690444763e8631ecd3a84e5b
This commit is contained in:
android-build-team Robot
2021-05-04 01:08:32 +00:00
63 changed files with 1534 additions and 604 deletions

View File

@@ -76,6 +76,9 @@
<com.android.settings.accessibility.BalanceSeekBar
android:id="@*android:id/seekbar"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

View File

@@ -26,7 +26,7 @@
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<LinearLayout
android:id="@+id/icon_container"
android:id="@+id/icon_frame"
android:layout_width="56dp"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"

View File

@@ -980,9 +980,9 @@
<string name="biometric_settings_category_ways_to_unlock">Ways to unlock</string>
<!-- Biometric category title - configuration options for using biometric to unlock the device or authenticate in apps. [CHAR LIMIT=50] -->
<string name="biometric_settings_category_ways_to_use">Use face and fingerprint to</string>
<!-- Text shown on a toggle which allows or disallows the device to use biometric for unlocking the device. [CHAR LIMIT=20] -->
<!-- Text shown on a toggle which allows or disallows the device to use biometric for unlocking the device. [CHAR LIMIT=50] -->
<string name="biometric_settings_use_biometric_unlock_phone">Unlocking your phone</string>
<!-- Text shown on a toggle which allows or disallows the device to use biometric for authentication. [CHAR LIMIT=30] -->
<!-- Text shown on a toggle which allows or disallows the device to use biometric for authentication. [CHAR LIMIT=50] -->
<string name="biometric_settings_use_biometric_for_apps">Authentication in apps</string>
<!-- Title of dialog shown when the user tries to skip setting up a screen lock, warning them of potential consequences of not doing so [CHAR LIMIT=30]-->

View File

@@ -715,8 +715,8 @@
parent="@*android:style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">56dp</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:paddingEnd">8dp</item>
<item name="android:paddingStart">8dp</item>
<item name="android:background">?android:attr/selectableItemBackground</item>
</style>

View File

@@ -60,10 +60,11 @@
settings:allowDividerBelow="true"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController" />
<com.android.settingslib.widget.FooterPreference
android:key="autoclick_footer"
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="accessibility_autoclick_footer"
android:title="@string/accessibility_autoclick_description"
android:persistent="false"
android:selectable="false"
settings:searchable="false" />
settings:searchable="false"
settings:controller="com.android.settings.accessibility.ToggleAutoclickFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -59,11 +59,11 @@
android:persistent="false"
settings:controller="com.android.settings.accessibility.FloatingMenuOpacityPreferenceController"/>
<com.android.settingslib.widget.FooterPreference
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="accessibility_button_footer"
android:title="@string/accessibility_button_description"
android:persistent="false"
android:selectable="false"
settings:searchable="false"
android:persistent="false"/>
</PreferenceScreen>
settings:controller="com.android.settings.accessibility.AccessibilityButtonFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -55,8 +55,11 @@
android:title="@string/accessibility_timeout_2mins"
android:persistent="false" />
<com.android.settingslib.widget.FooterPreference
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="accessibility_control_timeout_footer"
android:title="@string/accessibility_control_timeout_preference_summary"
android:selectable="false" />
android:persistent="false"
android:selectable="false"
settings:searchable="false"
settings:controller="com.android.settings.accessibility.AccessibilityControlTimeoutFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -87,8 +87,11 @@
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="captioning_appearance_footer"
android:title="@string/accessibility_caption_preference_summary"
android:selectable="false"/>
android:persistent="false"
android:selectable="false"
settings:searchable="false"
settings:controller="com.android.settings.accessibility.CaptionFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -25,8 +25,12 @@
android:summary="%s"
android:title="@string/captioning_locale" />
<com.android.settingslib.widget.FooterPreference
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="captioning_more_options_footer"
android:title="@string/accessibility_caption_preference_summary"
android:selectable="false" />
android:persistent="false"
android:selectable="false"
settings:searchable="false"
settings:controller="com.android.settings.accessibility.CaptionFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -47,10 +47,12 @@
android:persistent="false"
android:title="@string/captioning_more_options_title" />
<com.android.settingslib.widget.FooterPreference
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="captioning_settings_footer"
android:title="@string/accessibility_caption_preference_summary"
android:persistent="false"
android:selectable="false"
android:title="@string/accessibility_caption_preference_summary"
settings:searchable="false"/>
settings:searchable="false"
settings:controller="com.android.settings.accessibility.CaptionFooterPreferenceController"/>
</PreferenceScreen>

View File

@@ -41,7 +41,6 @@
android:key="app_and_notif_cell_broadcast_settings"
android:title="@string/cell_broadcast_settings"
android:order="200"
settings:iconSpaceReserved="true"
settings:useAdminDisabledSummary="true">
<intent
android:action="android.intent.action.MAIN"

View File

@@ -55,7 +55,7 @@
<com.android.settingslib.widget.FooterPreference
android:key="app_usage_footer_preference"
android:title="@string/manager_battery_usage_footer"
android:selectable="true"
android:selectable="false"
settings:searchable="false"/>
</PreferenceScreen>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
<!-- 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.
@@ -17,7 +17,6 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:key="power_usage_summary_screen"
android:title="@string/power_usage_summary_title"
settings:keywords="@string/keywords_battery">
@@ -43,28 +42,24 @@
android:fragment="com.android.settings.fuelgauge.PowerUsageAdvanced"
android:key="battery_usage_summary"
android:title="@string/advanced_battery_preference_title"
app:iconSpaceReserved="false"
settings:searchable="false" />
<Preference
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
android:key="battery_saver_summary"
android:title="@string/battery_saver"
app:iconSpaceReserved="false"
settings:controller="com.android.settings.fuelgauge.BatterySaverController" />
<Preference
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
android:key="smart_battery_manager"
android:title="@string/smart_battery_manager_title"
app:iconSpaceReserved="false"
settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController" />
<SwitchPreference
android:key="battery_percentage"
android:title="@string/battery_percentage"
android:summary="@string/battery_percentage_description"
app:iconSpaceReserved="false"
settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
<com.android.settingslib.widget.FooterPreference

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import com.android.settings.R;
/**
* Preference controller for accessibility button footer.
*/
public class AccessibilityButtonFooterPreferenceController extends
AccessibilityFooterPreferenceController {
public AccessibilityButtonFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected String getLabelName() {
return mContext.getString(R.string.accessibility_button_title);
}
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.accessibility;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -35,11 +34,6 @@ public class AccessibilityButtonFragment extends DashboardFragment {
return R.xml.accessibility_button_settings;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
protected String getLogTag() {
return TAG;

View File

@@ -43,7 +43,7 @@ public class AccessibilityButtonLocationPreferenceController extends BasePrefere
@Override
public int getAvailabilityStatus() {
return AccessibilityUtil.isGestureNavigateEnabled(mContext)
? DISABLED_DEPENDENT_SETTING : AVAILABLE;
? CONDITIONALLY_UNAVAILABLE : AVAILABLE;
}
@Override

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import com.android.settings.R;
/**
* Preference controller for accessibility control timeout footer.
*/
public class AccessibilityControlTimeoutFooterPreferenceController extends
AccessibilityFooterPreferenceController {
public AccessibilityControlTimeoutFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected String getLabelName() {
return mContext.getString(R.string.accessibility_setting_item_control_timeout_title);
}
}

View File

@@ -118,16 +118,16 @@ public class AccessibilityEditDialogUtils {
* Method to show the magnification edit shortcut dialog in Magnification.
*
* @param context A valid context
* @param dialogTitle The title of magnify edit shortcut dialog
* @param positiveBtnListener The positive button listener
* @return A magnification edit shortcut dialog in Magnification
*/
public static Dialog createMagnificationSwitchShortcutDialog(Context context,
CharSequence dialogTitle, CustomButtonsClickListener positiveBtnListener) {
CustomButtonsClickListener positiveBtnListener) {
final View contentView = createSwitchShortcutDialogContentView(context);
final AlertDialog alertDialog = new AlertDialog.Builder(context)
.setView(contentView)
.setTitle(dialogTitle)
.setTitle(context.getString(
R.string.accessibility_magnification_switch_shortcut_title))
.create();
setCustomButtonsClickListener(alertDialog, contentView,
positiveBtnListener, /* negativeBtnListener= */ null);

View File

@@ -0,0 +1,109 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.R;
import com.android.settingslib.widget.FooterPreference;
/**
* A custom preference acting as footer of a page. It has a field for icon and text. It is added
* to screen as the last preference and groups of icon and text content in accessibility-focusable
* {@link android.view.accessibility.AccessibilityNodeInfo} for TalkBack to use.
*/
public final class AccessibilityFooterPreference extends FooterPreference {
private CharSequence mIconContentDescription;
private boolean mLinkEnabled;
public AccessibilityFooterPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AccessibilityFooterPreference(Context context) {
super(context);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
final TextView title = holder.itemView.findViewById(android.R.id.title);
if (mLinkEnabled) {
// When a TextView has a movement method, it will set the view to clickable. This makes
// View.onTouchEvent always return true and consumes the touch event, essentially
// nullifying any return values of MovementMethod.onTouchEvent.
// To still allow propagating touch events to the parent when this view doesn't have
// links, we only set the movement method here if the text contains links.
title.setMovementMethod(LinkMovementMethod.getInstance());
} else {
title.setMovementMethod(/* movement= */ null);
}
final LinearLayout infoFrame = holder.itemView.findViewById(R.id.icon_frame);
if (!TextUtils.isEmpty(mIconContentDescription)) {
// Groups related content.
infoFrame.setContentDescription(mIconContentDescription);
title.setFocusable(false);
} else {
infoFrame.setContentDescription(null);
title.setFocusable(true);
}
}
/**
* Sets the content description of the icon.
*/
public void setIconContentDescription(CharSequence iconContentDescription) {
if (!TextUtils.equals(iconContentDescription, mIconContentDescription)) {
mIconContentDescription = iconContentDescription;
notifyChanged();
}
}
/**
* Gets the content description of the icon.
*/
public CharSequence getIconContentDescription() {
return mIconContentDescription;
}
/**
* Sets the title field supports movement method.
*/
public void setLinkEnabled(boolean enabled) {
if (mLinkEnabled != enabled) {
mLinkEnabled = enabled;
notifyChanged();
}
}
/**
* Returns true if the title field supports movement method.
*/
public boolean isLinkEnabled() {
return mLinkEnabled;
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/**
* Base class for accessibility preference footer.
*/
public abstract class AccessibilityFooterPreferenceController extends BasePreferenceController {
public AccessibilityFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final AccessibilityFooterPreference footerPreference =
screen.findPreference(getPreferenceKey());
updateFooterPreferences(footerPreference);
}
/** Returns the accessibility feature name. */
protected abstract String getLabelName();
private void updateFooterPreferences(AccessibilityFooterPreference footerPreference) {
final String iconContentDescription = mContext.getString(
R.string.accessibility_introduction_title, getLabelName());
footerPreference.setIconContentDescription(iconContentDescription);
}
}

View File

@@ -33,8 +33,8 @@ import androidx.preference.PreferenceCategory;
import com.android.internal.widget.SubtitleView;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.search.SearchIndexable;
@@ -46,8 +46,10 @@ import java.util.Locale;
/** Settings fragment containing font style of captioning properties. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class CaptionAppearanceFragment extends SettingsPreferenceFragment
public class CaptionAppearanceFragment extends DashboardFragment
implements OnPreferenceChangeListener, OnValueChangedListener {
private static final String TAG = "CaptionAppearanceFragment";
private static final String PREF_CAPTION_PREVIEW = "caption_preview";
private static final String PREF_BACKGROUND_COLOR = "captioning_background_color";
private static final String PREF_BACKGROUND_OPACITY = "captioning_background_opacity";
@@ -107,12 +109,11 @@ public class CaptionAppearanceFragment extends SettingsPreferenceFragment
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
mCaptioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
addPreferencesFromResource(R.xml.captioning_appearance);
initializeAllPreferences();
updateAllPreferences();
refreshShowingCustom();
@@ -120,6 +121,16 @@ public class CaptionAppearanceFragment extends SettingsPreferenceFragment
refreshPreviewText();
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.captioning_appearance;
}
@Override
protected String getLogTag() {
return TAG;
}
private void refreshPreviewText() {
final Context context = getActivity();
if (context == null) {

View File

@@ -0,0 +1,36 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import com.android.settings.R;
/**
* Preference controller for caption footer.
*/
public class CaptionFooterPreferenceController extends AccessibilityFooterPreferenceController {
public CaptionFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected String getLabelName() {
return mContext.getString(R.string.accessibility_captioning_title);
}
}

View File

@@ -26,18 +26,19 @@ import android.view.accessibility.CaptioningManager;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
/** Settings fragment containing more options of captioning properties. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class CaptionMoreOptionsFragment extends SettingsPreferenceFragment
public class CaptionMoreOptionsFragment extends DashboardFragment
implements Preference.OnPreferenceChangeListener {
private static final String TAG = "CaptionMoreOptionsFragment";
private static final String PREF_LOCALE = "captioning_locale";
private CaptioningManager mCaptioningManager;
private LocalePreference mLocale;
@Override
@@ -46,17 +47,26 @@ public class CaptionMoreOptionsFragment extends SettingsPreferenceFragment
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
mCaptioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
addPreferencesFromResource(R.xml.captioning_more_options);
initializeAllPreferences();
updateAllPreferences();
installUpdateListeners();
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.captioning_more_options;
}
@Override
protected String getLogTag() {
return TAG;
}
private void initializeAllPreferences() {
mLocale = (LocalePreference) findPreference(PREF_LOCALE);
}

View File

@@ -28,7 +28,7 @@ import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.search.SearchIndexable;
@@ -41,8 +41,10 @@ import java.util.List;
/** Settings fragment containing captioning properties. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class CaptionPropertiesFragment extends SettingsPreferenceFragment
public class CaptionPropertiesFragment extends DashboardFragment
implements OnPreferenceChangeListener, OnMainSwitchChangeListener {
private static final String TAG = "CaptionPropertiesFragment";
private static final String PREF_SWITCH = "captioning_preference_switch";
private static final String PREF_TEXT = "captioning_caption_appearance";
private static final String PREF_MORE = "captioning_more_options";
@@ -62,12 +64,11 @@ public class CaptionPropertiesFragment extends SettingsPreferenceFragment
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
mCaptioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE);
addPreferencesFromResource(R.xml.captioning_settings);
initializeAllPreferences();
installUpdateListeners();
initFontSizeValuesArray();
@@ -79,6 +80,16 @@ public class CaptionPropertiesFragment extends SettingsPreferenceFragment
updateAllPreferences();
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.captioning_settings;
}
@Override
protected String getLogTag() {
return TAG;
}
private void initializeAllPreferences() {
mSwitch = (SettingsMainSwitchPreference) findPreference(PREF_SWITCH);
mTextAppearance = (Preference) findPreference(PREF_TEXT);

View File

@@ -47,6 +47,7 @@ import com.android.settings.accessibility.MagnificationCapabilities.Magnificatio
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import java.util.ArrayList;
@@ -55,8 +56,9 @@ import java.util.StringJoiner;
/** Controller that shows the magnification area mode summary and the preference click behavior. */
public class MagnificationModePreferenceController extends BasePreferenceController implements
DialogCreatable, LifecycleObserver, OnCreate, OnSaveInstanceState {
DialogCreatable, LifecycleObserver, OnCreate, OnResume, OnSaveInstanceState {
static final String PREF_KEY = "screen_magnification_mode";
private static final int DIALOG_ID_BASE = 10;
@VisibleForTesting
static final int DIALOG_MAGNIFICATION_MODE = DIALOG_ID_BASE + 1;
@@ -68,7 +70,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
private static final String TAG = "MagnificationModePreferenceController";
private static final char COMPONENT_NAME_SEPARATOR = ':';
private MagnificationSettingsFragment mParentFragment;
private DialogHelper mDialogHelper;
// The magnification mode in the dialog.
private int mMode = MagnificationMode.NONE;
private Preference mModePreference;
@@ -121,7 +123,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
mModePreference = screen.findPreference(getPreferenceKey());
mModePreference.setOnPreferenceClickListener(preference -> {
mMode = MagnificationCapabilities.getCapabilities(mContext);
mParentFragment.showDialog(DIALOG_MAGNIFICATION_MODE);
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE);
return true;
});
}
@@ -131,8 +133,12 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
outState.putInt(EXTRA_MODE, mMode);
}
public void setParentFragment(MagnificationSettingsFragment parentFragment) {
mParentFragment = parentFragment;
/**
* Sets {@link DialogHelper} used to show the dialog.
*/
public void setDialogHelper(DialogHelper dialogHelper) {
mDialogHelper = dialogHelper;
mDialogHelper.setDialogDelegate(this);
}
@Override
@@ -207,7 +213,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
}
mMode = modeInfo.mMagnificationMode;
if (isTripleTapEnabled(mContext) && mMode != MagnificationMode.FULLSCREEN) {
mParentFragment.showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
}
}
@@ -229,9 +235,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
}
private Dialog createMagnificationShortCutConfirmDialog() {
final String title = mContext.getString(
R.string.accessibility_magnification_switch_shortcut_title);
return AccessibilityEditDialogUtils.createMagnificationSwitchShortcutDialog(mContext, title,
return AccessibilityEditDialogUtils.createMagnificationSwitchShortcutDialog(mContext,
this::onSwitchShortcutDialogButtonClicked);
}
@@ -267,6 +271,21 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
joiner.toString());
}
// TODO(b/186731461): Remove it when this controller is used in DashBoardFragment only.
@Override
public void onResume() {
updateState(mModePreference);
}
/**
* An interface to help the delegate to show the dialog. It will be injected to the delegate.
*/
interface DialogHelper extends DialogCreatable {
void showDialog(int dialogId);
void setDialogDelegate(DialogCreatable delegate);
}
@VisibleForTesting
static class MagnificationModeInfo extends ItemInfoArrayAdapter.ItemInfo {
@MagnificationMode

View File

@@ -20,6 +20,7 @@ import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -27,11 +28,13 @@ import com.android.settingslib.search.SearchIndexable;
/** Settings page for magnification. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MagnificationSettingsFragment extends DashboardFragment {
public class MagnificationSettingsFragment extends DashboardFragment implements
MagnificationModePreferenceController.DialogHelper {
private static final String TAG = "MagnificationSettingsFragment";
private MagnificationModePreferenceController mMagnificationModePreferenceController;
private DialogCreatable mDialogDelegate;
@Override
public int getMetricsCategory() {
@@ -41,19 +44,23 @@ public class MagnificationSettingsFragment extends DashboardFragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
mMagnificationModePreferenceController = use(MagnificationModePreferenceController.class);
mMagnificationModePreferenceController.setParentFragment(this);
use(MagnificationModePreferenceController.class).setDialogHelper(this);
}
@Override
protected void showDialog(int dialogId) {
public void showDialog(int dialogId) {
super.showDialog(dialogId);
}
@Override
public void setDialogDelegate(DialogCreatable delegate) {
mDialogDelegate = delegate;
}
@Override
public int getDialogMetricsCategory(int dialogId) {
if (mMagnificationModePreferenceController != null) {
return mMagnificationModePreferenceController.getDialogMetricsCategory(dialogId);
if (mDialogDelegate != null) {
return mDialogDelegate.getDialogMetricsCategory(dialogId);
}
return 0;
}
@@ -70,8 +77,8 @@ public class MagnificationSettingsFragment extends DashboardFragment {
@Override
public Dialog onCreateDialog(int dialogId) {
if (mMagnificationModePreferenceController != null) {
final Dialog dialog = mMagnificationModePreferenceController.onCreateDialog(dialogId);
if (mDialogDelegate != null) {
final Dialog dialog = mDialogDelegate.onCreateDialog(dialogId);
if (dialog != null) {
return dialog;
}

View File

@@ -0,0 +1,37 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import android.content.Context;
import com.android.settings.R;
/**
* Preference controller for accessibility autoclick footer.
*/
public class ToggleAutoclickFooterPreferenceController extends
AccessibilityFooterPreferenceController {
public ToggleAutoclickFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
protected String getLabelName() {
return mContext.getString(R.string.accessibility_autoclick_preference_title);
}
}

View File

@@ -107,7 +107,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe
lists.add(KEY_PREVIEW);
lists.add(KEY_CATEGORY_MODE);
lists.add(KEY_GENERAL_CATEGORY);
lists.add(KEY_INTRODUCTION_CATEGORY);
lists.add(KEY_HTML_DESCRIPTION_PREFERENCE);
return lists;
}

View File

@@ -54,7 +54,6 @@ import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
import java.lang.annotation.Retention;
@@ -87,7 +86,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
private static final String DRAWABLE_FOLDER = "drawable";
protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
protected static final String KEY_GENERAL_CATEGORY = "general_categories";
protected static final String KEY_INTRODUCTION_CATEGORY = "introduction_categories";
protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
protected static final String KEY_ANIMATED_IMAGE = "animated_image";
@@ -383,7 +382,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
lists.add(KEY_USE_SERVICE_PREFERENCE);
lists.add(KEY_ANIMATED_IMAGE);
lists.add(KEY_GENERAL_CATEGORY);
lists.add(KEY_INTRODUCTION_CATEGORY);
lists.add(KEY_HTML_DESCRIPTION_PREFERENCE);
return lists;
}
@@ -495,44 +494,57 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
generalCategory.addPreference(mSettingsPreference);
}
private void initIntroductionCategory() {
final PreferenceCategory introductionCategory = new PreferenceCategory(getPrefContext());
final CharSequence title =
getString(R.string.accessibility_introduction_title, mPackageName);
introductionCategory.setKey(KEY_INTRODUCTION_CATEGORY);
introductionCategory.setTitle(title);
getPreferenceScreen().addPreference(introductionCategory);
}
private void initHtmlTextPreference() {
if (TextUtils.isEmpty(mHtmlDescription)) {
return;
}
final PreferenceScreen screen = getPreferenceScreen();
final CharSequence htmlDescription = Html.fromHtml(mHtmlDescription.toString(),
Html.FROM_HTML_MODE_COMPACT, mImageGetter, /* tagHandler= */ null);
final String iconContentDescription =
getString(R.string.accessibility_introduction_title, mPackageName);
initIntroductionCategory();
final HtmlTextPreference htmlTextPreference = new HtmlTextPreference(getPrefContext());
htmlTextPreference.setSummary(mHtmlDescription);
htmlTextPreference.setImageGetter(mImageGetter);
htmlTextPreference.setSelectable(false);
final PreferenceCategory introductionCategory = findPreference(KEY_INTRODUCTION_CATEGORY);
introductionCategory.addPreference(htmlTextPreference);
final AccessibilityFooterPreference htmlFooterPreference =
new AccessibilityFooterPreference(screen.getContext());
htmlFooterPreference.setKey(KEY_HTML_DESCRIPTION_PREFERENCE);
htmlFooterPreference.setSummary(htmlDescription);
htmlFooterPreference.setLinkEnabled(false);
htmlFooterPreference.setIconContentDescription(iconContentDescription);
screen.addPreference(htmlFooterPreference);
}
private void initFooterPreference() {
if (!TextUtils.isEmpty(mDescription)) {
createFooterPreference(mDescription);
createFooterPreference(getPreferenceScreen(), mDescription,
getString(R.string.accessibility_introduction_title, mPackageName));
}
if (TextUtils.isEmpty(mHtmlDescription) && TextUtils.isEmpty(mDescription)) {
final CharSequence defaultDescription =
getText(R.string.accessibility_service_default_description);
createFooterPreference(defaultDescription);
createFooterPreference(getPreferenceScreen(), defaultDescription,
getString(R.string.accessibility_introduction_title, mPackageName));
}
}
/**
* Creates {@link AccessibilityFooterPreference} and append into {@link PreferenceScreen}
*
* @param screen The preference screen to add the footer preference
* @param summary The summary of the preference summary.
* @param iconContentDescription The content description of icon in the footer.
*/
@VisibleForTesting
void createFooterPreference(PreferenceScreen screen, CharSequence summary,
String iconContentDescription) {
final AccessibilityFooterPreference footerPreference =
new AccessibilityFooterPreference(screen.getContext());
footerPreference.setSummary(summary);
footerPreference.setIconContentDescription(iconContentDescription);
screen.addPreference(footerPreference);
}
@VisibleForTesting
void setupEditShortcutDialog(Dialog dialog) {
final View dialogSoftwareView = dialog.findViewById(R.id.software_shortcut);
@@ -707,12 +719,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
showDialog(DialogEnums.EDIT_SHORTCUT);
}
private void createFooterPreference(CharSequence title) {
final PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.addPreference(new FooterPreference.Builder(getActivity()).setTitle(
title).build());
}
/**
* Setups a configurable default if the setting has never been set.
*/

View File

@@ -42,6 +42,7 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
@@ -55,7 +56,8 @@ import java.util.StringJoiner;
* and does not have toggle bar to turn on service to use.
*/
public class ToggleScreenMagnificationPreferenceFragment extends
ToggleFeaturePreferenceFragment {
ToggleFeaturePreferenceFragment implements
MagnificationModePreferenceController.DialogHelper {
// TODO(b/147021230): Move duplicated functions with android/internal/accessibility into util.
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
@@ -67,6 +69,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends
private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
private MagnificationModePreferenceController mModePreferenceController;
private DialogCreatable mDialogDelegate;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -108,6 +113,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override
public Dialog onCreateDialog(int dialogId) {
if (mDialogDelegate != null) {
final Dialog dialog = mDialogDelegate.onCreateDialog(dialogId);
if (dialog != null) {
return dialog;
}
}
final AlertDialog dialog;
switch (dialogId) {
case DialogEnums.GESTURE_NAVIGATION_TUTORIAL:
@@ -128,20 +139,35 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override
protected void initSettingsPreference() {
// If the device doesn't support magnification area, it should hide the settings preference.
if (!getContext().getResources().getBoolean(
com.android.internal.R.bool.config_magnification_area)) {
return;
}
mSettingsPreference = new Preference(getPrefContext());
mSettingsPreference.setTitle(R.string.accessibility_menu_item_settings);
// TODO(b/177371954): "magnification area" should be brought up to the highest level of the
// settings UI so that it appears below "shortcut" to replace "settings.
mSettingsPreference.setFragment(MagnificationSettingsFragment.class.getName());
mSettingsPreference.setTitle(R.string.accessibility_magnification_mode_title);
mSettingsPreference.setKey(MagnificationModePreferenceController.PREF_KEY);
mSettingsPreference.setPersistent(false);
final PreferenceCategory generalCategory = findPreference(KEY_GENERAL_CATEGORY);
generalCategory.addPreference(mSettingsPreference);
mModePreferenceController = new MagnificationModePreferenceController(getContext(),
MagnificationModePreferenceController.PREF_KEY);
mModePreferenceController.setDialogHelper(this);
getSettingsLifecycle().addObserver(mModePreferenceController);
mModePreferenceController.displayPreference(getPreferenceScreen());
}
@Override
public void showDialog(int dialogId) {
super.showDialog(dialogId);
}
@Override
public void setDialogDelegate(DialogCreatable delegate) {
mDialogDelegate = delegate;
}
@Override
@@ -278,6 +304,13 @@ public class ToggleScreenMagnificationPreferenceFragment extends
@Override
public int getDialogMetricsCategory(int dialogId) {
if (mDialogDelegate != null) {
final int category = mDialogDelegate.getDialogMetricsCategory(dialogId);
if (category != 0) {
return category;
}
}
switch (dialogId) {
case DialogEnums.GESTURE_NAVIGATION_TUTORIAL:
return SettingsEnums.DIALOG_TOGGLE_SCREEN_MAGNIFICATION_GESTURE_NAVIGATION;

View File

@@ -44,7 +44,6 @@ import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
@@ -53,6 +52,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.AppPreference;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -116,7 +116,7 @@ public class PasswordsPreferenceController extends BasePreferenceController
Context prefContext, @UserIdInt int user, PreferenceGroup group) {
for (int i = 0; i < mServices.size(); i++) {
final AutofillServiceInfo service = mServices.get(i);
final Preference pref = new Preference(prefContext);
final AppPreference pref = new AppPreference(prefContext);
final ServiceInfo serviceInfo = service.getServiceInfo();
pref.setTitle(serviceInfo.loadLabel(mPm));
final Drawable icon =

View File

@@ -511,7 +511,7 @@ public class ManageApplications extends InstrumentedFragment
if (storageType == STORAGE_TYPE_MUSIC) {
filter = new CompoundFilter(ApplicationsState.FILTER_AUDIO, filter);
} else if (storageType == STORAGE_TYPE_DEFAULT) {
filter = new CompoundFilter(ApplicationsState.FILTER_OTHER_APPS, filter);
filter = new CompoundFilter(ApplicationsState.FILTER_APPS_EXCEPT_GAMES, filter);
}
return filter;
}

View File

@@ -280,8 +280,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
METHOD_GET_DYNAMIC_SUMMARY);
refreshSummary(uri, preference);
return createDynamicDataObserver(METHOD_GET_DYNAMIC_SUMMARY, uri, preference);
} else {
preference.setSummary(R.string.summary_placeholder);
}
return null;
}

View File

@@ -120,7 +120,9 @@ public class StorageAsyncLoader
// This isn't quite right because it slams the first user by user id with the whole code
// size, but this ensures that we count all apps seen once.
boolean isAddCodeBytesForFirstUserId = false;
if (!mSeenPackages.contains(app.packageName)) {
isAddCodeBytesForFirstUserId = true;
blamedSize += stats.getCodeBytes();
mSeenPackages.add(app.packageName);
}
@@ -130,13 +132,34 @@ public class StorageAsyncLoader
result.gamesSize += blamedSize;
break;
case CATEGORY_AUDIO:
// TODO(b/170918505): Should revamp audio size calculation with the data
// from media provider.
result.musicAppsSize += blamedSize;
if (isAddCodeBytesForFirstUserId) {
result.musicAppsSize -= stats.getCodeBytes();
}
result.otherAppsSize += blamedSize;
break;
case CATEGORY_VIDEO:
// TODO(b/170918505): Should revamp video size calculation with the data
// from media provider.
result.videoAppsSize += blamedSize;
if (isAddCodeBytesForFirstUserId) {
result.videoAppsSize -= stats.getCodeBytes();
}
result.otherAppsSize += blamedSize;
break;
case CATEGORY_IMAGE:
// TODO(b/170918505): Should revamp image size calculation with the data
// from media provider.
result.photosAppsSize += blamedSize;
if (isAddCodeBytesForFirstUserId) {
result.photosAppsSize -= stats.getCodeBytes();
}
result.otherAppsSize += blamedSize;
break;
default:
// The deprecated game flag does not set the category.

View File

@@ -107,7 +107,7 @@ public class PeakRefreshRatePreferenceController extends TogglePreferenceControl
mContext.getContentResolver(),
Settings.System.PEAK_REFRESH_RATE,
getDefaultPeakRefreshRate());
return peakRefreshRate == mPeakRefreshRate;
return Math.round(peakRefreshRate) == Math.round(mPeakRefreshRate);
}
@Override
@@ -190,6 +190,7 @@ public class PeakRefreshRatePreferenceController extends TogglePreferenceControl
com.android.internal.R.integer.config_defaultPeakRefreshRate);
}
Log.d(TAG, "DeviceConfig getDefaultPeakRefreshRate : " + defaultPeakRefreshRate);
return defaultPeakRefreshRate;
}
}

View File

@@ -21,13 +21,13 @@ import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.AggregateBatteryConsumer;
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;
@@ -344,16 +344,38 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
}
}
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)) {
final BatteryConsumer deviceConsumer = mBatteryUsageStats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
final BatteryConsumer appsConsumer = mBatteryUsageStats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
componentId++) {
if (!showAllApps
&& mBatteryUtils.shouldHideDevicePowerComponent(deviceConsumer, componentId)) {
continue;
}
results.add(new BatteryEntry(mContext, mHandler, mUserManager,
consumer, /* isHidden */ true, null, null, loadDataInBackground));
results.add(new BatteryEntry(mContext, componentId,
deviceConsumer.getConsumedPower(componentId),
appsConsumer.getConsumedPower(componentId),
deviceConsumer.getUsageDurationMillis(componentId)));
}
for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+ deviceConsumer.getCustomPowerComponentCount();
componentId++) {
if (!showAllApps
&& mBatteryUtils.shouldHideCustomDevicePowerComponent(deviceConsumer,
componentId)) {
continue;
}
results.add(new BatteryEntry(mContext, componentId,
deviceConsumer.getCustomPowerComponentName(componentId),
deviceConsumer.getConsumedPowerForCustomComponent(componentId),
appsConsumer.getConsumedPowerForCustomComponent(componentId)));
}
if (showAllApps) {
@@ -431,20 +453,26 @@ public class BatteryAppListPreferenceController extends AbstractPreferenceContro
.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,
final AggregateBatteryConsumer.Builder appsBatteryConsumerBuilder =
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
final AggregateBatteryConsumer.Builder deviceBatteryConsumerBuilder =
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
for (@BatteryConsumer.PowerComponent int componentId : new int[]{
BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY,
BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
BatteryConsumer.POWER_COMPONENT_CAMERA,
BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
BatteryConsumer.POWER_COMPONENT_IDLE,
BatteryConsumer.POWER_COMPONENT_MEMORY,
BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
BatteryConsumer.POWER_COMPONENT_PHONE,
BatteryConsumer.POWER_COMPONENT_SCREEN,
BatteryConsumer.POWER_COMPONENT_WIFI,
}) {
builder.getOrCreateSystemBatteryConsumerBuilder(drainType)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, use);
appsBatteryConsumerBuilder.setConsumedPower(componentId, use);
deviceBatteryConsumerBuilder.setConsumedPower(componentId, use * 2);
use += 5;
}

View File

@@ -66,8 +66,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
@VisibleForTesting PreferenceGroup mAppListPrefGroup;
@VisibleForTesting BatteryChartView mBatteryChartView;
@VisibleForTesting ExpandDividerPreference mExpandDividerPreference;
@VisibleForTesting CategoryTitleType mCategoryTitleType =
CategoryTitleType.TYPE_UNKNOWN;
@VisibleForTesting int[] mBatteryHistoryLevels;
@VisibleForTesting long[] mBatteryHistoryKeys;
@@ -87,14 +85,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
@VisibleForTesting
final List<BatteryDiffEntry> mSystemEntries = new ArrayList<>();
/** Which component data will be shown in the screen. */
enum CategoryTitleType {
TYPE_UNKNOWN,
TYPE_APP_COMPONENT,
TYPE_SYSTEM_COMPONENT,
TYPE_ALL_COMPONENTS
}
public BatteryChartPreferenceController(
Context context, String preferenceKey,
Lifecycle lifecycle, SettingsActivity activity,
@@ -283,7 +273,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
}
private void addAllPreferences() {
mCategoryTitleType = CategoryTitleType.TYPE_UNKNOWN;
final List<BatteryDiffEntry> entries =
mBatteryIndexedMap.get(Integer.valueOf(mTrapezoidIndex));
if (entries == null) {
@@ -312,10 +301,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
// Adds app entries to the list if it is not empty.
if (!appEntries.isEmpty()) {
addPreferenceToScreen(appEntries);
mCategoryTitleType = CategoryTitleType.TYPE_APP_COMPONENT;
}
// Adds the expabable divider if we have two sections data.
if (!appEntries.isEmpty() && !mSystemEntries.isEmpty()) {
// Adds the expabable divider if we have system entries data.
if (!mSystemEntries.isEmpty()) {
if (mExpandDividerPreference == null) {
mExpandDividerPreference = new ExpandDividerPreference(mPrefContext);
mExpandDividerPreference.setOnExpandListener(this);
@@ -323,9 +311,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
mExpandDividerPreference.setOrder(
mAppListPrefGroup.getPreferenceCount());
mAppListPrefGroup.addPreference(mExpandDividerPreference);
mCategoryTitleType = CategoryTitleType.TYPE_ALL_COMPONENTS;
} else if (appEntries.isEmpty() && !mSystemEntries.isEmpty()) {
mCategoryTitleType = CategoryTitleType.TYPE_SYSTEM_COMPONENT;
}
refreshExpandUi();
}
@@ -408,38 +393,14 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
@VisibleForTesting
void refreshCategoryTitle() {
final String slotInformation = getSlotInformation();
Log.d(TAG, String.format("refreshCategoryTitle:%s slotInfo:%s",
mCategoryTitleType, slotInformation));
refreshPreferenceCategoryTitle(slotInformation);
refreshExpandableDividerTitle(slotInformation);
}
private void refreshExpandableDividerTitle(String slotInformation) {
if (mExpandDividerPreference == null) {
return;
Log.d(TAG, String.format("refreshCategoryTitle:%s", slotInformation));
if (mAppListPrefGroup != null) {
mAppListPrefGroup.setTitle(
getSlotInformation(/*isApp=*/ true, slotInformation));
}
mExpandDividerPreference.setTitle(
mCategoryTitleType == CategoryTitleType.TYPE_ALL_COMPONENTS
? getSlotInformation(/*isApp=*/ false, slotInformation)
: null);
}
private void refreshPreferenceCategoryTitle(String slotInformation) {
if (mAppListPrefGroup == null) {
return;
}
switch (mCategoryTitleType) {
case TYPE_APP_COMPONENT:
case TYPE_ALL_COMPONENTS:
mAppListPrefGroup.setTitle(
getSlotInformation(/*isApp=*/ true, slotInformation));
break;
case TYPE_SYSTEM_COMPONENT:
mAppListPrefGroup.setTitle(
getSlotInformation(/*isApp=*/ false, slotInformation));
break;
default:
mAppListPrefGroup.setTitle(R.string.battery_app_usage_for_past_24);
if (mExpandDividerPreference != null) {
mExpandDividerPreference.setTitle(
getSlotInformation(/*isApp=*/ false, slotInformation));
}
}

View File

@@ -15,8 +15,6 @@ package com.android.settings.fuelgauge;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
@@ -29,7 +27,6 @@ import androidx.annotation.VisibleForTesting;
import com.android.settingslib.utils.StringUtil;
import java.time.Duration;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
@@ -158,8 +155,8 @@ public class BatteryDiffEntry {
break;
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
final BatteryEntry.NameAndIcon nameAndIconForSystem =
BatteryEntry.getNameAndIconFromDrainType(
mContext, mBatteryHistEntry.mDrainType);
BatteryEntry.getNameAndIconFromPowerComponent(
mContext, mBatteryHistEntry.mPowerComponentId);
if (nameAndIconForSystem != null) {
mAppLabel = nameAndIconForSystem.name;
if (nameAndIconForSystem.iconId != 0) {

View File

@@ -29,11 +29,11 @@ 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.DebugUtils;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -160,6 +160,11 @@ public class BatteryEntry {
private final Context mContext;
private final BatteryConsumer mBatteryConsumer;
private final boolean mIsHidden;
@ConvertUtils.ConsumerType
private final int mConsumerType;
@BatteryConsumer.PowerComponent
private final int mPowerComponentId;
private long mUsageDurationMs;
public String name;
public Drawable icon;
@@ -188,8 +193,10 @@ public class BatteryEntry {
mBatteryConsumer = batteryConsumer;
mIsHidden = isHidden;
mDefaultPackageName = packageName;
mPowerComponentId = -1;
if (batteryConsumer instanceof UidBatteryConsumer) {
mConsumerType = ConvertUtils.CONSUMER_TYPE_UID_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
@@ -215,27 +222,54 @@ public class BatteryEntry {
}
}
getQuickNameIconForUid(uid, packages, loadDataInBackground);
return;
} else if (batteryConsumer instanceof SystemBatteryConsumer) {
mConsumedPower = batteryConsumer.getConsumedPower()
- ((SystemBatteryConsumer) batteryConsumer).getPowerConsumedByApps();
final NameAndIcon nameAndIcon = getNameAndIconFromDrainType(
context, ((SystemBatteryConsumer) batteryConsumer).getDrainType());
iconId = nameAndIcon.iconId;
name = nameAndIcon.name;
} else if (batteryConsumer instanceof UserBatteryConsumer) {
mConsumerType = ConvertUtils.CONSUMER_TYPE_USER_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
final NameAndIcon nameAndIcon = getNameAndIconFromUserId(
context, ((UserBatteryConsumer) batteryConsumer).getUserId());
icon = nameAndIcon.icon;
name = nameAndIcon.name;
} else {
throw new IllegalArgumentException("Unsupported battery consumer: " + batteryConsumer);
}
}
/** Battery entry for a power component of AggregateBatteryConsumer */
public BatteryEntry(Context context, int powerComponentId, double devicePowerMah,
double appsPowerMah, long usageDurationMs) {
mContext = context;
mBatteryConsumer = null;
mIsHidden = false;
mPowerComponentId = powerComponentId;
mConsumedPower = devicePowerMah - appsPowerMah;
mUsageDurationMs = usageDurationMs;
mConsumerType = ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY;
final NameAndIcon nameAndIcon = getNameAndIconFromPowerComponent(context, powerComponentId);
iconId = nameAndIcon.iconId;
name = nameAndIcon.name;
if (iconId != 0) {
icon = context.getDrawable(iconId);
}
}
/** Battery entry for a custom power component of AggregateBatteryConsumer */
public BatteryEntry(Context context, int powerComponentId, String powerComponentName,
double devicePowerMah, double appsPowerMah) {
mContext = context;
mBatteryConsumer = null;
mIsHidden = false;
mPowerComponentId = powerComponentId;
iconId = R.drawable.ic_power_system;
icon = context.getDrawable(iconId);
name = powerComponentName;
mConsumedPower = devicePowerMah - appsPowerMah;
mConsumerType = ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY;
}
public Drawable getIcon() {
return icon;
}
@@ -247,6 +281,16 @@ public class BatteryEntry {
return name;
}
@ConvertUtils.ConsumerType
public int getConsumerType() {
return mConsumerType;
}
@BatteryConsumer.PowerComponent
public int getPowerComponentId() {
return mPowerComponentId;
}
void getQuickNameIconForUid(
final int uid, final String[] packages, final boolean loadDataInBackground) {
// Locale sync to system config in Settings
@@ -395,13 +439,10 @@ public class BatteryEntry {
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 "";
return "S|" + mPowerComponentId;
}
}
@@ -448,13 +489,6 @@ public class BatteryEntry {
}
}
/**
* Returns the BatteryConsumer of the app described by this entry.
*/
public BatteryConsumer getBatteryConsumer() {
return mBatteryConsumer;
}
/**
* Returns foreground foreground time (in milliseconds) that is attributed to this entry.
*/
@@ -462,10 +496,8 @@ public class BatteryEntry {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs(
UidBatteryConsumer.STATE_FOREGROUND);
} else if (mBatteryConsumer instanceof SystemBatteryConsumer) {
return ((SystemBatteryConsumer) mBatteryConsumer).getUsageDurationMillis();
} else {
return 0;
return mUsageDurationMs;
}
}
@@ -537,52 +569,53 @@ public class BatteryEntry {
}
/**
* Gets name annd icon resource from SystemBatteryConsumer drain type.
* Gets name and icon resource from BatteryConsumer power component ID.
*/
public static NameAndIcon getNameAndIconFromDrainType(
Context context, final int drainType) {
String name = null;
int iconId = 0;
switch (drainType) {
case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY:
public static NameAndIcon getNameAndIconFromPowerComponent(
Context context, @BatteryConsumer.PowerComponent int powerComponentId) {
String name;
int iconId;
switch (powerComponentId) {
case BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY:
name = context.getResources().getString(R.string.ambient_display_screen_title);
iconId = R.drawable.ic_settings_aod;
break;
case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH:
case BatteryConsumer.POWER_COMPONENT_BLUETOOTH:
name = context.getResources().getString(R.string.power_bluetooth);
iconId = com.android.internal.R.drawable.ic_settings_bluetooth;
break;
case SystemBatteryConsumer.DRAIN_TYPE_CAMERA:
case BatteryConsumer.POWER_COMPONENT_CAMERA:
name = context.getResources().getString(R.string.power_camera);
iconId = R.drawable.ic_settings_camera;
break;
case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO:
case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO:
name = context.getResources().getString(R.string.power_cell);
iconId = R.drawable.ic_cellular_1_bar;
break;
case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT:
case BatteryConsumer.POWER_COMPONENT_FLASHLIGHT:
name = context.getResources().getString(R.string.power_flashlight);
iconId = R.drawable.ic_settings_display;
break;
case SystemBatteryConsumer.DRAIN_TYPE_PHONE:
case BatteryConsumer.POWER_COMPONENT_PHONE:
name = context.getResources().getString(R.string.power_phone);
iconId = R.drawable.ic_settings_voice_calls;
break;
case SystemBatteryConsumer.DRAIN_TYPE_SCREEN:
case BatteryConsumer.POWER_COMPONENT_SCREEN:
name = context.getResources().getString(R.string.power_screen);
iconId = R.drawable.ic_settings_display;
break;
case SystemBatteryConsumer.DRAIN_TYPE_WIFI:
case BatteryConsumer.POWER_COMPONENT_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:
case BatteryConsumer.POWER_COMPONENT_IDLE:
case BatteryConsumer.POWER_COMPONENT_MEMORY:
name = context.getResources().getString(R.string.power_idle);
iconId = R.drawable.ic_settings_phone_idle;
break;
case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM:
name = null;
default:
name = DebugUtils.constantToString(BatteryConsumer.class, "POWER_COMPONENT_",
powerComponentId);
iconId = R.drawable.ic_power_system;
break;
}

View File

@@ -15,10 +15,8 @@ package com.android.settings.fuelgauge;
import android.content.ContentValues;
import android.database.Cursor;
import android.util.Log;
import java.time.Duration;
import java.util.TimeZone;
/** A container class to carry data from {@link ContentValues}. */
public class BatteryHistEntry {
@@ -30,6 +28,8 @@ public class BatteryHistEntry {
public static final String KEY_APP_LABEL = "appLabel";
public static final String KEY_PACKAGE_NAME = "packageName";
public static final String KEY_IS_HIDDEN = "isHidden";
// Device booting elapsed time from SystemClock.elapsedRealtime().
public static final String KEY_BOOT_TIMESTAMP = "bootTimestamp";
public static final String KEY_TIMESTAMP = "timestamp";
public static final String KEY_ZONE_ID = "zoneId";
public static final String KEY_TOTAL_POWER = "totalPower";
@@ -50,6 +50,7 @@ public class BatteryHistEntry {
// Whether the data is represented as system component or not?
public final boolean mIsHidden;
// Records the timestamp relative information.
public final long mBootTimestamp;
public final long mTimestamp;
public final String mZoneId;
// Records the battery usage relative information.
@@ -58,7 +59,7 @@ public class BatteryHistEntry {
public final double mPercentOfTotal;
public final long mForegroundUsageTimeInMs;
public final long mBackgroundUsageTimeInMs;
public final int mDrainType;
public final int mPowerComponentId;
public final int mConsumerType;
// Records the battery intent relative information.
public final int mBatteryLevel;
@@ -74,6 +75,7 @@ public class BatteryHistEntry {
mAppLabel = getString(values, KEY_APP_LABEL);
mPackageName = getString(values, KEY_PACKAGE_NAME);
mIsHidden = getBoolean(values, KEY_IS_HIDDEN);
mBootTimestamp = getLong(values, KEY_BOOT_TIMESTAMP);
mTimestamp = getLong(values, KEY_TIMESTAMP);
mZoneId = getString(values, KEY_ZONE_ID);
mTotalPower = getDouble(values, KEY_TOTAL_POWER);
@@ -81,7 +83,7 @@ public class BatteryHistEntry {
mPercentOfTotal = getDouble(values, KEY_PERCENT_OF_TOTAL);
mForegroundUsageTimeInMs = getLong(values, KEY_FOREGROUND_USAGE_TIME);
mBackgroundUsageTimeInMs = getLong(values, KEY_BACKGROUND_USAGE_TIME);
mDrainType = getInteger(values, KEY_DRAIN_TYPE);
mPowerComponentId = getInteger(values, KEY_DRAIN_TYPE);
mConsumerType = getInteger(values, KEY_CONSUMER_TYPE);
mBatteryLevel = getInteger(values, KEY_BATTERY_LEVEL);
mBatteryStatus = getInteger(values, KEY_BATTERY_STATUS);
@@ -94,6 +96,7 @@ public class BatteryHistEntry {
mAppLabel = getString(cursor, KEY_APP_LABEL);
mPackageName = getString(cursor, KEY_PACKAGE_NAME);
mIsHidden = getBoolean(cursor, KEY_IS_HIDDEN);
mBootTimestamp = getLong(cursor, KEY_BOOT_TIMESTAMP);
mTimestamp = getLong(cursor, KEY_TIMESTAMP);
mZoneId = getString(cursor, KEY_ZONE_ID);
mTotalPower = getDouble(cursor, KEY_TOTAL_POWER);
@@ -101,7 +104,7 @@ public class BatteryHistEntry {
mPercentOfTotal = getDouble(cursor, KEY_PERCENT_OF_TOTAL);
mForegroundUsageTimeInMs = getLong(cursor, KEY_FOREGROUND_USAGE_TIME);
mBackgroundUsageTimeInMs = getLong(cursor, KEY_BACKGROUND_USAGE_TIME);
mDrainType = getInteger(cursor, KEY_DRAIN_TYPE);
mPowerComponentId = getInteger(cursor, KEY_DRAIN_TYPE);
mConsumerType = getInteger(cursor, KEY_CONSUMER_TYPE);
mBatteryLevel = getInteger(cursor, KEY_BATTERY_LEVEL);
mBatteryStatus = getInteger(cursor, KEY_BATTERY_STATUS);
@@ -136,7 +139,7 @@ public class BatteryHistEntry {
mKey = Long.toString(mUid);
break;
case ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY:
mKey = "S|" + mDrainType;
mKey = "S|" + mPowerComponentId;
break;
case ConvertUtils.CONSUMER_TYPE_USER_BATTERY:
mKey = "U|" + mUserId;
@@ -153,12 +156,13 @@ public class BatteryHistEntry {
.append("\nBatteryHistEntry{")
.append(String.format("\n\tpackage=%s|label=%s|uid=%d|userId=%d|isHidden=%b",
mPackageName, mAppLabel, mUid, mUserId, mIsHidden))
.append(String.format("\n\ttimestamp=%s|zoneId=%s", recordAtDateTime, mZoneId))
.append(String.format("\n\ttimestamp=%s|zoneId=%s|bootTimestamp=%d",
recordAtDateTime, mZoneId, Duration.ofMillis(mBootTimestamp).getSeconds()))
.append(String.format("\n\tusage=%f|total=%f|consume=%f|elapsedTime=%d|%d",
mPercentOfTotal, mTotalPower, mConsumePower,
Duration.ofMillis(mForegroundUsageTimeInMs).getSeconds(),
Duration.ofMillis(mBackgroundUsageTimeInMs).getSeconds()))
.append(String.format("\n\tdrain=%d|consumer=%d", mDrainType, mConsumerType))
.append(String.format("\n\tdrain=%d|consumer=%d", mPowerComponentId, mConsumerType))
.append(String.format("\n\tbattery=%d|status=%d|health=%d\n}",
mBatteryLevel, mBatteryStatus, mBatteryHealth));
return builder.toString();
@@ -249,5 +253,4 @@ public class BatteryHistEntry {
mIsValidEntry = false;
return false;
}
}

View File

@@ -23,13 +23,13 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Build;
import android.os.Process;
import android.os.SystemBatteryConsumer;
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
@@ -195,22 +195,34 @@ public class BatteryUtils {
}
/**
* Returns true if the specified battery consumer should be excluded from the summary
* Returns true if the specified device power component 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:
public boolean shouldHideDevicePowerComponent(BatteryConsumer consumer,
@BatteryConsumer.PowerComponent int powerComponentId) {
switch (powerComponentId) {
case BatteryConsumer.POWER_COMPONENT_IDLE:
case BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO:
case BatteryConsumer.POWER_COMPONENT_SCREEN:
case BatteryConsumer.POWER_COMPONENT_BLUETOOTH:
case BatteryConsumer.POWER_COMPONENT_WIFI:
return true;
default:
return consumer.getConsumedPower() < MIN_POWER_THRESHOLD_MILLI_AMP_HOURS;
return consumer.getConsumedPower(powerComponentId)
< MIN_POWER_THRESHOLD_MILLI_AMP_HOURS;
}
}
/**
* Returns true if the specified device custom power component should be excluded from the
* summary battery consumption list.
*/
public boolean shouldHideCustomDevicePowerComponent(BatteryConsumer consumer,
int customPowerComponentId) {
return consumer.getConsumedPowerForCustomComponent(customPowerComponentId)
< MIN_POWER_THRESHOLD_MILLI_AMP_HOURS;
}
/**
* Returns true if one the specified packages belongs to a hidden system module.
*/

View File

@@ -15,14 +15,9 @@ package com.android.settings.fuelgauge;
import android.annotation.IntDef;
import android.content.ContentValues;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.content.Context;
import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.UserHandle;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -79,61 +74,46 @@ public final class ConvertUtils {
private ConvertUtils() {}
/** Gets consumer type from {@link BatteryConsumer}. */
@ConsumerType
public static int getConsumerType(BatteryConsumer consumer) {
if (consumer instanceof UidBatteryConsumer) {
return CONSUMER_TYPE_UID_BATTERY;
} else if (consumer instanceof UserBatteryConsumer) {
return CONSUMER_TYPE_USER_BATTERY;
} else if (consumer instanceof SystemBatteryConsumer) {
return CONSUMER_TYPE_SYSTEM_BATTERY;
} else {
return CONSUMER_TYPE_UNKNOWN;
}
}
/** Gets battery drain type for {@link SystemBatteryConsumer}. */
public static int getDrainType(BatteryConsumer consumer) {
if (consumer instanceof SystemBatteryConsumer) {
return ((SystemBatteryConsumer) consumer).getDrainType();
}
return INVALID_DRAIN_TYPE;
}
public static ContentValues convert(
BatteryEntry entry,
BatteryUsageStats batteryUsageStats,
int batteryLevel,
int batteryStatus,
int batteryHealth,
long bootTimestamp,
long timestamp) {
final ContentValues values = new ContentValues();
if (entry != null && batteryUsageStats != null) {
values.put("uid", Long.valueOf(entry.getUid()));
values.put("userId",
values.put(BatteryHistEntry.KEY_UID, Long.valueOf(entry.getUid()));
values.put(BatteryHistEntry.KEY_USER_ID,
Long.valueOf(UserHandle.getUserId(entry.getUid())));
values.put("appLabel", entry.getLabel());
values.put("packageName", entry.getDefaultPackageName());
values.put("isHidden", Boolean.valueOf(entry.isHidden()));
values.put("totalPower",
values.put(BatteryHistEntry.KEY_APP_LABEL, entry.getLabel());
values.put(BatteryHistEntry.KEY_PACKAGE_NAME,
entry.getDefaultPackageName());
values.put(BatteryHistEntry.KEY_IS_HIDDEN, Boolean.valueOf(entry.isHidden()));
values.put(BatteryHistEntry.KEY_TOTAL_POWER,
Double.valueOf(batteryUsageStats.getConsumedPower()));
values.put("consumePower", Double.valueOf(entry.getConsumedPower()));
values.put("percentOfTotal", Double.valueOf(entry.percent));
values.put("foregroundUsageTimeInMs",
values.put(BatteryHistEntry.KEY_CONSUME_POWER,
Double.valueOf(entry.getConsumedPower()));
values.put(BatteryHistEntry.KEY_PERCENT_OF_TOTAL,
Double.valueOf(entry.percent));
values.put(BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME,
Long.valueOf(entry.getTimeInForegroundMs()));
values.put("backgroundUsageTimeInMs",
values.put(BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME,
Long.valueOf(entry.getTimeInBackgroundMs()));
values.put("drainType", getDrainType(entry.getBatteryConsumer()));
values.put("consumerType", getConsumerType(entry.getBatteryConsumer()));
values.put(BatteryHistEntry.KEY_DRAIN_TYPE,
entry.getPowerComponentId());
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE,
entry.getConsumerType());
} else {
values.put("packageName", FAKE_PACKAGE_NAME);
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, FAKE_PACKAGE_NAME);
}
values.put("timestamp", Long.valueOf(timestamp));
values.put("zoneId", TimeZone.getDefault().getID());
values.put("batteryLevel", Integer.valueOf(batteryLevel));
values.put("batteryStatus", Integer.valueOf(batteryStatus));
values.put("batteryHealth", Integer.valueOf(batteryHealth));
values.put(BatteryHistEntry.KEY_BOOT_TIMESTAMP, Long.valueOf(bootTimestamp));
values.put(BatteryHistEntry.KEY_TIMESTAMP, Long.valueOf(timestamp));
values.put(BatteryHistEntry.KEY_ZONE_ID, TimeZone.getDefault().getID());
values.put(BatteryHistEntry.KEY_BATTERY_LEVEL, Integer.valueOf(batteryLevel));
values.put(BatteryHistEntry.KEY_BATTERY_STATUS, Integer.valueOf(batteryStatus));
values.put(BatteryHistEntry.KEY_BATTERY_HEALTH, Integer.valueOf(batteryHealth));
return values;
}

View File

@@ -81,10 +81,10 @@ public class BatterySaverSettings extends DashboardFragment {
// Updates the footer for this page.
@VisibleForTesting
void setupFooter() {
mFooterText = new SpannableStringBuilder(getText(
com.android.internal.R.string.battery_saver_description_with_learn_more));
mHelpUri = getString(R.string.help_url_battery_saver_settings);
if (!TextUtils.isEmpty(mHelpUri)) {
mFooterText = new SpannableStringBuilder(getText(
com.android.internal.R.string.battery_saver_description_with_learn_more));
addHelpLink();
}
}
@@ -96,6 +96,7 @@ public class BatterySaverSettings extends DashboardFragment {
if (pref != null) {
SupportPageLearnMoreSpan.linkify(mFooterText, this, mHelpUri);
pref.setTitle(mFooterText);
pref.setSelectable(false);
}
}
@@ -129,8 +130,6 @@ public class BatterySaverSettings extends DashboardFragment {
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// remove underline
ds.setUnderlineText(false);
}
/**

View File

@@ -29,9 +29,9 @@ import android.util.Log;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.AppSwitchPreference;
import java.util.Collections;
import java.util.List;
@@ -100,7 +100,7 @@ public class ResumableMediaAppsController extends BasePreferenceController {
}
}
class MediaSwitchPreference extends SwitchPreference {
class MediaSwitchPreference extends AppSwitchPreference {
private String mPackageName;
MediaSwitchPreference(Context context, String packageName) {

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityButtonFooterPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonFooterPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private final Context mContext = ApplicationProvider.getApplicationContext();
private PreferenceScreen mScreen;
private AccessibilityButtonFooterPreferenceController mController;
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
final AccessibilityFooterPreference footerPreference =
new AccessibilityFooterPreference(mContext);
footerPreference.setKey(TEST_KEY);
mScreen.addPreference(footerPreference);
mController = new AccessibilityButtonFooterPreferenceController(mContext, TEST_KEY);
}
@Test
public void onPreferenceChange_shouldSetCorrectIconContentDescription() {
mController.displayPreference(mScreen);
final AccessibilityFooterPreference footerPreference = mScreen.findPreference(TEST_KEY);
final String packageName = mContext.getString(R.string.accessibility_button_title);
final String iconContentDescription = mContext.getString(
R.string.accessibility_introduction_title,
packageName);
assertThat(footerPreference.getIconContentDescription()).isEqualTo(iconContentDescription);
}
}

View File

@@ -22,7 +22,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
@@ -69,11 +69,11 @@ public class AccessibilityButtonLocationPreferenceControllerTest {
}
@Test
public void getAvailabilityStatus_navigationGestureEnabled_returnDisabledDependentSetting() {
public void getAvailabilityStatus_navigationGestureEnabled_returnConditionallyUnavailable() {
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
.thenReturn(NAV_BAR_MODE_GESTURAL);
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test

View File

@@ -0,0 +1,67 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link AccessibilityControlTimeoutFooterPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class AccessibilityControlTimeoutFooterPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private final Context mContext = ApplicationProvider.getApplicationContext();
private PreferenceScreen mScreen;
private AccessibilityControlTimeoutFooterPreferenceController mController;
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
final AccessibilityFooterPreference footerPreference =
new AccessibilityFooterPreference(mContext);
footerPreference.setKey(TEST_KEY);
mScreen.addPreference(footerPreference);
mController = new AccessibilityControlTimeoutFooterPreferenceController(mContext, TEST_KEY);
}
@Test
public void onPreferenceChange_shouldSetCorrectIconContentDescription() {
mController.displayPreference(mScreen);
final AccessibilityFooterPreference footerPreference =
mScreen.findPreference(TEST_KEY);
final String packageName =
mContext.getString(R.string.accessibility_setting_item_control_timeout_title);
final String iconContentDescription = mContext.getString(
R.string.accessibility_introduction_title,
packageName);
assertThat(footerPreference.getIconContentDescription()).isEqualTo(iconContentDescription);
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2019 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.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/** Tests for {@link AccessibilityFooterPreference} */
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityFooterPreferenceTest {
private static final String DEFAULT_SUMMARY = "default summary";
private static final String DEFAULT_DESCRIPTION = "default description";
private AccessibilityFooterPreference mAccessibilityFooterPreference;
private PreferenceViewHolder mPreferenceViewHolder;
@Before
public void setUp() {
final Context context = RuntimeEnvironment.application;
mAccessibilityFooterPreference = new AccessibilityFooterPreference(context);
final LayoutInflater inflater = LayoutInflater.from(context);
final View view =
inflater.inflate(R.layout.preference_footer, null);
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(view);
}
@Test
public void onBindViewHolder_initTextConfig_parseTextAndFocusable() {
mAccessibilityFooterPreference.setSummary(DEFAULT_SUMMARY);
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
android.R.id.title);
assertThat(summaryView.getText().toString()).isEqualTo(DEFAULT_SUMMARY);
assertThat(summaryView.isFocusable()).isEqualTo(true);
}
@Test
public void onBindViewHolder_initTextConfigAndAccessibleIcon_groupContentForAccessible() {
mAccessibilityFooterPreference.setSummary(DEFAULT_SUMMARY);
mAccessibilityFooterPreference.setIconContentDescription(DEFAULT_DESCRIPTION);
mAccessibilityFooterPreference.onBindViewHolder(mPreferenceViewHolder);
final TextView summaryView = (TextView) mPreferenceViewHolder.findViewById(
android.R.id.title);
assertThat(summaryView.getText().toString()).isEqualTo(DEFAULT_SUMMARY);
assertThat(summaryView.isFocusable()).isEqualTo(false);
final LinearLayout infoFrame = (LinearLayout) mPreferenceViewHolder.findViewById(
R.id.icon_frame);
assertThat(infoFrame.getContentDescription()).isEqualTo(DEFAULT_DESCRIPTION);
assertThat(infoFrame.isFocusable()).isEqualTo(false);
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link CaptionFooterPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class CaptionFooterPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private final Context mContext = ApplicationProvider.getApplicationContext();
private PreferenceScreen mScreen;
private CaptionFooterPreferenceController mController;
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
final AccessibilityFooterPreference footerPreference =
new AccessibilityFooterPreference(mContext);
footerPreference.setKey(TEST_KEY);
mScreen.addPreference(footerPreference);
mController = new CaptionFooterPreferenceController(mContext, TEST_KEY);
}
@Test
public void onPreferenceChange_shouldSetCorrectIconContentDescription() {
mController.displayPreference(mScreen);
final AccessibilityFooterPreference footerPreference = mScreen.findPreference(TEST_KEY);
final String packageName = mContext.getString(R.string.accessibility_captioning_title);
final String iconContentDescription = mContext.getString(
R.string.accessibility_introduction_title,
packageName);
assertThat(footerPreference.getIconContentDescription()).isEqualTo(iconContentDescription);
}
}

View File

@@ -16,8 +16,6 @@
package com.android.settings.accessibility;
import static androidx.lifecycle.Lifecycle.Event.ON_CREATE;
import static com.android.settings.accessibility.AccessibilityEditDialogUtils.CustomButton;
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
@@ -25,41 +23,35 @@ import static com.android.settings.accessibility.MagnificationPreferenceFragment
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.AdapterView;
import android.widget.ListView;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
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.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** Tests for {@link MagnificationModePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowDashboardFragment.class)
public class MagnificationModePreferenceControllerTest {
private static final String PREF_KEY = "screen_magnification_mode";
private static final int MAGNIFICATION_MODE_DEFAULT = MagnificationMode.ALL;
@@ -67,39 +59,38 @@ public class MagnificationModePreferenceControllerTest {
@Rule
public MockitoRule mocks = MockitoJUnit.rule();
@Mock
private PreferenceScreen mScreen;
private Context mContext;
private TestMagnificationSettingsFragment mFragment;
private MagnificationModePreferenceController mController;
private Preference mModePreference;
@Spy
private TestDialogHelper mDialogHelper = new TestDialogHelper();
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mController = new MagnificationModePreferenceController(mContext, PREF_KEY);
mScreen = spy(new PreferenceScreen(mContext, null));
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
mModePreference = new Preference(mContext);
mFragment = spy(new TestMagnificationSettingsFragment(mController));
doReturn(mScreen).when(mFragment).getPreferenceScreen();
doReturn(mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)).when(
mFragment).getChildFragmentManager();
mContext.setTheme(R.style.Theme_AppCompat);
doReturn(mModePreference).when(mScreen).findPreference(PREF_KEY);
mModePreference.setKey(PREF_KEY);
mScreen.addPreference(mModePreference);
MagnificationCapabilities.setCapabilities(mContext, MAGNIFICATION_MODE_DEFAULT);
mController = new MagnificationModePreferenceController(mContext, PREF_KEY);
showPreferenceOnTheScreen(null);
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
}
@Test
public void settingsModeIsDefault_checkedModeInDialogIsDefault() {
public void clickPreference_settingsModeIsDefault_checkedModeInDialogIsDefault() {
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
assertThat(getCheckedModeFromDialog()).isEqualTo(
MAGNIFICATION_MODE_DEFAULT);
}
@Test
public void choseModeIsDifferentFromInSettings_checkedModeInDialogIsExpected() {
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.WINDOW);
assertThat(getCheckedModeFromDialog()).isEqualTo(MagnificationMode.WINDOW);
@@ -107,11 +98,11 @@ public class MagnificationModePreferenceControllerTest {
@Test
public void dialogIsReCreated_settingsModeIsAllAndChoseWindowMode_checkedModeIsWindow() {
showPreferenceOnTheScreen(null);
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.WINDOW);
reshowPreferenceOnTheScreen();
mFragment.showDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
mDialogHelper.showDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
assertThat(getCheckedModeFromDialog()).isEqualTo(
MagnificationMode.WINDOW);
@@ -120,24 +111,22 @@ public class MagnificationModePreferenceControllerTest {
@Test
public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
enableTripleTap();
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.WINDOW);
verify(mFragment).showDialog(
verify(mDialogHelper).showDialog(
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
}
@Test
public void chooseModeAll_modeAllInSettingsAndTripleTapEnabled_notShowShortcutDialog() {
enableTripleTap();
MagnificationCapabilities.setCapabilities(mContext,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
mFragment.onCreate(Bundle.EMPTY);
mFragment.onCreateDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.ALL);
verify(mFragment, never()).showDialog(
verify(mDialogHelper, never()).showDialog(
MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
}
@@ -206,48 +195,38 @@ public class MagnificationModePreferenceControllerTest {
private void reshowPreferenceOnTheScreen() {
final Bundle bundle = new Bundle();
mFragment.onSaveInstanceState(bundle);
mFragment.onDetach();
mController.onSaveInstanceState(bundle);
showPreferenceOnTheScreen(bundle);
}
private void showPreferenceOnTheScreen(Bundle savedInstanceState) {
mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
mController.setDialogHelper(mDialogHelper);
mController.onCreate(savedInstanceState);
mController.displayPreference(mScreen);
}
private static class TestMagnificationSettingsFragment extends MagnificationSettingsFragment {
TestMagnificationSettingsFragment(AbstractPreferenceController... controllers) {
// Add given controllers for injection. Although controllers will be added in
// onAttach(). use(AbstractPreferenceController.class) returns the first added one.
for (int i = 0; i < controllers.length; i++) {
addPreferenceController(controllers[i]);
}
}
private static class TestDialogHelper implements DialogCreatable,
MagnificationModePreferenceController.DialogHelper {
private DialogCreatable mDialogDelegate;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Simulate the observable behaviour because ShadowDashFragment doesn't call
// super.create.
getSettingsLifecycle().onCreate(icicle);
getSettingsLifecycle().handleLifecycleEvent(ON_CREATE);
}
@Override
protected void showDialog(int dialogId) {
super.showDialog(dialogId);
// In current fragment architecture, we could assume onCreateDialog is called directly.
public void showDialog(int dialogId) {
onCreateDialog(dialogId);
}
@Override
protected void addPreferenceController(AbstractPreferenceController controller) {
super.addPreferenceController(controller);
public void setDialogDelegate(DialogCreatable delegate) {
mDialogDelegate = delegate;
}
@Override
public Dialog onCreateDialog(int dialogId) {
return mDialogDelegate.onCreateDialog(dialogId);
}
@Override
public int getDialogMetricsCategory(int dialogId) {
return mDialogDelegate.getDialogMetricsCategory(dialogId);
}
}
}

View File

@@ -18,23 +18,78 @@ package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Bundle;
import androidx.fragment.app.FragmentManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.List;
/** Tests for {@link MagnificationSettingsFragment} */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowDashboardFragment.class)
public class MagnificationSettingsFragmentTest {
private final Context mContext = ApplicationProvider.getApplicationContext();
private MagnificationSettingsFragment mFragment;
private PreferenceScreen mScreen;
@Before
public void setup() {
mContext.setTheme(R.style.Theme_AppCompat);
mFragment = spy(new MagnificationSettingsFragment());
mScreen = new PreferenceScreen(mContext, null);
doReturn(mContext).when(mFragment).getContext();
doReturn(mScreen).when(mFragment).getPreferenceScreen();
doReturn(mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS)).when(
mFragment).getChildFragmentManager();
}
@Test
public void showPreferenceOnTheScreen_setDialogHelper() {
showPreferenceOnTheScreen(null);
verify(mFragment).setDialogDelegate(any(MagnificationModePreferenceController.class));
}
@Test
public void onCreateDialog_setDialogDelegate_invokeDialogDelegate() {
final DialogCreatable dialogDelegate = mock(DialogCreatable.class, RETURNS_DEEP_STUBS);
when(dialogDelegate.getDialogMetricsCategory(anyInt())).thenReturn(1);
mFragment.setDialogDelegate(dialogDelegate);
mFragment.onCreateDialog(1);
mFragment.getDialogMetricsCategory(1);
verify(dialogDelegate).onCreateDialog(1);
verify(dialogDelegate).getDialogMetricsCategory(1);
}
@Test
public void getNonIndexableKeys_existInXmlLayout() {
@@ -46,4 +101,10 @@ public class MagnificationSettingsFragmentTest {
R.xml.accessibility_magnification_service_settings);
assertThat(keys).containsAtLeastElementsIn(niks);
}
private void showPreferenceOnTheScreen(Bundle savedInstanceState) {
mFragment.onAttach(mContext);
mFragment.onCreate(savedInstanceState);
mFragment.onResume();
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.
*/
package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link ToggleAutoclickFooterPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class ToggleAutoclickFooterPreferenceControllerTest {
private static final String TEST_KEY = "test_key";
private final Context mContext = ApplicationProvider.getApplicationContext();
private PreferenceScreen mScreen;
private ToggleAutoclickFooterPreferenceController mController;
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
final AccessibilityFooterPreference footerPreference =
new AccessibilityFooterPreference(mContext);
footerPreference.setKey(TEST_KEY);
mScreen.addPreference(footerPreference);
mController = new ToggleAutoclickFooterPreferenceController(mContext, TEST_KEY);
}
@Test
public void onPreferenceChange_shouldSetCorrectIconContentDescription() {
mController.displayPreference(mScreen);
final AccessibilityFooterPreference footerPreference = mScreen.findPreference(TEST_KEY);
final String packageName = mContext.getString(
R.string.accessibility_autoclick_preference_title);
final String iconContentDescription = mContext.getString(
R.string.accessibility_introduction_title,
packageName);
assertThat(footerPreference.getIconContentDescription()).isEqualTo(iconContentDescription);
}
}

View File

@@ -39,6 +39,7 @@ import androidx.annotation.XmlRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
@@ -48,6 +49,7 @@ import com.android.settings.testutils.shadow.ShadowFragment;
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.RobolectricTestRunner;
@@ -63,6 +65,8 @@ public class ToggleFeaturePreferenceFragmentTest {
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
private static final String DEFAULT_SUMMARY = "default summary";
private static final String DEFAULT_DESCRIPTION = "default description";
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
@@ -70,9 +74,10 @@ public class ToggleFeaturePreferenceFragmentTest {
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private TestToggleFeaturePreferenceFragment mFragment;
private PreferenceScreen mScreen;
private Context mContext = ApplicationProvider.getApplicationContext();
@Mock
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceManager mPreferenceManager;
@Before
@@ -83,7 +88,9 @@ public class ToggleFeaturePreferenceFragmentTest {
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
doReturn(null).when(mFragment).getPreferenceScreen();
mScreen = spy(new PreferenceScreen(mContext, null));
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
doReturn(mScreen).when(mFragment).getPreferenceScreen();
}
@Test
@@ -195,6 +202,21 @@ public class ToggleFeaturePreferenceFragmentTest {
assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE);
}
@Test
public void createFooterPreference_shouldSetAsExpectedValue() {
mFragment.createFooterPreference(mFragment.getPreferenceScreen(),
DEFAULT_SUMMARY, DEFAULT_DESCRIPTION);
AccessibilityFooterPreference accessibilityFooterPreference =
(AccessibilityFooterPreference) mFragment.getPreferenceScreen().getPreference(
mFragment.getPreferenceScreen().getPreferenceCount() - 1);
assertThat(accessibilityFooterPreference.getSummary()).isEqualTo(DEFAULT_SUMMARY);
assertThat(accessibilityFooterPreference.getIconContentDescription()).isEqualTo(
DEFAULT_DESCRIPTION);
assertThat(accessibilityFooterPreference.isSelectable()).isEqualTo(true);
assertThat(accessibilityFooterPreference.getOrder()).isEqualTo(Integer.MAX_VALUE - 1);
}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}

View File

@@ -23,9 +23,13 @@ import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
@@ -34,6 +38,7 @@ import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,21 +46,28 @@ import android.view.ViewGroup;
import androidx.annotation.XmlRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowSettingsPreferenceFragment.class})
public class ToggleScreenMagnificationPreferenceFragmentTest {
private static final String PLACEHOLDER_PACKAGE_NAME = "com.mock.example";
@@ -79,9 +91,6 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
private Context mContext;
private Resources mResources;
@Mock
private PreferenceManager mPreferenceManager;
@Mock
private FragmentActivity mActivity;
@Before
@@ -89,14 +98,11 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
mFragment = spy(new TestToggleScreenMagnificationPreferenceFragment());
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
when(mFragment.getContext()).thenReturn(mContext);
mActivity = Robolectric.setupActivity(FragmentActivity.class);
mFragment = spy(new TestToggleScreenMagnificationPreferenceFragment(mContext));
mResources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(mResources);
when(mFragment.getContext().getResources()).thenReturn(mResources);
doReturn(null).when(mFragment).getPreferenceScreen();
doReturn(mActivity).when(mFragment).getActivity();
}
@@ -257,15 +263,38 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
}
@Test
public void initSettingsPreference_notSupportsMagnificationArea_settingsPreferenceIsNull() {
public void onCreateView_notSupportsMagnificationArea_settingsPreferenceIsNull() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_magnification_area))
.thenReturn(false);
mFragment.initSettingsPreference();
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
assertThat(mFragment.mSettingsPreference).isNull();
}
@Test
public void onCreateView_setDialogDelegateAndAddTheControllerToLifeCycleObserver() {
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
verify(mFragment).setDialogDelegate(any(MagnificationModePreferenceController.class));
verify(mFragment.mSpyLifeyCycle).addObserver(
any(MagnificationModePreferenceController.class));
}
@Test
public void onCreateDialog_setDialogDelegate_invokeDialogDelegate() {
final DialogCreatable dialogDelegate = mock(DialogCreatable.class, RETURNS_DEEP_STUBS);
when(dialogDelegate.getDialogMetricsCategory(anyInt())).thenReturn(1);
mFragment.setDialogDelegate(dialogDelegate);
mFragment.onCreateDialog(1);
mFragment.getDialogMetricsCategory(1);
verify(dialogDelegate).onCreateDialog(1);
verify(dialogDelegate).getDialogMetricsCategory(1);
}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}
@@ -291,8 +320,25 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
public static class TestToggleScreenMagnificationPreferenceFragment
/**
* a test fragment that initializes PreferenceScreen for testing.
*/
static class TestToggleScreenMagnificationPreferenceFragment
extends ToggleScreenMagnificationPreferenceFragment {
private final Lifecycle mSpyLifeyCycle = Mockito.mock(Lifecycle.class);
private final Context mContext;
private final PreferenceManager mPreferenceManager;
TestToggleScreenMagnificationPreferenceFragment(Context context) {
super();
mContext = context;
mPreferenceManager = new PreferenceManager(context);
mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context));
setArguments(new Bundle());
}
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
}
@@ -313,9 +359,21 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return mock(View.class);
public PreferenceScreen getPreferenceScreen() {
return mPreferenceManager.getPreferenceScreen();
}
@Override
public <T extends Preference> T findPreference(CharSequence key) {
if (TextUtils.isEmpty(key)) {
return null;
}
return getPreferenceScreen().findPreference(key);
}
@Override
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
@Override
@@ -337,5 +395,15 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
protected void updateShortcutPreference() {
// UI related function, do nothing in tests
}
@Override
public Lifecycle getSettingsLifecycle() {
return mSpyLifeyCycle;
}
@Override
public Context getContext() {
return mContext;
}
}
}

View File

@@ -285,7 +285,7 @@ public class DashboardFeatureProviderImplTest {
}
@Test
public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() {
public void bindPreference_noSummary_shouldSetNullSummary() {
final Preference preference = new Preference(RuntimeEnvironment.application);
mActivityInfo.metaData.remove(META_DATA_PREFERENCE_SUMMARY);
@@ -295,8 +295,7 @@ public class DashboardFeatureProviderImplTest {
MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */,
Preference.DEFAULT_ORDER);
assertThat(preference.getSummary())
.isEqualTo(RuntimeEnvironment.application.getString(R.string.summary_placeholder));
assertThat(preference.getSummary()).isNull();
}
@Test

View File

@@ -33,6 +33,7 @@ import android.graphics.drawable.Drawable;
import android.text.format.DateUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
import com.android.settings.R;
@@ -482,52 +483,13 @@ public final class BatteryChartPreferenceControllerTest {
}
@Test
public void testRefreshCategoryTitle_appComponent_setHourIntoPreferenceTitle() {
public void testRefreshCategoryTitle_setHourIntoBothTitleTextView() {
mBatteryChartPreferenceController = createController();
setUpBatteryHistoryKeys();
mBatteryChartPreferenceController.mCategoryTitleType =
BatteryChartPreferenceController.CategoryTitleType.TYPE_APP_COMPONENT;
mBatteryChartPreferenceController.mAppListPrefGroup =
spy(new PreferenceCategory(mContext));
mBatteryChartPreferenceController.mExpandDividerPreference =
mExpandDividerPreference;
// Simulates select the first slot.
mBatteryChartPreferenceController.mTrapezoidIndex = 0;
mBatteryChartPreferenceController.refreshCategoryTitle();
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// Verifies the title in the preference group.
verify(mAppListGroup).setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("App usage for 4 pm-7 am");
verify(mExpandDividerPreference).setTitle(null);
}
@Test
public void testRefreshCategoryTitle_systemComponent_setHourIntoPreferenceTitle() {
setUpBatteryHistoryKeys();
mBatteryChartPreferenceController.mCategoryTitleType =
BatteryChartPreferenceController.CategoryTitleType.TYPE_SYSTEM_COMPONENT;
mBatteryChartPreferenceController.mExpandDividerPreference =
mExpandDividerPreference;
// Simulates select the first slot.
mBatteryChartPreferenceController.mTrapezoidIndex = 0;
mBatteryChartPreferenceController.refreshCategoryTitle();
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// Verifies the title in the preference group.
verify(mAppListGroup).setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("System usage for 4 pm-7 am");
verify(mExpandDividerPreference).setTitle(null);
}
@Test
public void testRefreshCategoryTitle_allComponents_setHourIntoBothTitleTextView() {
setUpBatteryHistoryKeys();
mBatteryChartPreferenceController.mCategoryTitleType =
BatteryChartPreferenceController.CategoryTitleType.TYPE_ALL_COMPONENTS;
mBatteryChartPreferenceController.mExpandDividerPreference =
mExpandDividerPreference;
spy(new ExpandDividerPreference(mContext));
// Simulates select the first slot.
mBatteryChartPreferenceController.mTrapezoidIndex = 0;
@@ -535,22 +497,25 @@ public final class BatteryChartPreferenceControllerTest {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// Verifies the title in the preference group.
verify(mAppListGroup).setTitle(captor.capture());
verify(mBatteryChartPreferenceController.mAppListPrefGroup)
.setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("App usage for 4 pm-7 am");
// Verifies the title in the expandable divider.
captor = ArgumentCaptor.forClass(String.class);
verify(mExpandDividerPreference).setTitle(captor.capture());
verify(mBatteryChartPreferenceController.mExpandDividerPreference)
.setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("System usage for 4 pm-7 am");
}
@Test
public void testRefreshCategoryTitle_allComponents_setLast24HrIntoBothTitleTextView() {
mBatteryChartPreferenceController.mCategoryTitleType =
BatteryChartPreferenceController.CategoryTitleType.TYPE_ALL_COMPONENTS;
public void testRefreshCategoryTitle_setLast24HrIntoBothTitleTextView() {
mBatteryChartPreferenceController = createController();
mBatteryChartPreferenceController.mAppListPrefGroup =
spy(new PreferenceCategory(mContext));
mBatteryChartPreferenceController.mExpandDividerPreference =
mExpandDividerPreference;
spy(new ExpandDividerPreference(mContext));
// Simulates select all condition.
mBatteryChartPreferenceController.mTrapezoidIndex =
BatteryChartView.SELECTED_INDEX_ALL;
@@ -559,12 +524,14 @@ public final class BatteryChartPreferenceControllerTest {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
// Verifies the title in the preference group.
verify(mAppListGroup).setTitle(captor.capture());
verify(mBatteryChartPreferenceController.mAppListPrefGroup)
.setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("App usage for past 24 hr");
// Verifies the title in the expandable divider.
captor = ArgumentCaptor.forClass(String.class);
verify(mExpandDividerPreference).setTitle(captor.capture());
verify(mBatteryChartPreferenceController.mExpandDividerPreference)
.setTitle(captor.capture());
assertThat(captor.getValue())
.isEqualTo("System usage for past 24 hr");
}
@@ -643,8 +610,11 @@ public final class BatteryChartPreferenceControllerTest {
}
private BatteryChartPreferenceController createController() {
return new BatteryChartPreferenceController(
mContext, "app_list", /*lifecycle=*/ null,
mSettingsActivity, mFragment);
final BatteryChartPreferenceController controller =
new BatteryChartPreferenceController(
mContext, "app_list", /*lifecycle=*/ null,
mSettingsActivity, mFragment);
controller.mPrefContext = mContext;
return controller;
}
}

View File

@@ -17,18 +17,17 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.SystemBatteryConsumer;
import android.os.UserManager;
import android.os.BatteryConsumer;
import android.os.UserHandle;
import android.os.UserManager;
import com.android.settings.R;
@@ -112,9 +111,9 @@ public final class BatteryDiffEntryTest {
public void testLoadLabelAndIcon_forSystemBattery_returnExpectedResult() {
// Generates fake testing data.
final ContentValues values = getContentValuesWithType(
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
values.put("drainType",
Integer.valueOf(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY));
Integer.valueOf(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY));
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
final BatteryDiffEntry entry = createBatteryDiffEntry(10, batteryHistEntry);

View File

@@ -28,9 +28,9 @@ 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;
@@ -68,7 +68,6 @@ public class BatteryEntryTest {
@Mock private PackageManager mockPackageManager;
@Mock private UserManager mockUserManager;
@Mock private UidBatteryConsumer mUidBatteryConsumer;
@Mock private SystemBatteryConsumer mSystemBatteryConsumer;
@Before
public void stubContextToReturnMockPackageManager() {
@@ -97,11 +96,12 @@ public class BatteryEntryTest {
consumer, false, packages, packageName);
}
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 createAggregateBatteryEntry(int powerComponentId) {
return new BatteryEntry(mMockContext, powerComponentId, 200, 100, 1000);
}
private BatteryEntry createCustomAggregateBatteryEntry(int powerComponentId) {
return new BatteryEntry(mMockContext, powerComponentId, "CUSTOM", 200, 100);
}
private BatteryEntry createUserBatteryConsumer(int userId) {
@@ -151,16 +151,22 @@ public class BatteryEntryTest {
@Test
public void batteryEntryForAOD_containCorrectInfo() {
final SystemBatteryConsumer systemBatteryConsumer = mock(SystemBatteryConsumer.class);
when(systemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY);
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
mockUserManager, systemBatteryConsumer, false, null, null);
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, 200, 100, 1000);
assertThat(entry.iconId).isEqualTo(R.drawable.ic_settings_aod);
assertThat(entry.name).isEqualTo("Ambient display");
}
@Test
public void batteryEntryForCustomComponent_containCorrectInfo() {
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 42, "ABC", 200, 100);
assertThat(entry.iconId).isEqualTo(R.drawable.ic_power_system);
assertThat(entry.name).isEqualTo("ABC");
}
@Test
public void getTimeInForegroundMs_app() {
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
@@ -173,11 +179,9 @@ public class BatteryEntryTest {
}
@Test
public void getTimeInForegroundMs_systemConsumer() {
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
mockUserManager, mSystemBatteryConsumer, false, null, null);
when(mSystemBatteryConsumer.getUsageDurationMillis()).thenReturn(100L);
public void getTimeInForegroundMs_aggregateBatteryConsumer() {
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
BatteryConsumer.POWER_COMPONENT_BLUETOOTH, 10, 20, 100);
assertThat(entry.getTimeInForegroundMs()).isEqualTo(100L);
}
@@ -195,11 +199,8 @@ public class BatteryEntryTest {
@Test
public void getTimeInBackgroundMs_systemConsumer() {
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
mockUserManager, mSystemBatteryConsumer, false, null, null);
when(mSystemBatteryConsumer.getUsageDurationMillis())
.thenReturn(100L);
final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application,
BatteryConsumer.POWER_COMPONENT_BLUETOOTH, 100, 200, 1000);
assertThat(entry.getTimeInBackgroundMs()).isEqualTo(0);
}
@@ -225,13 +226,21 @@ public class BatteryEntryTest {
}
@Test
public void getKey_SystemBatteryConsumer_returnDrainType() {
final BatteryEntry entry =
createSystemBatteryEntry(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH);
public void getKey_AggregateBatteryConsumer_returnComponentId() {
final BatteryEntry entry = createAggregateBatteryEntry(
BatteryConsumer.POWER_COMPONENT_BLUETOOTH);
final String key = entry.getKey();
assertThat(key).isEqualTo("S|2");
}
@Test
public void getKey_CustomAggregateBatteryConsumer_returnComponentId() {
final BatteryEntry entry = createCustomAggregateBatteryEntry(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 42);
final String key = entry.getKey();
assertThat(key).isEqualTo("S|1042");
}
@Test
public void getKey_UserBatteryConsumer_returnUserId() {
doReturn(mockUserManager).when(mMockContext).getSystemService(UserManager.class);

View File

@@ -17,15 +17,12 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import android.database.MatrixCursor;
import android.content.ContentValues;
import android.os.BatteryConsumer;
import android.database.MatrixCursor;
import android.os.BatteryManager;
import android.os.BatteryUsageStats;
import android.os.SystemBatteryConsumer;
import android.os.UserHandle;
import org.junit.Before;
@@ -44,8 +41,6 @@ public final class BatteryHistEntryTest {
private BatteryEntry mockBatteryEntry;
@Mock
private BatteryUsageStats mBatteryUsageStats;
@Mock
private SystemBatteryConsumer mockSystemBatteryConsumer;
@Before
public void setUp() {
@@ -65,9 +60,9 @@ public final class BatteryHistEntryTest {
mockBatteryEntry.percent = 0.3;
when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
when(mockBatteryEntry.getBatteryConsumer())
.thenReturn(mockSystemBatteryConsumer);
when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
when(mockBatteryEntry.getPowerComponentId()).thenReturn(expectedType);
when(mockBatteryEntry.getConsumerType())
.thenReturn(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
final ContentValues values =
ConvertUtils.convert(
mockBatteryEntry,
@@ -75,6 +70,7 @@ public final class BatteryHistEntryTest {
/*batteryLevel=*/ 12,
/*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
/*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
/*bootTimestamp=*/ 101L,
/*timestamp=*/ 10001L);
assertBatteryHistEntry(
@@ -98,6 +94,7 @@ public final class BatteryHistEntryTest {
BatteryHistEntry.KEY_APP_LABEL,
BatteryHistEntry.KEY_PACKAGE_NAME,
BatteryHistEntry.KEY_IS_HIDDEN,
BatteryHistEntry.KEY_BOOT_TIMESTAMP,
BatteryHistEntry.KEY_TIMESTAMP,
BatteryHistEntry.KEY_ZONE_ID,
BatteryHistEntry.KEY_TOTAL_POWER,
@@ -117,6 +114,7 @@ public final class BatteryHistEntryTest {
"Settings",
"com.google.android.settings.battery",
Integer.valueOf(1),
Long.valueOf(101l),
Long.valueOf(10001L),
TimeZone.getDefault().getID(),
Double.valueOf(5.1),
@@ -141,7 +139,7 @@ public final class BatteryHistEntryTest {
public void testGetKey_consumerUidType_returnExpectedString() {
final ContentValues values = getContentValuesWithType(
ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
values.put("uid", 3);
values.put(BatteryHistEntry.KEY_UID, 3);
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
assertThat(batteryHistEntry.getKey()).isEqualTo("3");
@@ -151,7 +149,7 @@ public final class BatteryHistEntryTest {
public void testGetKey_consumerUserType_returnExpectedString() {
final ContentValues values = getContentValuesWithType(
ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
values.put("userId", 2);
values.put(BatteryHistEntry.KEY_USER_ID, 2);
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
assertThat(batteryHistEntry.getKey()).isEqualTo("U|2");
@@ -161,7 +159,7 @@ public final class BatteryHistEntryTest {
public void testGetKey_consumerSystemType_returnExpectedString() {
final ContentValues values = getContentValuesWithType(
ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
values.put("drainType", 1);
values.put(BatteryHistEntry.KEY_DRAIN_TYPE, 1);
final BatteryHistEntry batteryHistEntry = new BatteryHistEntry(values);
assertThat(batteryHistEntry.getKey()).isEqualTo("S|1");
@@ -203,7 +201,8 @@ public final class BatteryHistEntryTest {
private static ContentValues getContentValuesWithType(int consumerType) {
final ContentValues values = new ContentValues();
values.put("consumerType", Integer.valueOf(consumerType));
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE,
Integer.valueOf(consumerType));
return values;
}
@@ -216,6 +215,7 @@ public final class BatteryHistEntryTest {
assertThat(entry.mPackageName)
.isEqualTo("com.google.android.settings.battery");
assertThat(entry.mIsHidden).isTrue();
assertThat(entry.mBootTimestamp).isEqualTo(101L);
assertThat(entry.mTimestamp).isEqualTo(10001L);
assertThat(entry.mZoneId).isEqualTo(TimeZone.getDefault().getID());
assertThat(entry.mTotalPower).isEqualTo(5.1);
@@ -223,7 +223,7 @@ public final class BatteryHistEntryTest {
assertThat(entry.mPercentOfTotal).isEqualTo(percentOfTotal);
assertThat(entry.mForegroundUsageTimeInMs).isEqualTo(1234L);
assertThat(entry.mBackgroundUsageTimeInMs).isEqualTo(5689L);
assertThat(entry.mDrainType).isEqualTo(drainType);
assertThat(entry.mPowerComponentId).isEqualTo(drainType);
assertThat(entry.mConsumerType)
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
assertThat(entry.mBatteryLevel).isEqualTo(12);

View File

@@ -44,12 +44,12 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;
import android.os.Build;
import android.os.Process;
import android.os.SystemBatteryConsumer;
import android.os.SystemClock;
import com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper;
@@ -113,7 +113,7 @@ public class BatteryUtilsTest {
@Mock
private BatteryUsageStats mBatteryUsageStats;
@Mock
private SystemBatteryConsumer mSystemBatteryConsumer;
private BatteryConsumer mAggregateBatteryConsumer;
@Mock
private BatteryInfo mBatteryInfo;
@Mock
@@ -218,53 +218,47 @@ public class BatteryUtilsTest {
@Test
public void testShouldHideSystemConsumer_TypeIdle_ReturnTrue() {
when(mSystemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_IDLE);
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue();
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_IDLE)).isTrue();
}
@Test
public void testShouldHideSystemConsumer_TypeMobileRadio_ReturnTrue() {
when(mSystemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO);
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue();
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)).isTrue();
}
@Test
public void testShouldHideSystemConsumer_TypeScreen_ReturnTrue() {
when(mSystemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_SCREEN);
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue();
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_SCREEN)).isTrue();
}
@Test
public void testShouldHideSystemConsumer_TypeBluetooth_ReturnTrue() {
when(mSystemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH);
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue();
}
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_BLUETOOTH)).isTrue(); }
@Test
public void testShouldHideSystemConsumer_TypeWifi_ReturnTrue() {
when(mSystemBatteryConsumer.getDrainType())
.thenReturn(SystemBatteryConsumer.DRAIN_TYPE_WIFI);
assertThat(mBatteryUtils.shouldHideSystemBatteryConsumer(mSystemBatteryConsumer)).isTrue();
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_WIFI)).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();
when(mAggregateBatteryConsumer.getConsumedPower(
BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)).thenReturn(0.0005);
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)).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();
when(mAggregateBatteryConsumer.getConsumedPower(
BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)).thenReturn(0.5);
assertThat(mBatteryUtils.shouldHideDevicePowerComponent(mAggregateBatteryConsumer,
BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)).isFalse();
}
@Test

View File

@@ -17,18 +17,13 @@ package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.ContentValues;
import android.content.Context;
import android.os.BatteryConsumer;
import android.os.BatteryManager;
import android.os.BatteryUsageStats;
import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
import android.os.UserHandle;
import org.junit.Before;
@@ -39,12 +34,10 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
@@ -56,14 +49,6 @@ public final class ConvertUtilsTest {
private BatteryUsageStats mBatteryUsageStats;
@Mock
private BatteryEntry mockBatteryEntry;
@Mock
private BatteryConsumer mockBatteryConsumer;
@Mock
private UidBatteryConsumer mockUidBatteryConsumer;
@Mock
private UserBatteryConsumer mockUserBatteryConsumer;
@Mock
private SystemBatteryConsumer mockSystemBatteryConsumer;
@Before
public void setUp() {
@@ -84,9 +69,9 @@ public final class ConvertUtilsTest {
mockBatteryEntry.percent = 0.3;
when(mockBatteryEntry.getTimeInForegroundMs()).thenReturn(1234L);
when(mockBatteryEntry.getTimeInBackgroundMs()).thenReturn(5689L);
when(mockBatteryEntry.getBatteryConsumer())
.thenReturn(mockSystemBatteryConsumer);
when(mockSystemBatteryConsumer.getDrainType()).thenReturn(expectedType);
when(mockBatteryEntry.getPowerComponentId()).thenReturn(expectedType);
when(mockBatteryEntry.getConsumerType())
.thenReturn(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
final ContentValues values =
ConvertUtils.convert(
@@ -95,30 +80,36 @@ public final class ConvertUtilsTest {
/*batteryLevel=*/ 12,
/*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
/*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
/*bootTimestamp=*/ 101L,
/*timestamp=*/ 10001L);
assertThat(values.getAsLong("uid")).isEqualTo(1001L);
assertThat(values.getAsLong("userId"))
assertThat(values.getAsLong(BatteryHistEntry.KEY_UID)).isEqualTo(1001L);
assertThat(values.getAsLong(BatteryHistEntry.KEY_USER_ID))
.isEqualTo(UserHandle.getUserId(1001));
assertThat(values.getAsString("appLabel")).isEqualTo("Settings");
assertThat(values.getAsString("packageName"))
assertThat(values.getAsString(BatteryHistEntry.KEY_APP_LABEL))
.isEqualTo("Settings");
assertThat(values.getAsString(BatteryHistEntry.KEY_PACKAGE_NAME))
.isEqualTo("com.google.android.settings.battery");
assertThat(values.getAsBoolean("isHidden")).isTrue();
assertThat(values.getAsLong("timestamp")).isEqualTo(10001L);
assertThat(values.getAsString("zoneId"))
assertThat(values.getAsBoolean(BatteryHistEntry.KEY_IS_HIDDEN)).isTrue();
assertThat(values.getAsLong(BatteryHistEntry.KEY_BOOT_TIMESTAMP))
.isEqualTo(101L);
assertThat(values.getAsLong(BatteryHistEntry.KEY_TIMESTAMP)).isEqualTo(10001L);
assertThat(values.getAsString(BatteryHistEntry.KEY_ZONE_ID))
.isEqualTo(TimeZone.getDefault().getID());
assertThat(values.getAsDouble("totalPower")).isEqualTo(5.1);
assertThat(values.getAsDouble("consumePower")).isEqualTo(1.1);
assertThat(values.getAsDouble("percentOfTotal")).isEqualTo(0.3);
assertThat(values.getAsLong("foregroundUsageTimeInMs")).isEqualTo(1234L);
assertThat(values.getAsLong("backgroundUsageTimeInMs")).isEqualTo(5689L);
assertThat(values.getAsInteger("drainType")).isEqualTo(expectedType);
assertThat(values.getAsInteger("consumerType"))
assertThat(values.getAsDouble(BatteryHistEntry.KEY_TOTAL_POWER)).isEqualTo(5.1);
assertThat(values.getAsDouble(BatteryHistEntry.KEY_CONSUME_POWER)).isEqualTo(1.1);
assertThat(values.getAsDouble(BatteryHistEntry.KEY_PERCENT_OF_TOTAL)).isEqualTo(0.3);
assertThat(values.getAsLong(BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME))
.isEqualTo(1234L);
assertThat(values.getAsLong(BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME))
.isEqualTo(5689L);
assertThat(values.getAsInteger(BatteryHistEntry.KEY_DRAIN_TYPE)).isEqualTo(expectedType);
assertThat(values.getAsInteger(BatteryHistEntry.KEY_CONSUMER_TYPE))
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
assertThat(values.getAsInteger("batteryLevel")).isEqualTo(12);
assertThat(values.getAsInteger("batteryStatus"))
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_LEVEL)).isEqualTo(12);
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_STATUS))
.isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
assertThat(values.getAsInteger("batteryHealth"))
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_HEALTH))
.isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
}
@@ -131,52 +122,24 @@ public final class ConvertUtilsTest {
/*batteryLevel=*/ 12,
/*batteryStatus=*/ BatteryManager.BATTERY_STATUS_FULL,
/*batteryHealth=*/ BatteryManager.BATTERY_HEALTH_COLD,
/*bootTimestamp=*/ 101L,
/*timestamp=*/ 10001L);
assertThat(values.getAsLong("timestamp")).isEqualTo(10001L);
assertThat(values.getAsString("zoneId"))
assertThat(values.getAsLong(BatteryHistEntry.KEY_BOOT_TIMESTAMP))
.isEqualTo(101L);
assertThat(values.getAsLong(BatteryHistEntry.KEY_TIMESTAMP))
.isEqualTo(10001L);
assertThat(values.getAsString(BatteryHistEntry.KEY_ZONE_ID))
.isEqualTo(TimeZone.getDefault().getID());
assertThat(values.getAsInteger("batteryLevel")).isEqualTo(12);
assertThat(values.getAsInteger("batteryStatus"))
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_LEVEL)).isEqualTo(12);
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_STATUS))
.isEqualTo(BatteryManager.BATTERY_STATUS_FULL);
assertThat(values.getAsInteger("batteryHealth"))
assertThat(values.getAsInteger(BatteryHistEntry.KEY_BATTERY_HEALTH))
.isEqualTo(BatteryManager.BATTERY_HEALTH_COLD);
assertThat(values.getAsString("packageName"))
assertThat(values.getAsString(BatteryHistEntry.KEY_PACKAGE_NAME))
.isEqualTo(ConvertUtils.FAKE_PACKAGE_NAME);
}
@Test
public void testGetDrainType_returnsExpetcedResult() {
final int expectedType = 3;
when(mockSystemBatteryConsumer.getDrainType())
.thenReturn(expectedType);
assertThat(ConvertUtils.getDrainType(mockSystemBatteryConsumer))
.isEqualTo(expectedType);
}
@Test
public void testGetDrainType_notValidConsumer_returnsInvalidTypeValue() {
assertThat(ConvertUtils.getDrainType(mockUserBatteryConsumer))
.isEqualTo(ConvertUtils.INVALID_DRAIN_TYPE);
}
@Test
public void testGetConsumerType_returnsExpetcedResult() {
assertThat(ConvertUtils.getConsumerType(mockUidBatteryConsumer))
.isEqualTo(ConvertUtils.CONSUMER_TYPE_UID_BATTERY);
assertThat(ConvertUtils.getConsumerType(mockUserBatteryConsumer))
.isEqualTo(ConvertUtils.CONSUMER_TYPE_USER_BATTERY);
assertThat(ConvertUtils.getConsumerType(mockSystemBatteryConsumer))
.isEqualTo(ConvertUtils.CONSUMER_TYPE_SYSTEM_BATTERY);
}
@Test
public void testGetConsumeType_invalidConsumer_returnsInvalidType() {
assertThat(ConvertUtils.getConsumerType(mockBatteryConsumer))
.isEqualTo(ConvertUtils.CONSUMER_TYPE_UNKNOWN);
}
@Test
public void testGetIndexedUsageMap_returnsExpectedResult() {
// Creates the fake testing data.
@@ -287,14 +250,16 @@ public final class ConvertUtilsTest {
long uid, long foregroundUsageTimeInMs, long backgroundUsageTimeInMs) {
// Only insert required fields.
final ContentValues values = new ContentValues();
values.put("packageName", packageName);
values.put("appLabel", appLabel);
values.put("uid", Long.valueOf(uid));
values.put("consumerType",
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, packageName);
values.put(BatteryHistEntry.KEY_APP_LABEL, appLabel);
values.put(BatteryHistEntry.KEY_UID, Long.valueOf(uid));
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE,
Integer.valueOf(ConvertUtils.CONSUMER_TYPE_UID_BATTERY));
values.put("consumePower", consumePower);
values.put("foregroundUsageTimeInMs", Long.valueOf(foregroundUsageTimeInMs));
values.put("backgroundUsageTimeInMs", Long.valueOf(backgroundUsageTimeInMs));
values.put(BatteryHistEntry.KEY_CONSUME_POWER, consumePower);
values.put(BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME,
Long.valueOf(foregroundUsageTimeInMs));
values.put(BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME,
Long.valueOf(backgroundUsageTimeInMs));
return new BatteryHistEntry(values);
}

View File

@@ -0,0 +1,43 @@
/*
* 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.
*/
package com.android.settings.testutils.shadow;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.settings.SettingsPreferenceFragment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
/**
* Shadow of {@link SettingsPreferenceFragment}.
*
* Override the {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}} to skip inflating
* a View from a xml.
*/
@Implements(SettingsPreferenceFragment.class)
public class ShadowSettingsPreferenceFragment extends ShadowFragment {
@Implementation
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return container;
}
}

View File

@@ -22,7 +22,9 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
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;
@@ -30,20 +32,22 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.TrafficStats;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.SparseArray;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.settings.R;
import com.android.settingslib.applications.StorageStatsSource;
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;
@@ -57,11 +61,11 @@ public class StorageAsyncLoaderTest {
private static final int SECONDARY_USER_ID = 10;
private static final String PACKAGE_NAME_1 = "com.blah.test";
private static final String PACKAGE_NAME_2 = "com.blah.test2";
private static final String PACKAGE_NAME_3 = "com.blah.test3";
private static final long DEFAULT_QUOTA = 64 * TrafficStats.MB_IN_BYTES;
@Mock
private StorageStatsSource mSource;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
private PackageManager mPackageManager;
@@ -76,6 +80,7 @@ public class StorageAsyncLoaderTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mContext = spy(ApplicationProvider.getApplicationContext());
mInfo = new ArrayList<>();
mLoader = new StorageAsyncLoader(mContext, mUserManager, "id", mSource, mPackageManager);
when(mPackageManager.getInstalledApplicationsAsUser(eq(PRIMARY_USER_ID), anyInt()))
@@ -85,6 +90,10 @@ public class StorageAsyncLoaderTest {
mUsers.add(info);
when(mUserManager.getUsers()).thenReturn(mUsers);
when(mSource.getCacheQuotaBytes(anyString(), anyInt())).thenReturn(DEFAULT_QUOTA);
final Resources resources = spy(mContext.getResources());
when(mContext.getResources()).thenReturn(resources);
doReturn("content://com.android.providers.media.documents/root/videos_root")
.when(resources).getString(R.string.config_videos_storage_category_uri);
}
@Test
@@ -169,8 +178,8 @@ public class StorageAsyncLoaderTest {
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(11L);
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0);
// Code size is not included for file based video category.
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(10L);
}
@Test
@@ -206,7 +215,8 @@ public class StorageAsyncLoaderTest {
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
assertThat(result.size()).isEqualTo(2);
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(11L);
// Code size is not included for file based video category.
assertThat(result.get(PRIMARY_USER_ID).videoAppsSize).isEqualTo(10L);
// No code size for the second user.
assertThat(result.get(SECONDARY_USER_ID).videoAppsSize).isEqualTo(10L);
}
@@ -221,6 +231,18 @@ public class StorageAsyncLoaderTest {
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(DEFAULT_QUOTA + 11);
}
@Test
public void testAppsAreFiltered() throws Exception {
addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_IMAGE);
addPackage(PACKAGE_NAME_2, 0, 1, 10, ApplicationInfo.CATEGORY_VIDEO);
addPackage(PACKAGE_NAME_3, 0, 1, 10, ApplicationInfo.CATEGORY_AUDIO);
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(33L);
}
private ApplicationInfo addPackage(String packageName, long cacheSize, long codeSize,
long dataSize, int category) throws Exception {
StorageStatsSource.AppStorageStats storageStats =