1015a50bef99a23a8c795486b99021a5784d65d64Doris Ling/*
2015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * Copyright (C) 2017 The Android Open Source Project
3015a50bef99a23a8c795486b99021a5784d65d64Doris Ling *
4015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * Licensed under the Apache License, Version 2.0 (the "License");
5015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * you may not use this file except in compliance with the License.
6015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * You may obtain a copy of the License at
7015a50bef99a23a8c795486b99021a5784d65d64Doris Ling *
8015a50bef99a23a8c795486b99021a5784d65d64Doris Ling *      http://www.apache.org/licenses/LICENSE-2.0
9015a50bef99a23a8c795486b99021a5784d65d64Doris Ling *
10015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * Unless required by applicable law or agreed to in writing, software
11015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * distributed under the License is distributed on an "AS IS" BASIS,
12015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * See the License for the specific language governing permissions and
14015a50bef99a23a8c795486b99021a5784d65d64Doris Ling * limitations under the License.
15015a50bef99a23a8c795486b99021a5784d65d64Doris Ling */
16015a50bef99a23a8c795486b99021a5784d65d64Doris Ling
17015a50bef99a23a8c795486b99021a5784d65d64Doris Lingpackage com.android.settings.applications;
18015a50bef99a23a8c795486b99021a5784d65d64Doris Ling
195c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evansimport android.app.AlertDialog;
20ee01dcc74a357e67477246e39603b88183f17cc8jackqdyuleiimport android.app.LoaderManager;
212508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport android.app.admin.DevicePolicyManager;
22ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishiimport android.content.Context;
2393be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Lingimport android.content.Intent;
24015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport android.content.pm.ApplicationInfo;
252508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport android.content.pm.PackageInfo;
26edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evansimport android.content.pm.PackageManager;
2777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport android.content.res.Resources;
28cdbc114376499c22bc43c078d58cf3331dd40adejackqdyuleiimport android.os.BatteryStats;
29ee01dcc74a357e67477246e39603b88183f17cc8jackqdyuleiimport android.os.Bundle;
302508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport android.os.UserManager;
3109955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport android.support.v7.preference.Preference;
32edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evansimport android.support.v7.preference.PreferenceManager;
33edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evansimport android.support.v7.preference.PreferenceScreen;
3409955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport android.view.View;
3509955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport android.widget.Button;
36015a50bef99a23a8c795486b99021a5784d65d64Doris Ling
37cdbc114376499c22bc43c078d58cf3331dd40adejackqdyuleiimport com.android.internal.os.BatterySipper;
38cdbc114376499c22bc43c078d58cf3331dd40adejackqdyuleiimport com.android.internal.os.BatteryStatsHelper;
3958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyuleiimport com.android.settings.R;
40cdbc114376499c22bc43c078d58cf3331dd40adejackqdyuleiimport com.android.settings.SettingsActivity;
41015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport com.android.settings.SettingsRobolectricTestRunner;
42015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport com.android.settings.TestConfig;
4309955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport com.android.settings.applications.instantapps.InstantAppButtonsController;
4458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyuleiimport com.android.settings.fuelgauge.BatteryUtils;
4509955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport com.android.settings.testutils.FakeFeatureFactory;
4677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport com.android.settingslib.Utils;
4709955c38659ec6e0420f90b89292585ededf6d44Antony Sargentimport com.android.settingslib.applications.AppUtils;
482508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport com.android.settingslib.applications.ApplicationsState.AppEntry;
49ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishiimport com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
50edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evansimport com.android.settingslib.applications.instantapps.InstantAppDataProvider;
51015a50bef99a23a8c795486b99021a5784d65d64Doris Ling
522508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport org.junit.Before;
53015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport org.junit.Test;
54015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport org.junit.runner.RunWith;
552508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport org.mockito.Answers;
562508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport org.mockito.Mock;
572508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport org.mockito.MockitoAnnotations;
58ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishiimport org.robolectric.RuntimeEnvironment;
59015a50bef99a23a8c795486b99021a5784d65d64Doris Lingimport org.robolectric.annotation.Config;
6077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport org.robolectric.annotation.Implementation;
6177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport org.robolectric.annotation.Implements;
622508ed56ca1ae3c8a775507090b31f57b61c188aDoris Lingimport org.robolectric.util.ReflectionHelpers;
63015a50bef99a23a8c795486b99021a5784d65d64Doris Ling
64013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyuleiimport java.util.ArrayList;
6577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport java.util.HashSet;
66013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyuleiimport java.util.List;
67013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei
6877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static com.google.common.truth.Truth.assertThat;
6977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Matchers.any;
7077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Matchers.anyDouble;
7177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Matchers.anyInt;
7277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Matchers.anyString;
7377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.doReturn;
7477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.mock;
7577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.never;
7677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.spy;
7777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.times;
7877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.verify;
7977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhangimport static org.mockito.Mockito.when;
8077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
811f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang
82015a50bef99a23a8c795486b99021a5784d65d64Doris Ling@RunWith(SettingsRobolectricTestRunner.class)
83015a50bef99a23a8c795486b99021a5784d65d64Doris Ling@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
84015a50bef99a23a8c795486b99021a5784d65d64Doris Lingpublic final class InstalledAppDetailsTest {
85f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
86f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    private static final String PACKAGE_NAME = "test_package_name";
87013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    private static final int TARGET_UID = 111;
88013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    private static final int OTHER_UID = 222;
8958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    private static final double BATTERY_LEVEL = 60;
9058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    private static final String BATTERY_LEVEL_STRING = "60%";
91f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
9209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
9309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    private Context mContext;
942508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
952508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    private UserManager mUserManager;
965d2918a6756cdb9890ffbddf0991426486d86213jackqdyulei    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
97cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    private SettingsActivity mActivity;
981f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    @Mock
992508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    private DevicePolicyManager mDevicePolicyManager;
100cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    @Mock
101cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    private BatterySipper mBatterySipper;
102cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    @Mock
103013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    private BatterySipper mOtherBatterySipper;
10458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
105cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    private BatteryStatsHelper mBatteryStatsHelper;
106cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    @Mock
107cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    private BatteryStats.Uid mUid;
108f4c1cef322f2c747b606ba0d78563bbb0e887c51jackqdyulei    @Mock
109f4c1cef322f2c747b606ba0d78563bbb0e887c51jackqdyulei    private PackageManager mPackageManager;
11058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Mock
11158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    private BatteryUtils mBatteryUtils;
112ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    @Mock
113ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    private LoaderManager mLoaderManager;
1142508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
115ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    private FakeFeatureFactory mFeatureFactory;
1161f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    private InstalledAppDetails mAppDetail;
117cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    private Context mShadowContext;
11858406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    private Preference mBatteryPreference;
1191f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang
12077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
1212508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    @Before
1222508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    public void setUp() {
1232508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        MockitoAnnotations.initMocks(this);
12477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        FakeFeatureFactory.setupForTest(mContext);
12577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
126f4c1cef322f2c747b606ba0d78563bbb0e887c51jackqdyulei        mShadowContext = RuntimeEnvironment.application;
127cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mAppDetail = spy(new InstalledAppDetails());
12858406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mBatteryUtils = mBatteryUtils;
12958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
13058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mBatteryPreference = new Preference(mShadowContext);
13158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mBatteryPreference = mBatteryPreference;
132cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei
133cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
134cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mBatterySipper.uidObj = mUid;
135013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        doReturn(TARGET_UID).when(mBatterySipper).getUid();
136013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        doReturn(OTHER_UID).when(mOtherBatterySipper).getUid();
137cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        doReturn(mActivity).when(mAppDetail).getActivity();
138cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        doReturn(mShadowContext).when(mAppDetail).getContext();
139f4c1cef322f2c747b606ba0d78563bbb0e887c51jackqdyulei        doReturn(mPackageManager).when(mActivity).getPackageManager();
14009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
14109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        // Default to not considering any apps to be instant (individual tests can override this).
14209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
14309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                (InstantAppDataProvider) (i -> false));
1442508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    }
1452508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
146015a50bef99a23a8c795486b99021a5784d65d64Doris Ling    @Test
1472508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() {
1482508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false);
1492508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        when(mUserManager.getUsers().size()).thenReturn(2);
1502508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
1512508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
1522508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final ApplicationInfo info = new ApplicationInfo();
1532508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        info.enabled = true;
1542508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final AppEntry appEntry = mock(AppEntry.class);
1552508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        appEntry.info = info;
1562508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final PackageInfo packageInfo = mock(PackageInfo.class);
1572508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
1582508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
1592508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isTrue();
1602508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    }
1612508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
1622508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    @Test
1632508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    public void shouldShowUninstallForAll_installForSelfOnly_shouldReturnFalse() {
1642508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false);
1652508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        when(mUserManager.getUsers().size()).thenReturn(2);
1662508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
1672508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
1682508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final ApplicationInfo info = new ApplicationInfo();
1692508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        info.flags = ApplicationInfo.FLAG_INSTALLED;
1702508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        info.enabled = true;
1712508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final AppEntry appEntry = mock(AppEntry.class);
1722508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        appEntry.info = info;
1732508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        final PackageInfo packageInfo = mock(PackageInfo.class);
1742508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
1752508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
1762508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
1772508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling    }
1782508ed56ca1ae3c8a775507090b31f57b61c188aDoris Ling
179ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    @Test
180ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    public void getStorageSummary_shouldWorkForExternal() {
181ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        Context context = RuntimeEnvironment.application.getApplicationContext();
182ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        AppStorageStats stats = mock(AppStorageStats.class);
183ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        when(stats.getTotalBytes()).thenReturn(1L);
184ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi
185ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        assertThat(InstalledAppDetails.getStorageSummary(context, stats, true))
18645c42b2c70887925fbbdeafcabc9e85ed112962dDaniel Nishi                .isEqualTo("1.00B used in external storage");
187ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    }
188ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi
189ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    @Test
190ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    public void getStorageSummary_shouldWorkForInternal() {
191ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        Context context = RuntimeEnvironment.application.getApplicationContext();
192ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        AppStorageStats stats = mock(AppStorageStats.class);
193ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        when(stats.getTotalBytes()).thenReturn(1L);
194ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi
195ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi        assertThat(InstalledAppDetails.getStorageSummary(context, stats, false))
19645c42b2c70887925fbbdeafcabc9e85ed112962dDaniel Nishi                .isEqualTo("1.00B used in internal storage");
1971f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    }
1981f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang
1991f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    @Test
2001f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    public void launchFragment_hasNoPackageInfo_shouldFinish() {
2011f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", null);
2021f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang
2031f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isFalse();
2041f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        verify(mActivity).finishAndRemoveTask();
2051f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    }
2061f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang
2071f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    @Test
2081f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang    public void launchFragment_hasPackageInfo_shouldReturnTrue() {
2091f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        final PackageInfo packageInfo = mock(PackageInfo.class);
2101f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
211ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi
2121f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isTrue();
2131f81d10dc5119f5a6c57ceada1161c4a9f528f19Fan Zhang        verify(mActivity, never()).finishAndRemoveTask();
214ad7aa871e78d36bbd267f3dff47ccc3d1caa6031Daniel Nishi    }
21509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
216cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    @Test
217f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    public void packageSizeChange_isOtherPackage_shouldNotRefreshUi() {
218f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
219f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        mAppDetail.onPackageSizeChanged("Not_" + PACKAGE_NAME);
220f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
221f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        verify(mAppDetail, never()).refreshUi();
222f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    }
223f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
224f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    @Test
225f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    public void packageSizeChange_isOwnPackage_shouldRefreshUi() {
226f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        doReturn(Boolean.TRUE).when(mAppDetail).refreshUi();
227f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
228f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
229f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        mAppDetail.onPackageSizeChanged(PACKAGE_NAME);
230f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
231f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang        verify(mAppDetail).refreshUi();
232f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    }
233f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang
234f6126e7a00defc36fefc659af6c99dd67b69bcc8Fan Zhang    @Test
235cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    public void launchPowerUsageDetailFragment_shouldNotCrash() {
236cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mAppDetail.mBatteryPreference = mBatteryPreference;
237cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mAppDetail.mSipper = mBatterySipper;
238cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
239cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei
240cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        // Should not crash
241cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei        mAppDetail.onPreferenceClick(mBatteryPreference);
242cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei    }
243cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei
24409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // Tests that we don't show the "uninstall for all users" button for instant apps.
24509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    @Test
24609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    public void instantApps_noUninstallForAllButton() {
24709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        // Make this app appear to be instant.
24809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
24909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                (InstantAppDataProvider) (i -> true));
25009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false);
25109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        when(mUserManager.getUsers().size()).thenReturn(2);
25209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
25309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final ApplicationInfo info = new ApplicationInfo();
25409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        info.enabled = true;
25509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final AppEntry appEntry = mock(AppEntry.class);
25609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        appEntry.info = info;
25709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final PackageInfo packageInfo = mock(PackageInfo.class);
25809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
25909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
26009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
26109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
26209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
26309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
26409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    }
26509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
26609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // Tests that we don't show the uninstall button for instant apps"
26709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    @Test
26809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    public void instantApps_noUninstallButton() {
26909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        // Make this app appear to be instant.
27009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
271cdbc114376499c22bc43c078d58cf3331dd40adejackqdyulei                (InstantAppDataProvider) (i -> true));
27209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final ApplicationInfo info = new ApplicationInfo();
27309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        info.flags = ApplicationInfo.FLAG_INSTALLED;
27409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        info.enabled = true;
27509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final AppEntry appEntry = mock(AppEntry.class);
27609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        appEntry.info = info;
27709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final PackageInfo packageInfo = mock(PackageInfo.class);
27809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        packageInfo.applicationInfo = info;
27909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final Button uninstallButton = mock(Button.class);
28009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
28109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
28209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
28309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
28409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mUninstallButton", uninstallButton);
28509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
28609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        mAppDetail.initUnintsallButtonForUserApp();
28709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        verify(uninstallButton).setVisibility(View.GONE);
28809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    }
28909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
29009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // Tests that we don't show the force stop button for instant apps (they aren't allowed to run
29109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // when they aren't in the foreground).
29209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    @Test
29309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    public void instantApps_noForceStop() {
29409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        // Make this app appear to be instant.
29509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
29609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                (InstantAppDataProvider) (i -> true));
29709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final PackageInfo packageInfo = mock(PackageInfo.class);
29809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final AppEntry appEntry = mock(AppEntry.class);
29909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final ApplicationInfo info = new ApplicationInfo();
30009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        appEntry.info = info;
30109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final Button forceStopButton = mock(Button.class);
30209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
30309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
30409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
30509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
30609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(mAppDetail, "mForceStopButton", forceStopButton);
30709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
30809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        mAppDetail.checkForceStop();
30909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        verify(forceStopButton).setVisibility(View.GONE);
31009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    }
31109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
3125c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans    @Test
3135c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans    public void instantApps_buttonControllerHandlesDialog() {
3145c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        InstantAppButtonsController mockController = mock(InstantAppButtonsController.class);
3155c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        ReflectionHelpers.setField(
3165c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans                mAppDetail, "mInstantAppButtonsController", mockController);
3175c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        // Make sure first that button controller is not called for supported dialog id
3185c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        AlertDialog mockDialog = mock(AlertDialog.class);
3195c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        when(mockController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
3205c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans                .thenReturn(mockDialog);
3215c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        assertThat(mAppDetail.createDialog(InstantAppButtonsController.DLG_CLEAR_APP, 0))
3225c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans                .isEqualTo(mockDialog);
3235c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans        verify(mockController).createDialog(InstantAppButtonsController.DLG_CLEAR_APP);
3245c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans    }
3255c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans
32609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // A helper class for testing the InstantAppButtonsController - it lets us look up the
32709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // preference associated with a key for instant app buttons and get back a mock
32809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    // LayoutPreference (to avoid a null pointer exception).
32909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    public static class InstalledAppDetailsWithMockInstantButtons extends InstalledAppDetails {
33009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        @Mock
33109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        private LayoutPreference mInstantButtons;
33209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
33309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        public InstalledAppDetailsWithMockInstantButtons() {
33409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent            super();
33509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent            MockitoAnnotations.initMocks(this);
33609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        }
33709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
33809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        @Override
33909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        public Preference findPreference(CharSequence key) {
34009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent            if (key == "instant_app_buttons") {
34109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                return mInstantButtons;
34209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent            }
34309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent            return super.findPreference(key);
34409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        }
34509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    }
34609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
34709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    @Test
34809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    public void instantApps_instantSpecificButtons() {
34909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        // Make this app appear to be instant.
35009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
35109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                (InstantAppDataProvider) (i -> true));
35209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final PackageInfo packageInfo = mock(PackageInfo.class);
35309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
35409955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final InstalledAppDetailsWithMockInstantButtons
35509955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                fragment = new InstalledAppDetailsWithMockInstantButtons();
35609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        ReflectionHelpers.setField(fragment, "mPackageInfo", packageInfo);
35777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(fragment, "mApplicationFeatureProvider",
35877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                mFeatureFactory.applicationFeatureProvider);
35909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
36009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        final InstantAppButtonsController buttonsController =
36109955c38659ec6e0420f90b89292585ededf6d44Antony Sargent                mock(InstantAppButtonsController.class);
36209955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        when(buttonsController.setPackageName(anyString())).thenReturn(buttonsController);
36309955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
36477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        when(mFeatureFactory.applicationFeatureProvider.newInstantAppButtonsController(
3655c9f7a88b48854ab5837e8a371690999235d2c7cJesse Evans                any(), any(), any())).thenReturn(buttonsController);
36609955c38659ec6e0420f90b89292585ededf6d44Antony Sargent
36709955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        fragment.maybeAddInstantAppButtons();
36809955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        verify(buttonsController).setPackageName(anyString());
36909955c38659ec6e0420f90b89292585ededf6d44Antony Sargent        verify(buttonsController).show();
37009955c38659ec6e0420f90b89292585ededf6d44Antony Sargent    }
371edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans
372edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans    @Test
373edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans    public void instantApps_removeCorrectPref() {
374edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        PreferenceScreen mockPreferenceScreen = mock(PreferenceScreen.class);
375edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        PreferenceManager mockPreferenceManager = mock(PreferenceManager.class);
376edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        AppDomainsPreference mockAppDomainsPref = mock(AppDomainsPreference.class);
377edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        Preference mockLaunchPreference = mock(Preference.class);
378edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        PackageInfo mockPackageInfo = mock(PackageInfo.class);
379edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        PackageManager mockPackageManager = mock(PackageManager.class);
380edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setField(
381edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                mAppDetail, "mLaunchPreference", mockLaunchPreference);
382edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setField(
383edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                mAppDetail, "mInstantAppDomainsPreference", mockAppDomainsPref);
384edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setField(
385edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                mAppDetail, "mPreferenceManager", mockPreferenceManager);
386edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setField(
387edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                mAppDetail, "mPackageInfo", mockPackageInfo);
388edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setField(
389edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                mAppDetail, "mPm", mockPackageManager);
390edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        when(mockPreferenceManager.getPreferenceScreen()).thenReturn(mockPreferenceScreen);
391edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans
392edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
393edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                (InstantAppDataProvider) (i -> false));
394edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        mAppDetail.prepareInstantAppPrefs();
395edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans
396edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        // For the non instant case we remove the app domain pref, and leave the launch pref
397edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        verify(mockPreferenceScreen).removePreference(mockAppDomainsPref);
398edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        verify(mockPreferenceScreen, never()).removePreference(mockLaunchPreference);
399edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans
400edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        // For the instant app case we remove the launch preff, and leave the app domain pref
401edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
402edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                (InstantAppDataProvider) (i -> true));
403edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans
404edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        mAppDetail.prepareInstantAppPrefs();
405edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        verify(mockPreferenceScreen).removePreference(mockLaunchPreference);
406edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        // Will be 1 still due to above call
407edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans        verify(mockPreferenceScreen, times(1))
408edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans                .removePreference(mockAppDomainsPref);
409edc5099e8986d9beee70d18b6a1bf3cc8ebc6aaaJesse Evans    }
41093be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling
41193be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling    @Test
41293be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling    public void onActivityResult_uninstalledUpdates_shouldInvalidateOptionsMenu() {
41393be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling        doReturn(true).when(mAppDetail).refreshUi();
41493be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling
41593be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling        mAppDetail.onActivityResult(InstalledAppDetails.REQUEST_UNINSTALL, 0, mock(Intent.class));
41693be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling
41793be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling        verify(mActivity).invalidateOptionsMenu();
41893be46ce5e1ccc1855d580b5077c1cf0f6b4225fDoris Ling    }
419013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei
420013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    @Test
421013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    public void findTargetSipper_findCorrectSipper() {
422013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        List<BatterySipper> usageList = new ArrayList<>();
423013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        usageList.add(mBatterySipper);
424013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        usageList.add(mOtherBatterySipper);
425013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        doReturn(usageList).when(mBatteryStatsHelper).getUsageList();
426013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei
427013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei        assertThat(mAppDetail.findTargetSipper(mBatteryStatsHelper, TARGET_UID)).isEqualTo(
428013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei                mBatterySipper);
429013d3f634274b7a7f920acc7d9c90925fd352d9bjackqdyulei    }
43058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
43158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Test
43258406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    public void updateBattery_noBatteryStats_summaryNo() {
43358406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        doReturn(mShadowContext.getString(R.string.no_battery_summary)).when(mAppDetail).getString(
43458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei                R.string.no_battery_summary);
43558406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.updateBattery();
43658406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
43758406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        assertThat(mBatteryPreference.getSummary()).isEqualTo(
43858406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei                "No battery use since last full charge");
43958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    }
44058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
44158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Test
44258406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    public void updateBattery_hasBatteryStats_summaryPercent() {
44358406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
44458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mSipper = mBatterySipper;
44558406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
44658406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei                anyDouble(), anyDouble(), anyInt());
44758406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        doReturn(mShadowContext.getString(R.string.battery_summary, BATTERY_LEVEL_STRING)).when(
44858406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei                mAppDetail).getString(R.string.battery_summary, BATTERY_LEVEL_STRING);
44958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
45058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
45158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.updateBattery();
45258406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
45358406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
45458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    }
45558406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
45658406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Test
45758406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
45858406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
45958406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        mAppDetail.mSipper = mBatterySipper;
46058406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
46158406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        assertThat(mAppDetail.isBatteryStatsAvailable()).isTrue();
46258406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    }
46358406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei
46458406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    @Test
46558406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    public void isBatteryStatsAvailable_parametersNull_returnFalse() {
46658406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei        assertThat(mAppDetail.isBatteryStatsAvailable()).isFalse();
46758406203e2f5f3bd8a5b6c3a49aad402057e8455jackqdyulei    }
46877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
46977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Test
47077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
47177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final ApplicationInfo info = new ApplicationInfo();
47277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.packageName = "pkg";
47377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.enabled = true;
47477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final AppEntry appEntry = mock(AppEntry.class);
47577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        appEntry.info = info;
47677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final HashSet<String> homePackages = new HashSet<>();
47777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        homePackages.add(info.packageName);
47877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
47977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mHomePackages", homePackages);
48077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
48177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final Button button = mock(Button.class);
48277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
48377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        assertThat(mAppDetail.handleDisableable(button)).isFalse();
48477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        verify(button).setText(R.string.disable_text);
48577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    }
48677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
48777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Test
48877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Config(shadows = ShadowUtils.class)
48977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    public void handleDisableable_appIsEnabled_buttonShouldWork() {
49077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final ApplicationInfo info = new ApplicationInfo();
49177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.packageName = "pkg";
49277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.enabled = true;
49377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
49477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
49577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final AppEntry appEntry = mock(AppEntry.class);
49677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        appEntry.info = info;
49777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
49877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                new HashSet<>());
49977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
50077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
50177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                mFeatureFactory.applicationFeatureProvider);
50277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
50377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final Button button = mock(Button.class);
50477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
50577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        assertThat(mAppDetail.handleDisableable(button)).isTrue();
50677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        verify(button).setText(R.string.disable_text);
50777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    }
50877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
50977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Test
51077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Config(shadows = ShadowUtils.class)
51177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    public void handleDisableable_appIsEnabledAndInKeepEnabledWhitelist_buttonShouldNotWork() {
51277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final ApplicationInfo info = new ApplicationInfo();
51377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.packageName = "pkg";
51477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.enabled = true;
51577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
51677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
51777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final AppEntry appEntry = mock(AppEntry.class);
51877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        appEntry.info = info;
51977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
52077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final HashSet<String> packages = new HashSet<>();
52177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        packages.add(info.packageName);
52277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
52377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                packages);
52477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
52577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
52677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                mFeatureFactory.applicationFeatureProvider);
52777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
52877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
52977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        final Button button = mock(Button.class);
53077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
53177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        assertThat(mAppDetail.handleDisableable(button)).isFalse();
53277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        verify(button).setText(R.string.disable_text);
53377ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    }
53477ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang
535ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    @Test
536ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    public void testRestartBatteryStatsLoader() {
537ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei        doReturn(mLoaderManager).when(mAppDetail).getLoaderManager();
538ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei
539ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei        mAppDetail.restartBatteryStatsLoader();
540ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei
541ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei        verify(mLoaderManager).restartLoader(InstalledAppDetails.LOADER_BATTERY, Bundle.EMPTY,
542ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei                mAppDetail.mBatteryCallbacks);
543ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei    }
544ee01dcc74a357e67477246e39603b88183f17cc8jackqdyulei
54577ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    @Implements(Utils.class)
54677ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    public static class ShadowUtils {
54777ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        @Implementation
54877ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        public static boolean isSystemPackage(Resources resources, PackageManager pm,
54977ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang                PackageInfo pkg) {
55077ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang            return false;
55177ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang        }
55277ee0b08ddb8a348a051f19a349f371bf517905dFan Zhang    }
553015a50bef99a23a8c795486b99021a5784d65d64Doris Ling}
554