Add BatteryTipDialogFragment.

This DialogFragment handles all the tip related dialogs. This cl makes:
1. All the tips parcelable.
2. Add dialog for HighUsageTip. It also need adapter to populate app
list in dialog.
3. Add and update tests

Bug: 70570352
Test: RunSettingsRoboTests
Change-Id: Ie4c986172cfc73d8746abc7457d966c8600c6145
This commit is contained in:
jackqdyulei
2018-01-02 14:51:01 -08:00
parent ca102facf0
commit fde637ff60
19 changed files with 601 additions and 92 deletions

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:paddingStart="?android:dialogPreferredPadding"
android:paddingEnd="?android:dialogPreferredPadding"
android:orientation="horizontal">
<ImageView
android:id="@+id/app_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"/>
<TextView
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="24dp"
android:textColor="?android:textColorPrimary"
android:paddingEnd="7dp"/>
<TextView
android:id="@+id/app_screen_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingEnd="16dp"
android:textAlignment="viewEnd"
android:textColor="?android:textColorPrimary"/>
</LinearLayout>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 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.
-->
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:scrollbars="vertical"/>

View File

@@ -94,6 +94,7 @@ import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.TtsSpan;
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -1382,4 +1383,18 @@ public final class Utils extends com.android.settingslib.Utils {
}
return new BitmapDrawable(null, bitmap);
}
/**
* Get the {@link Drawable} that represents the app icon
*/
public static Drawable getBadgedIcon(IconDrawableFactory iconDrawableFactory,
PackageManager packageManager, String packageName, int userId) {
try {
final ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName,
PackageManager.GET_META_DATA);
return iconDrawableFactory.getBadgedIcon(appInfo, userId);
} catch (PackageManager.NameNotFoundException e) {
return packageManager.getDefaultActivityIcon();
}
}
}

View File

@@ -31,6 +31,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment;
@@ -151,12 +152,6 @@ public class PowerUsageAnomalyDetails extends DashboardFragment implements
@VisibleForTesting
Drawable getBadgedIcon(String packageName, int userId) {
try {
final ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName,
PackageManager.GET_META_DATA);
return mIconDrawableFactory.getBadgedIcon(appInfo, userId);
} catch (PackageManager.NameNotFoundException e) {
return mPackageManager.getDefaultActivityIcon();
}
return Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, packageName, userId);
}
}

View File

@@ -266,7 +266,7 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
KEY_APP_LIST, lifecycle, activity, this);
controllers.add(mBatteryAppListPreferenceController);
mBatteryTipPreferenceController = new BatteryTipPreferenceController(context,
KEY_BATTERY_TIP, this);
KEY_BATTERY_TIP, this, this);
controllers.add(mBatteryTipPreferenceController);
controllers.add(new BatterySaverController(context, getLifecycle()));
controllers.add(new BatteryPercentagePreferenceController(context));

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController.BatteryTipListener;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
/**
* Dialog Fragment to show action dialog for each anomaly
*/
public class BatteryTipDialogFragment extends InstrumentedDialogFragment implements
DialogInterface.OnClickListener {
private static final String ARG_BATTERY_TIP = "battery_tip";
@VisibleForTesting
BatteryTip mBatteryTip;
public static BatteryTipDialogFragment newInstance(BatteryTip batteryTip) {
BatteryTipDialogFragment dialogFragment = new BatteryTipDialogFragment();
Bundle args = new Bundle(1);
args.putParcelable(ARG_BATTERY_TIP, batteryTip);
dialogFragment.setArguments(args);
return dialogFragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Bundle bundle = getArguments();
final Context context = getContext();
mBatteryTip = bundle.getParcelable(ARG_BATTERY_TIP);
switch (mBatteryTip.getType()) {
case BatteryTip.TipType.SUMMARY:
case BatteryTip.TipType.LOW_BATTERY:
//TODO(b/70570352): add dialog
return null;
case BatteryTip.TipType.HIGH_DEVICE_USAGE:
final HighUsageTip highUsageTip = (HighUsageTip) mBatteryTip;
final RecyclerView view = (RecyclerView) LayoutInflater.from(context).inflate(
R.layout.recycler_view,
null);
view.setLayoutManager(new LinearLayoutManager(context));
view.setAdapter(new HighUsageAdapter(context,
highUsageTip.getHighUsageAppList()));
return new AlertDialog.Builder(context)
.setMessage(getString(R.string.battery_tip_dialog_message,
highUsageTip.getScreenTimeMs()))
.setView(view)
.setPositiveButton(android.R.string.ok, null)
.create();
default:
throw new IllegalArgumentException("unknown type " + mBatteryTip.getType());
}
}
@Override
public int getMetricsCategory() {
//TODO(b/70570352): add correct metric id
return 0;
}
@Override
public void onClick(DialogInterface dialog, int which) {
final BatteryTipListener lsn = (BatteryTipListener) getTargetFragment();
if (lsn == null) {
return;
}
mBatteryTip.action();
lsn.onBatteryTipHandled(mBatteryTip);
}
}

