1 /* 2 * Copyright (C) 2018 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 */ 16 17 package com.android.settings.fuelgauge; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.doAnswer; 22 import static org.mockito.Mockito.doReturn; 23 import static org.mockito.Mockito.spy; 24 import static org.robolectric.Shadows.shadowOf; 25 26 import android.app.AlertDialog; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.ApplicationInfo; 30 import android.content.pm.PackageManager; 31 import android.os.Bundle; 32 import android.os.UserHandle; 33 import android.support.v7.preference.CheckBoxPreference; 34 import android.support.v7.preference.Preference; 35 import android.support.v7.preference.PreferenceCategory; 36 import android.support.v7.preference.PreferenceManager; 37 import android.util.IconDrawableFactory; 38 import android.widget.CheckBox; 39 40 import com.android.settings.SettingsActivity; 41 import com.android.settings.core.InstrumentedPreferenceFragment; 42 import com.android.settings.fuelgauge.batterytip.AppInfo; 43 import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment; 44 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; 45 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip; 46 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip; 47 import com.android.settings.testutils.SettingsRobolectricTestRunner; 48 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 import org.mockito.Answers; 53 import org.mockito.ArgumentCaptor; 54 import org.mockito.Mock; 55 import org.mockito.MockitoAnnotations; 56 import org.robolectric.RuntimeEnvironment; 57 import org.robolectric.shadows.ShadowAlertDialog; 58 import org.robolectric.shadows.ShadowDialog; 59 import org.robolectric.util.FragmentTestUtil; 60 61 import java.util.ArrayList; 62 import java.util.List; 63 64 @RunWith(SettingsRobolectricTestRunner.class) 65 public class RestrictedAppDetailsTest { 66 67 private static final String PACKAGE_NAME = "com.android.app"; 68 private static final int USER_ID = 10; 69 private static final int UID = UserHandle.getUid(USER_ID, 234); 70 private static final String APP_NAME = "app"; 71 72 73 @Mock 74 private PackageManager mPackageManager; 75 @Mock 76 private ApplicationInfo mApplicationInfo; 77 @Mock 78 private IconDrawableFactory mIconDrawableFactory; 79 @Mock 80 private InstrumentedPreferenceFragment mFragment; 81 private PreferenceManager mPreferenceManager; 82 private RestrictedAppDetails mRestrictedAppDetails; 83 private Context mContext; 84 private AppInfo mAppInfo; 85 private Intent mIntent; 86 private CheckBoxPreference mCheckBoxPreference; 87 88 @Before setUp()89 public void setUp() { 90 MockitoAnnotations.initMocks(this); 91 92 mContext = spy(RuntimeEnvironment.application); 93 mRestrictedAppDetails = spy(new RestrictedAppDetails()); 94 mAppInfo = new AppInfo.Builder() 95 .setPackageName(PACKAGE_NAME) 96 .setUid(UID) 97 .build(); 98 99 mPreferenceManager = new PreferenceManager(mContext); 100 101 doReturn(mPreferenceManager).when(mRestrictedAppDetails).getPreferenceManager(); 102 doReturn(mContext).when(mFragment).getContext(); 103 mRestrictedAppDetails.mPackageManager = mPackageManager; 104 mRestrictedAppDetails.mIconDrawableFactory = mIconDrawableFactory; 105 mRestrictedAppDetails.mAppInfos = new ArrayList<>(); 106 mRestrictedAppDetails.mAppInfos.add(mAppInfo); 107 mRestrictedAppDetails.mRestrictedAppListGroup = spy(new PreferenceCategory(mContext)); 108 mRestrictedAppDetails.mBatteryUtils = spy(new BatteryUtils(mContext)); 109 doReturn(mPreferenceManager).when( 110 mRestrictedAppDetails.mRestrictedAppListGroup).getPreferenceManager(); 111 112 mCheckBoxPreference = new CheckBoxPreference(mContext); 113 mCheckBoxPreference.setKey(mRestrictedAppDetails.getKeyFromAppInfo(mAppInfo)); 114 } 115 116 @Test refreshUi_displayPreference()117 public void refreshUi_displayPreference() throws Exception { 118 doReturn(mApplicationInfo).when(mPackageManager) 119 .getApplicationInfoAsUser(PACKAGE_NAME, 0, USER_ID); 120 doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(mApplicationInfo); 121 doReturn(true).when(mRestrictedAppDetails.mBatteryUtils).isForceAppStandbyEnabled(UID, 122 PACKAGE_NAME); 123 124 mRestrictedAppDetails.refreshUi(); 125 126 assertThat(mRestrictedAppDetails.mRestrictedAppListGroup.getPreferenceCount()).isEqualTo(1); 127 final CheckBoxPreference preference = 128 (CheckBoxPreference) mRestrictedAppDetails.mRestrictedAppListGroup.getPreference(0); 129 assertThat(preference.getTitle()).isEqualTo(APP_NAME); 130 assertThat(preference.isChecked()).isTrue(); 131 } 132 133 @Test startRestrictedAppDetails_startWithCorrectData()134 public void startRestrictedAppDetails_startWithCorrectData() { 135 final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); 136 doAnswer(invocation -> { 137 // Get the intent in which it has the app info bundle 138 mIntent = captor.getValue(); 139 return true; 140 }).when(mContext).startActivity(captor.capture()); 141 142 RestrictedAppDetails.startRestrictedAppDetails(mFragment, 143 mRestrictedAppDetails.mAppInfos); 144 145 final Bundle bundle = mIntent.getBundleExtra( 146 SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); 147 // Verify the bundle has the correct info 148 final List<AppInfo> appInfos = bundle.getParcelableArrayList( 149 RestrictedAppDetails.EXTRA_APP_INFO_LIST); 150 assertThat(appInfos).containsExactly(mAppInfo); 151 } 152 153 @Test createDialogFragment_toRestrict_createRestrictDialog()154 public void createDialogFragment_toRestrict_createRestrictDialog() { 155 final BatteryTipDialogFragment dialogFragment = mRestrictedAppDetails.createDialogFragment( 156 mAppInfo, true); 157 158 FragmentTestUtil.startFragment(dialogFragment); 159 160 final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog(); 161 ShadowAlertDialog shadowDialog = shadowOf(dialog); 162 assertThat(shadowDialog.getTitle()).isEqualTo("Restrict app?"); 163 } 164 165 @Test createDialogFragment_toUnrestrict_createUnrestrictDialog()166 public void createDialogFragment_toUnrestrict_createUnrestrictDialog() { 167 final BatteryTipDialogFragment dialogFragment = mRestrictedAppDetails.createDialogFragment( 168 mAppInfo, false); 169 170 FragmentTestUtil.startFragment(dialogFragment); 171 172 final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog(); 173 ShadowAlertDialog shadowDialog = shadowOf(dialog); 174 assertThat(shadowDialog.getTitle()).isEqualTo("Remove restriction?"); 175 } 176 177 @Test onBatteryTipHandled_restrict_setChecked()178 public void onBatteryTipHandled_restrict_setChecked() { 179 final RestrictAppTip restrictAppTip = new RestrictAppTip(BatteryTip.StateType.NEW, 180 mAppInfo); 181 mRestrictedAppDetails.mRestrictedAppListGroup.addPreference(mCheckBoxPreference); 182 183 mRestrictedAppDetails.onBatteryTipHandled(restrictAppTip); 184 185 assertThat(mCheckBoxPreference.isChecked()).isTrue(); 186 } 187 188 @Test onBatteryTipHandled_unrestrict_setUnchecked()189 public void onBatteryTipHandled_unrestrict_setUnchecked() { 190 final UnrestrictAppTip unrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, 191 mAppInfo); 192 mRestrictedAppDetails.mRestrictedAppListGroup.addPreference(mCheckBoxPreference); 193 194 mRestrictedAppDetails.onBatteryTipHandled(unrestrictAppTip); 195 196 assertThat(mCheckBoxPreference.isChecked()).isFalse(); 197 } 198 } 199