1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings.fuelgauge;
17
18
19import android.content.Context;
20import android.content.pm.ApplicationInfo;
21import android.content.pm.PackageManager;
22import android.content.pm.PackageManager.NameNotFoundException;
23import android.os.Handler;
24import android.os.Process;
25import android.os.UserManager;
26
27import com.android.internal.os.BatterySipper;
28import com.android.internal.os.BatterySipper.DrainType;
29import com.android.settings.TestConfig;
30
31import org.junit.Before;
32import org.junit.Rule;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35import org.mockito.Mock;
36import org.mockito.junit.MockitoRule;
37import org.mockito.junit.MockitoJUnit;
38import org.robolectric.RobolectricTestRunner;
39import org.robolectric.annotation.Config;
40
41import static com.google.common.truth.Truth.assertThat;
42import static org.mockito.Mockito.mock;
43import static org.mockito.Mockito.when;
44
45@RunWith(RobolectricTestRunner.class)
46@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
47public class BatteryEntryTest {
48
49    private static final int APP_UID = 123;
50    private static final int SYSTEM_UID = Process.SYSTEM_UID;
51    private static final String APP_DEFAULT_PACKAGE_NAME = "com.android.test";
52    private static final String APP_LABEL = "Test App Name";
53    private static final String HIGH_DRAIN_PACKAGE = "com.android.test.screen";
54    private static final String ANDROID_PACKAGE = "android";
55    private static final String[] SYSTEM_PACKAGES = {HIGH_DRAIN_PACKAGE, ANDROID_PACKAGE};
56
57    @Rule public MockitoRule mocks = MockitoJUnit.rule();
58
59    @Mock private Context mockContext;
60    @Mock private Handler mockHandler;
61    @Mock private PackageManager mockPackageManager;
62    @Mock private UserManager mockUserManager;
63
64    @Before
65    public void stubContextToReturnMockPackageManager() {
66        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
67    }
68
69    @Before
70    public void stubPackageManagerToReturnAppPackageAndName() throws NameNotFoundException {
71        when(mockPackageManager.getPackagesForUid(APP_UID)).thenReturn(
72            new String[]{APP_DEFAULT_PACKAGE_NAME});
73
74        ApplicationInfo appInfo = mock(ApplicationInfo.class);
75        when(mockPackageManager.getApplicationInfo(APP_DEFAULT_PACKAGE_NAME, 0 /* no flags */))
76            .thenReturn(appInfo);
77        when(mockPackageManager.getApplicationLabel(appInfo)).thenReturn(APP_LABEL);
78    }
79
80    private BatteryEntry createBatteryEntryForApp() {
81        return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForApp());
82    }
83
84    private BatterySipper createSipperForApp() {
85        BatterySipper sipper =
86            new BatterySipper(DrainType.APP, new FakeUid(APP_UID), 0 /* power use */);
87        sipper.packageWithHighestDrain = HIGH_DRAIN_PACKAGE;
88        return sipper;
89    }
90
91    private BatteryEntry createBatteryEntryForSystem() {
92        return new BatteryEntry(mockContext, mockHandler, mockUserManager, createSipperForSystem());
93    }
94
95    private BatterySipper createSipperForSystem() {
96        BatterySipper sipper =
97                new BatterySipper(DrainType.APP, new FakeUid(SYSTEM_UID), 0 /* power use */);
98        sipper.packageWithHighestDrain = HIGH_DRAIN_PACKAGE;
99        sipper.mPackages = SYSTEM_PACKAGES;
100        return sipper;
101    }
102
103    @Test
104    public void batteryEntryForApp_shouldSetDefaultPackageNameAndLabel() throws Exception {
105        BatteryEntry entry = createBatteryEntryForApp();
106
107        assertThat(entry.defaultPackageName).isEqualTo(APP_DEFAULT_PACKAGE_NAME);
108        assertThat(entry.getLabel()).isEqualTo(APP_LABEL);
109    }
110
111    @Test
112    public void batteryEntryForApp_shouldSetLabelAsPackageName_whenPackageCannotBeFound()
113        throws Exception {
114      when(mockPackageManager.getApplicationInfo(APP_DEFAULT_PACKAGE_NAME, 0 /* no flags */))
115          .thenThrow(new NameNotFoundException());
116
117      BatteryEntry entry = createBatteryEntryForApp();
118
119      assertThat(entry.getLabel()).isEqualTo(APP_DEFAULT_PACKAGE_NAME);
120    }
121
122    @Test
123    public void batteryEntryForApp_shouldSetHighestDrainPackage_whenPackagesCannotBeFoundForUid() {
124        when(mockPackageManager.getPackagesForUid(APP_UID)).thenReturn(null);
125
126        BatteryEntry entry = createBatteryEntryForApp();
127
128        assertThat(entry.getLabel()).isEqualTo(HIGH_DRAIN_PACKAGE);
129    }
130
131    @Test
132    public void batteryEntryForApp_shouldSetHighestDrainPackage_whenMultiplePackagesFoundForUid() {
133        when(mockPackageManager.getPackagesForUid(APP_UID)).thenReturn(
134            new String[]{APP_DEFAULT_PACKAGE_NAME, "package2", "package3"});
135
136        BatteryEntry entry = createBatteryEntryForApp();
137
138        assertThat(entry.getLabel()).isEqualTo(HIGH_DRAIN_PACKAGE);
139    }
140
141    @Test
142    public void extractPackageFromSipper_systemSipper_returnSystemPackage() {
143        BatteryEntry entry = createBatteryEntryForSystem();
144
145        assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(
146                new String[]{ANDROID_PACKAGE});
147    }
148
149    @Test
150    public void extractPackageFromSipper_normalSipper_returnDefaultPakcage() {
151        BatteryEntry entry = createBatteryEntryForApp();
152
153        assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(entry.sipper.mPackages);
154    }
155}
156