View File

@@ -18,6 +18,7 @@ package com.android.settings.fuelgauge.batterytip;
import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.PreferenceFragment;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
@@ -34,6 +35,9 @@ import java.util.Map;
* Controller in charge of the battery tip group
*/
public class BatteryTipPreferenceController extends BasePreferenceController {
private static final String TAG = "BatteryTipPreferenceController";
private static final int REQUEST_ANOMALY_ACTION = 0;
private BatteryTipListener mBatteryTipListener;
private List<BatteryTip> mBatteryTips;
private Map<String, BatteryTip> mBatteryTipMap;
@@ -41,16 +45,18 @@ public class BatteryTipPreferenceController extends BasePreferenceController {
PreferenceGroup mPreferenceGroup;
@VisibleForTesting
Context mPrefContext;
PreferenceFragment mFragment;
public BatteryTipPreferenceController(Context context, String preferenceKey) {
this(context, preferenceKey, null);
this(context, preferenceKey, null, null);
}
public BatteryTipPreferenceController(Context context, String preferenceKey,
BatteryTipListener batteryTipListener) {
PreferenceFragment fragment, BatteryTipListener batteryTipListener) {
super(context, preferenceKey);
mBatteryTipListener = batteryTipListener;
mBatteryTipMap = new HashMap<>();
mFragment = fragment;
}
@Override
@@ -96,7 +102,10 @@ public class BatteryTipPreferenceController extends BasePreferenceController {
final BatteryTip batteryTip = mBatteryTipMap.get(preference.getKey());
if (batteryTip != null) {
if (batteryTip.shouldShowDialog()) {
// build and show the dialog
BatteryTipDialogFragment dialogFragment = BatteryTipDialogFragment.newInstance(
batteryTip);
dialogFragment.setTargetFragment(mFragment, REQUEST_ANOMALY_ACTION);
dialogFragment.show(mFragment.getFragmentManager(), TAG);
} else {
batteryTip.action();
if (mBatteryTipListener != null) {

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.support.v7.widget.RecyclerView;
import android.util.IconDrawableFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.Utils;
import java.util.List;
/**
* Adapter for the high usage app list
*/
public class HighUsageAdapter extends RecyclerView.Adapter<HighUsageAdapter.ViewHolder> {
private final Context mContext;
private final IconDrawableFactory mIconDrawableFactory;
private final PackageManager mPackageManager;
private final List<HighUsageApp> mHighUsageAppList;
public static class ViewHolder extends RecyclerView.ViewHolder {
public View view;
public ImageView appIcon;
public TextView appName;
public TextView appTime;
public ViewHolder(View v) {
super(v);
view = v;
appIcon = v.findViewById(R.id.app_icon);
appName = v.findViewById(R.id.app_name);
appTime = v.findViewById(R.id.app_screen_time);
}
}
public HighUsageAdapter(Context context, List<HighUsageApp> highUsageAppList) {
mContext = context;
mHighUsageAppList = highUsageAppList;
mIconDrawableFactory = IconDrawableFactory.newInstance(context);
mPackageManager = context.getPackageManager();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.app_high_usage_item,
parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final HighUsageApp app = mHighUsageAppList.get(position);
holder.appIcon.setImageDrawable(
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, app.packageName,
UserHandle.myUserId()));
holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName));
holder.appTime.setText(Utils.formatElapsedTime(mContext, app.screenOnTimeMs, false));
}
@Override
public int getItemCount() {
return mHighUsageAppList.size();
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Class representing app with high screen usage
*/
public class HighUsageApp implements Comparable<HighUsageApp>, Parcelable {
public final String packageName;
public final long screenOnTimeMs;
public HighUsageApp(String packageName, long screenOnTimeMs) {
this.packageName = packageName;
this.screenOnTimeMs = screenOnTimeMs;
}
private HighUsageApp(Parcel in) {
packageName = in.readString();
screenOnTimeMs = in.readLong();
}
@Override
public int compareTo(HighUsageApp o) {
return Long.compare(screenOnTimeMs, o.screenOnTimeMs);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeLong(screenOnTimeMs);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public HighUsageApp createFromParcel(Parcel in) {
return new HighUsageApp(in);
}
public HighUsageApp[] newArray(int size) {
return new HighUsageApp[size];
}
};
}

View File

@@ -26,6 +26,7 @@ import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
import com.android.settings.fuelgauge.batterytip.HighUsageApp;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
@@ -41,7 +42,7 @@ import java.util.List;
public class HighUsageDetector implements BatteryTipDetector {
private BatteryTipPolicy mPolicy;
private BatteryStatsHelper mBatteryStatsHelper;
private List<HighUsageTip.HighUsageApp> mHighUsageAppList;
private List<HighUsageApp> mHighUsageAppList;
private Context mContext;
@VisibleForTesting
BatteryUtils mBatteryUtils;
@@ -67,7 +68,7 @@ public class HighUsageDetector implements BatteryTipDetector {
final long foregroundTimeMs = mBatteryUtils.getProcessTimeMs(
BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
BatteryStats.STATS_SINCE_CHARGED);
mHighUsageAppList.add(new HighUsageTip.HighUsageApp(
mHighUsageAppList.add(new HighUsageApp(
mBatteryUtils.getPackageName(batterySipper.getUid()),
foregroundTimeMs));
}
@@ -78,7 +79,6 @@ public class HighUsageDetector implements BatteryTipDetector {
Collections.sort(mHighUsageAppList, Collections.reverseOrder());
}
return new HighUsageTip(Utils.formatElapsedTime(mContext, screenUsageTimeMs, false),
mHighUsageAppList);
return new HighUsageTip(screenUsageTimeMs, mHighUsageAppList);
}
}

View File

@@ -16,8 +16,9 @@
package com.android.settings.fuelgauge.batterytip.tips;
import android.app.Dialog;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
import android.support.annotation.IntDef;
import android.support.v7.preference.Preference;
@@ -31,7 +32,7 @@ import java.lang.annotation.RetentionPolicy;
* Each {@link BatteryTip} contains basic data(e.g. title, summary, icon) as well as the
* pre-defined action(e.g. turn on battery saver)
*/
public abstract class BatteryTip implements Comparable<BatteryTip> {
public abstract class BatteryTip implements Comparable<BatteryTip>, Parcelable {
@Retention(RetentionPolicy.SOURCE)
@IntDef({StateType.NEW,
StateType.HANDLED,
@@ -62,12 +63,34 @@ public abstract class BatteryTip implements Comparable<BatteryTip> {
private static final String KEY_PREFIX = "key_battery_tip";
@TipType
protected int mType;
@StateType
protected int mState;
protected boolean mShowDialog;
BatteryTip(Parcel in) {
mType = in.readInt();
mState = in.readInt();
mShowDialog = in.readBoolean();
}
BatteryTip(int type, int state, boolean showDialog) {
mType = type;
mState = state;
mShowDialog = showDialog;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeInt(mState);
dest.writeBoolean(mShowDialog);
}
public abstract CharSequence getTitle(Context context);
public abstract CharSequence getSummary(Context context);
@@ -77,6 +100,7 @@ public abstract class BatteryTip implements Comparable<BatteryTip> {
/**
* Update the current {@link #mState} using the new {@code tip}.
*
* @param tip used to update
*/
public abstract void updateState(BatteryTip tip);
@@ -86,12 +110,6 @@ public abstract class BatteryTip implements Comparable<BatteryTip> {
*/
public abstract void action();
/**
* Build the dialog to display either the info about {@link BatteryTip} or confirmation
* about the action.
*/
public abstract Dialog buildDialog();
public Preference buildPreference(Context context) {
Preference preference = new Preference(context);
@@ -110,6 +128,10 @@ public abstract class BatteryTip implements Comparable<BatteryTip> {
return KEY_PREFIX + mType;
}
public int getType() {
return mType;
}
@StateType
public int getState() {
return mState;

View File

@@ -16,10 +16,14 @@
package com.android.settings.fuelgauge.batterytip.tips;
import android.app.Dialog;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.batterytip.HighUsageApp;
import java.util.List;
@@ -28,15 +32,29 @@ import java.util.List;
*/
public class HighUsageTip extends BatteryTip {
private final CharSequence mScreenTimeText;
private final List<HighUsageApp> mHighUsageAppList;
private final long mScreenTimeMs;
@VisibleForTesting
final List<HighUsageApp> mHighUsageAppList;
public HighUsageTip(CharSequence screenTimeText, List<HighUsageApp> appList) {
mShowDialog = true;
mScreenTimeText = screenTimeText;
mType = TipType.HIGH_DEVICE_USAGE;
public HighUsageTip(long screenTimeMs, List<HighUsageApp> appList) {
super(TipType.HIGH_DEVICE_USAGE, appList.isEmpty() ? StateType.INVISIBLE : StateType.NEW,
true /* showDialog */);
mScreenTimeMs = screenTimeMs;
mHighUsageAppList = appList;
mState = appList.isEmpty() ? StateType.INVISIBLE : StateType.NEW;
}
@VisibleForTesting
HighUsageTip(Parcel in) {
super(in);
mScreenTimeMs = in.readLong();
mHighUsageAppList = in.createTypedArrayList(HighUsageApp.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeLong(mScreenTimeMs);
dest.writeTypedList(mHighUsageAppList);
}
@Override
@@ -46,7 +64,8 @@ public class HighUsageTip extends BatteryTip {
@Override
public CharSequence getSummary(Context context) {
return context.getString(R.string.battery_tip_high_usage_summary, mScreenTimeText);
return context.getString(R.string.battery_tip_high_usage_summary,
Utils.formatElapsedTime(context, mScreenTimeMs, false));
}
@Override
@@ -64,27 +83,22 @@ public class HighUsageTip extends BatteryTip {
// do nothing
}
@Override
public Dialog buildDialog() {
//TODO(b/70570352): build the real dialog
return null;
public long getScreenTimeMs() {
return mScreenTimeMs;
}
/**
* Class representing app with high screen usage
*/
public static class HighUsageApp implements Comparable<HighUsageApp> {
public final String packageName;
public final long screenOnTimeMs;
public HighUsageApp(String packageName, long screenOnTimeMs) {
this.packageName = packageName;
this.screenOnTimeMs = screenOnTimeMs;
}
@Override
public int compareTo(HighUsageApp o) {
return Long.compare(screenOnTimeMs, o.screenOnTimeMs);
}
public List<HighUsageApp> getHighUsageAppList() {
return mHighUsageAppList;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public BatteryTip createFromParcel(Parcel in) {
return new HighUsageTip(in);
}
public BatteryTip[] newArray(int size) {
return new HighUsageTip[size];
}
};
}

View File

@@ -16,8 +16,9 @@
package com.android.settings.fuelgauge.batterytip.tips;
import android.app.Dialog;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.settings.R;
@@ -27,9 +28,11 @@ import com.android.settings.R;
public class LowBatteryTip extends BatteryTip {
public LowBatteryTip(@StateType int state) {
mShowDialog = false;
mState = state;
mType = TipType.LOW_BATTERY;
super(TipType.LOW_BATTERY, state, false /* showDialog */);
}
private LowBatteryTip(Parcel in) {
super(in);
}
@Override
@@ -57,9 +60,14 @@ public class LowBatteryTip extends BatteryTip {
// do nothing
}
@Override
public Dialog buildDialog() {
//TODO(b/70570352): create the dialog for low battery tip and add test
return null;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public BatteryTip createFromParcel(Parcel in) {
return new LowBatteryTip(in);
}
public BatteryTip[] newArray(int size) {
return new LowBatteryTip[size];
}
};
}

View File

@@ -16,8 +16,9 @@
package com.android.settings.fuelgauge.batterytip.tips;
import android.app.Dialog;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.settings.R;
@@ -27,9 +28,11 @@ import com.android.settings.R;
public class SummaryTip extends BatteryTip {
public SummaryTip(@StateType int state) {
mShowDialog = false;
mState = state;
mType = TipType.SUMMARY;
super(TipType.SUMMARY, state, false /* showDialog */);
}
private SummaryTip(Parcel in) {
super(in);
}
@Override
@@ -57,9 +60,13 @@ public class SummaryTip extends BatteryTip {
// do nothing
}
@Override
public Dialog buildDialog() {
//TODO(b/70570352): create the dialog for summary tip and add test
return null;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public BatteryTip createFromParcel(Parcel in) {
return new SummaryTip(in);
}
public BatteryTip[] newArray(int size) {
return new SummaryTip[size];
}
};
}

View File

@@ -4,13 +4,16 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyString;
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;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
import android.net.LinkAddress;
@@ -25,6 +28,7 @@ import android.os.storage.VolumeInfo;
import android.text.SpannableStringBuilder;
import android.text.format.DateUtils;
import android.text.style.TtsSpan;
import android.util.IconDrawableFactory;
import android.widget.EditText;
import android.widget.TextView;
@@ -46,8 +50,8 @@ import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class UtilsTest {
private static final String PACKAGE_NAME = "com.android.app";
private static final int USER_ID = 1;
@Mock
private WifiManager wifiManager;
@@ -59,6 +63,12 @@ public class UtilsTest {
private DevicePolicyManagerWrapper mDevicePolicyManager;
@Mock
private UserManager mUserManager;
@Mock
private PackageManager mPackageManager;
@Mock
private IconDrawableFactory mIconDrawableFactory;
@Mock
private ApplicationInfo mApplicationInfo;
private Context mContext;
@Before
@@ -332,4 +342,17 @@ public class UtilsTest {
assertThat(editText.getSelectionEnd()).isEqualTo(length);
}
@Test
public void testGetBadgedIcon_usePackageNameAndUserId() throws
PackageManager.NameNotFoundException {
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME,
PackageManager.GET_META_DATA);
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, PACKAGE_NAME, USER_ID);
// Verify that it uses the correct user id
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
}
}

View File

@@ -67,7 +67,6 @@ public class PowerUsageAnomalyDetailsTest {
private static final String PACKAGE_NAME_1 = "com.android.app1";
private static final String PACKAGE_NAME_2 = "com.android.app2";
private static final String PACKAGE_NAME_3 = "com.android.app3";
private static final int USER_ID = 1;
@Mock
private SettingsActivity mSettingsActivity;
@@ -198,16 +197,4 @@ public class PowerUsageAnomalyDetailsTest {
assertThat(mBundle.getParcelableArrayList(
PowerUsageAnomalyDetails.EXTRA_ANOMALY_LIST)).isEqualTo(mAnomalyList);
}
@Test
public void testGetBadgedIcon_usePackageNameAndUserId() throws
PackageManager.NameNotFoundException {
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME_1,
PackageManager.GET_META_DATA);
mFragment.getBadgedIcon(PACKAGE_NAME_1, USER_ID);
// Verify that it uses the correct user id
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
}
}

View File

@@ -85,7 +85,7 @@ public class BatteryTipPreferenceControllerTest {
mNewBatteryTips.add(new SummaryTip(BatteryTip.StateType.INVISIBLE));
mBatteryTipPreferenceController = new BatteryTipPreferenceController(mContext, KEY_PREF,
mBatteryTipListener);
null, mBatteryTipListener);
mBatteryTipPreferenceController.mPreferenceGroup = mPreferenceGroup;
mBatteryTipPreferenceController.mPrefContext = mContext;
}

View File

@@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Dialog;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
import android.support.v7.preference.Preference;
@@ -58,10 +60,32 @@ public class BatteryTipTest {
assertThat(preference.getIcon()).isEqualTo(mContext.getDrawable(ICON_ID));
}
@Test
public void testParcelable() {
final BatteryTip batteryTip = new TestBatteryTip();
Parcel parcel = Parcel.obtain();
batteryTip.writeToParcel(parcel, batteryTip.describeContents());
parcel.setDataPosition(0);
final BatteryTip parcelTip = new TestBatteryTip(parcel);
assertThat(parcelTip.getTitle(mContext)).isEqualTo(TITLE);
assertThat(parcelTip.getSummary(mContext)).isEqualTo(SUMMARY);
assertThat(parcelTip.getIconId()).isEqualTo(ICON_ID);
}
/**
* Used to test the non abstract methods in {@link TestBatteryTip}
*/
public class TestBatteryTip extends BatteryTip {
public static class TestBatteryTip extends BatteryTip {
TestBatteryTip() {
super(TipType.SUMMARY, StateType.NEW, true);
}
TestBatteryTip(Parcel in) {
super(in);
}
@Override
public String getTitle(Context context) {
@@ -88,10 +112,15 @@ public class BatteryTipTest {
// do nothing
}
@Override
public Dialog buildDialog() {
return null;
}
public final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public BatteryTip createFromParcel(Parcel in) {
return new TestBatteryTip(in);
}
public BatteryTip[] newArray(int size) {
return new TestBatteryTip[size];
}
};
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip.tips;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.os.Parcel;
import android.text.format.DateUtils;
import com.android.settings.TestConfig;
import com.android.settings.fuelgauge.batterytip.HighUsageApp;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class HighUsageTipTest {
private static final String PACKAGE_NAME = "com.android.app";
private static final long SCREEN_TIME = 30 * DateUtils.MINUTE_IN_MILLIS;
private Context mContext;
private HighUsageTip mBatteryTip;
private List<HighUsageApp> mUsageAppList;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mUsageAppList = new ArrayList<>();
mUsageAppList.add(new HighUsageApp(PACKAGE_NAME, SCREEN_TIME));
mBatteryTip = new HighUsageTip(SCREEN_TIME, mUsageAppList);
}
@Test
public void testParcelable() {
Parcel parcel = Parcel.obtain();
mBatteryTip.writeToParcel(parcel, mBatteryTip.describeContents());
parcel.setDataPosition(0);
final HighUsageTip parcelTip = new HighUsageTip(parcel);
assertThat(parcelTip.getTitle(mContext)).isEqualTo("Phone used heavily");
assertThat(parcelTip.getType()).isEqualTo(BatteryTip.TipType.HIGH_DEVICE_USAGE);
assertThat(parcelTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
assertThat(parcelTip.getScreenTimeMs()).isEqualTo(SCREEN_TIME);
assertThat(parcelTip.mHighUsageAppList.size()).isEqualTo(1);
final HighUsageApp app = parcelTip.mHighUsageAppList.get(0);
assertThat(app.packageName).isEqualTo(PACKAGE_NAME);
assertThat(app.screenOnTimeMs).isEqualTo(SCREEN_TIME);
}
}