1 /* 2 * Copyright 2019 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.development.compat; 18 19 import static com.android.internal.compat.OverrideAllowedState.ALLOWED; 20 import static com.android.internal.compat.OverrideAllowedState.DISABLED_NOT_DEBUGGABLE; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyLong; 26 import static org.mockito.ArgumentMatchers.anyString; 27 import static org.mockito.Mockito.doReturn; 28 import static org.mockito.Mockito.mock; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.when; 31 32 import android.compat.Compatibility.ChangeConfig; 33 import android.content.Context; 34 import android.content.pm.ApplicationInfo; 35 import android.content.pm.PackageManager; 36 import android.content.pm.PackageManager.NameNotFoundException; 37 import android.graphics.drawable.Drawable; 38 import android.os.RemoteException; 39 40 import androidx.preference.Preference; 41 import androidx.preference.PreferenceCategory; 42 import androidx.preference.PreferenceManager; 43 import androidx.preference.PreferenceScreen; 44 import androidx.preference.SwitchPreference; 45 46 import com.android.internal.compat.CompatibilityChangeConfig; 47 import com.android.internal.compat.CompatibilityChangeInfo; 48 import com.android.internal.compat.IOverrideValidator; 49 import com.android.internal.compat.IPlatformCompat; 50 import com.android.internal.compat.OverrideAllowedState; 51 import com.android.settings.R; 52 53 import org.junit.Before; 54 import org.junit.Test; 55 import org.junit.runner.RunWith; 56 import org.mockito.Mock; 57 import org.mockito.MockitoAnnotations; 58 import org.robolectric.RobolectricTestRunner; 59 import org.robolectric.RuntimeEnvironment; 60 61 import java.util.ArrayList; 62 import java.util.Arrays; 63 import java.util.HashSet; 64 import java.util.List; 65 import java.util.Set; 66 67 @RunWith(RobolectricTestRunner.class) 68 public class PlatformCompatDashboardTest { 69 private PlatformCompatDashboard mDashboard; 70 71 @Mock 72 private IPlatformCompat mPlatformCompat; 73 private PreferenceScreen mPreferenceScreen; 74 @Mock 75 private ApplicationInfo mApplicationInfo; 76 @Mock 77 private PreferenceManager mPreferenceManager; 78 @Mock 79 private IOverrideValidator mOverrideValidator; 80 @Mock 81 private PackageManager mPackageManager; 82 83 private Context mContext; 84 private CompatibilityChangeInfo[] mChanges; 85 private static final String APP_NAME = "foo.bar.baz"; 86 87 @Before setUp()88 public void setUp() throws RemoteException, NameNotFoundException { 89 MockitoAnnotations.initMocks(this); 90 mChanges = new CompatibilityChangeInfo[5]; 91 mChanges[0] = new CompatibilityChangeInfo( 92 1L, "Default_Enabled", 0, 0, false, false, "", false); 93 mChanges[1] = new CompatibilityChangeInfo( 94 2L, "Default_Disabled", 0, 0, true, false, "", false); 95 mChanges[2] = new CompatibilityChangeInfo( 96 3L, "Enabled_Since_SDK_1_1", -1, 1, false, false, "", false); 97 mChanges[3] = new CompatibilityChangeInfo( 98 4L, "Enabled_Since_SDK_1_2", -1, 1, false, false, "", false); 99 mChanges[4] = new CompatibilityChangeInfo( 100 5L, "Enabled_Since_SDK_2", -1, 2, false, false, "", false); 101 when(mPlatformCompat.listUIChanges()).thenReturn(mChanges); 102 when(mPlatformCompat.getOverrideValidator()).thenReturn(mOverrideValidator); 103 // By default, allow any change 104 when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) 105 .thenReturn(new OverrideAllowedState(ALLOWED, -1, -1)); 106 mContext = spy(RuntimeEnvironment.application); 107 mPreferenceManager = new PreferenceManager(mContext); 108 mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext); 109 mApplicationInfo.packageName = APP_NAME; 110 mDashboard = spy(new PlatformCompatDashboard()); 111 mDashboard.mSelectedApp = APP_NAME; 112 doReturn(mApplicationInfo).when(mDashboard).getApplicationInfo(); 113 doReturn(mContext).when(mDashboard).getContext(); 114 doReturn(mPlatformCompat).when(mDashboard).getPlatformCompat(); 115 doReturn(mPreferenceScreen).when(mDashboard).getPreferenceScreen(); 116 doReturn(mPreferenceManager).when(mDashboard).getPreferenceManager(); 117 doReturn(mPackageManager).when(mContext).getPackageManager(); 118 } 119 120 @Test getHelpResource_shouldNotHaveHelpResource()121 public void getHelpResource_shouldNotHaveHelpResource() { 122 assertThat(mDashboard.getHelpResource()).isEqualTo(0); 123 } 124 125 @Test getPreferenceScreenResId_shouldBePlatformCompatSettingsResId()126 public void getPreferenceScreenResId_shouldBePlatformCompatSettingsResId() { 127 assertThat(mDashboard.getPreferenceScreenResId()) 128 .isEqualTo(R.xml.platform_compat_settings); 129 } 130 131 @Test createAppPreference_targetSdkEquals1_summaryReturnsAppNameAndTargetSdk()132 public void createAppPreference_targetSdkEquals1_summaryReturnsAppNameAndTargetSdk() { 133 mApplicationInfo.targetSdkVersion = 1; 134 Drawable icon = mock(Drawable.class); 135 when(mApplicationInfo.loadIcon(any(PackageManager.class))).thenReturn(icon); 136 137 Preference appPreference = mDashboard.createAppPreference(mApplicationInfo); 138 139 assertThat(appPreference.getSummary()).isEqualTo(mContext.getResources().getString( 140 R.string.platform_compat_selected_app_summary, APP_NAME, 1)); 141 } 142 143 @Test createPreferenceForChange_defaultEnabledChange_createCheckedEntry()144 public void createPreferenceForChange_defaultEnabledChange_createCheckedEntry() { 145 CompatibilityChangeInfo enabledChange = mChanges[0]; 146 CompatibilityChangeConfig config = new CompatibilityChangeConfig( 147 new ChangeConfig(new HashSet<Long>(Arrays.asList(enabledChange.getId())), 148 new HashSet<Long>())); 149 150 Preference enabledPreference = mDashboard.createPreferenceForChange(mContext, enabledChange, 151 config); 152 153 SwitchPreference enabledSwitchPreference = (SwitchPreference) enabledPreference; 154 155 assertThat(enabledPreference.getSummary()).isEqualTo(mChanges[0].getName()); 156 assertThat(enabledPreference instanceof SwitchPreference).isTrue(); 157 assertThat(enabledSwitchPreference.isChecked()).isTrue(); 158 assertThat(enabledSwitchPreference.isEnabled()).isTrue(); 159 } 160 161 @Test createPreferenceForChange_defaultDisabledChange_createUncheckedEntry()162 public void createPreferenceForChange_defaultDisabledChange_createUncheckedEntry() { 163 CompatibilityChangeInfo disabledChange = mChanges[1]; 164 CompatibilityChangeConfig config = new CompatibilityChangeConfig( 165 new ChangeConfig(new HashSet<Long>(), 166 new HashSet<Long>(Arrays.asList(disabledChange.getId())))); 167 168 Preference disabledPreference = mDashboard.createPreferenceForChange(mContext, 169 disabledChange, config); 170 171 assertThat(disabledPreference.getSummary()).isEqualTo(mChanges[1].getName()); 172 SwitchPreference disabledSwitchPreference = (SwitchPreference) disabledPreference; 173 assertThat(disabledSwitchPreference.isChecked()).isFalse(); 174 assertThat(disabledSwitchPreference.isEnabled()).isTrue(); 175 } 176 177 @Test createPreferenceForChange_cannotOverride_createDisabledEntry()178 public void createPreferenceForChange_cannotOverride_createDisabledEntry() 179 throws RemoteException { 180 CompatibilityChangeInfo enabledChange = mChanges[0]; 181 CompatibilityChangeConfig config = new CompatibilityChangeConfig( 182 new ChangeConfig(new HashSet<Long>(Arrays.asList(enabledChange.getId())), 183 new HashSet<Long>())); 184 when(mOverrideValidator.getOverrideAllowedState(anyLong(),anyString())) 185 .thenReturn(new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1)); 186 187 Preference preference = mDashboard.createPreferenceForChange(mContext, enabledChange, 188 config); 189 190 SwitchPreference switchPreference = (SwitchPreference) preference; 191 192 assertThat(preference.getSummary()).isEqualTo(mChanges[0].getName()); 193 assertThat(preference instanceof SwitchPreference).isTrue(); 194 assertThat(switchPreference.isChecked()).isTrue(); 195 assertThat(switchPreference.isEnabled()).isFalse(); 196 } 197 198 @Test createChangeCategoryPreference_enabledAndDisabled_hasTitleAndEntries()199 public void createChangeCategoryPreference_enabledAndDisabled_hasTitleAndEntries() { 200 Set<Long> enabledChanges = new HashSet<>(); 201 enabledChanges.add(mChanges[0].getId()); 202 enabledChanges.add(mChanges[1].getId()); 203 enabledChanges.add(mChanges[2].getId()); 204 Set<Long> disabledChanges = new HashSet<>(); 205 disabledChanges.add(mChanges[3].getId()); 206 disabledChanges.add(mChanges[4].getId()); 207 CompatibilityChangeConfig config = new CompatibilityChangeConfig( 208 new ChangeConfig(enabledChanges, disabledChanges)); 209 List<CompatibilityChangeInfo> changesToAdd = new ArrayList<>(); 210 for (int i = 0; i < mChanges.length; ++i) { 211 changesToAdd.add(new CompatibilityChangeInfo(mChanges[i].getId(), mChanges[i].getName(), 212 -1, mChanges[i].getEnableSinceTargetSdk(), mChanges[i].getDisabled(), 213 mChanges[i].getLoggingOnly(), mChanges[i].getDescription(), 214 mChanges[i].getOverridable())); 215 } 216 217 PreferenceCategory category = mDashboard.createChangeCategoryPreference(changesToAdd, 218 config, "foo"); 219 220 assertThat(category.getTitle()).isEqualTo("foo"); 221 assertThat(category.getPreferenceCount()).isEqualTo(mChanges.length); 222 for (int i = 0; i < mChanges.length; ++i) { 223 Preference childPreference = category.getPreference(i); 224 assertThat(childPreference instanceof SwitchPreference).isTrue(); 225 } 226 } 227 } 228