1 /* 2 * Copyright (C) 2021 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.bluetooth; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.when; 24 25 import android.companion.AssociationInfo; 26 import android.companion.CompanionDeviceManager; 27 import android.content.pm.ApplicationInfo; 28 import android.content.pm.PackageManager; 29 import android.net.MacAddress; 30 31 import androidx.preference.Preference; 32 import androidx.preference.PreferenceCategory; 33 34 import org.junit.Ignore; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 import org.mockito.Mock; 38 import org.robolectric.RobolectricTestRunner; 39 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.List; 43 import java.util.Objects; 44 import java.util.stream.Collectors; 45 46 @Ignore("b/191992001") 47 @RunWith(RobolectricTestRunner.class) 48 public class BluetoothDetailsCompanionAppsControllerTest extends 49 BluetoothDetailsControllerTestBase { 50 private static final String PACKAGE_NAME_ONE = "com.google.android.deskclock"; 51 private static final String PACKAGE_NAME_TWO = "com.google.android.calculator"; 52 private static final String PACKAGE_NAME_THREE = "com.google.android.GoogleCamera"; 53 private static final CharSequence APP_NAME_ONE = "deskclock"; 54 private static final CharSequence APP_NAME_TWO = "calculator"; 55 private static final CharSequence APP_NAME_THREE = "GoogleCamera"; 56 57 @Mock 58 private CompanionDeviceManager mCompanionDeviceManager; 59 @Mock 60 private PackageManager mPackageManager; 61 62 private BluetoothDetailsCompanionAppsController mController; 63 private PreferenceCategory mProfiles; 64 private List<String> mPackages; 65 private List<CharSequence> mAppNames; 66 private List<AssociationInfo> mAssociations; 67 68 69 @Override setUp()70 public void setUp() { 71 super.setUp(); 72 mPackages = Arrays.asList(PACKAGE_NAME_ONE, PACKAGE_NAME_TWO, PACKAGE_NAME_THREE); 73 mAppNames = Arrays.asList(APP_NAME_ONE, APP_NAME_TWO, APP_NAME_THREE); 74 mProfiles = spy(new PreferenceCategory(mContext)); 75 mAssociations = new ArrayList<>(); 76 when(mCompanionDeviceManager.getAllAssociations()).thenReturn(mAssociations); 77 when(mProfiles.getPreferenceManager()).thenReturn(mPreferenceManager); 78 setupDevice(mDeviceConfig); 79 mController = 80 new BluetoothDetailsCompanionAppsController(mContext, mFragment, mCachedDevice, 81 mLifecycle); 82 mController.mCompanionDeviceManager = mCompanionDeviceManager; 83 mController.mPackageManager = mPackageManager; 84 mController.mProfilesContainer = mProfiles; 85 mProfiles.setKey(mController.getPreferenceKey()); 86 mScreen.addPreference(mProfiles); 87 } 88 setupFakeLabelAndInfo(String packageName, CharSequence appName)89 private void setupFakeLabelAndInfo(String packageName, CharSequence appName) { 90 ApplicationInfo appInfo = mock(ApplicationInfo.class); 91 try { 92 when(mPackageManager.getApplicationInfo(packageName, 0)).thenReturn(appInfo); 93 when(mPackageManager.getApplicationLabel(appInfo)).thenReturn(appName); 94 } catch (PackageManager.NameNotFoundException e) { 95 throw new RuntimeException(e); 96 } 97 } 98 addFakeAssociation(String packageName, CharSequence appName)99 private void addFakeAssociation(String packageName, CharSequence appName) { 100 setupFakeLabelAndInfo(packageName, appName); 101 102 final int associationId = mAssociations.size() + 1; 103 final AssociationInfo association = new AssociationInfo( 104 associationId, 105 /* userId */ 0, 106 packageName, 107 /* tag */ null, 108 MacAddress.fromString(mCachedDevice.getAddress()), 109 /* displayName */ null, 110 /* deviceProfile */ "", 111 /* associatedDevice */ null, 112 /* selfManaged */ false, 113 /* notifyOnDeviceNearby */ true, 114 /* revoked */ false, 115 /* pending */ false, 116 /* timeApprovedMs */ System.currentTimeMillis(), 117 /* lastTimeConnected */ Long.MAX_VALUE, 118 /* systemDataSyncFlags */ -1); 119 120 mAssociations.add(association); 121 showScreen(mController); 122 } 123 getPreference(int index)124 private Preference getPreference(int index) { 125 PreferenceCategory preferenceCategory = mProfiles.findPreference( 126 mController.getPreferenceKey()); 127 return Objects.requireNonNull(preferenceCategory).getPreference(index); 128 } 129 removeAssociation(String packageName)130 private void removeAssociation(String packageName) { 131 mAssociations = mAssociations.stream() 132 .filter(a -> !a.getPackageName().equals(packageName)) 133 .collect(Collectors.toList()); 134 135 when(mCompanionDeviceManager.getAllAssociations()).thenReturn(mAssociations); 136 137 showScreen(mController); 138 } 139 140 @Test addOneAssociation_preferenceShouldBeAdded()141 public void addOneAssociation_preferenceShouldBeAdded() { 142 addFakeAssociation(PACKAGE_NAME_ONE, APP_NAME_ONE); 143 144 Preference preferenceOne = getPreference(0); 145 146 assertThat(preferenceOne.getClass()).isEqualTo(CompanionAppWidgetPreference.class); 147 assertThat(preferenceOne.getKey()).isEqualTo(PACKAGE_NAME_ONE); 148 assertThat(preferenceOne.getTitle()).isEqualTo(APP_NAME_ONE.toString()); 149 assertThat(mProfiles.getPreferenceCount()).isEqualTo(1); 150 151 removeAssociation(PACKAGE_NAME_ONE); 152 153 assertThat(mProfiles.getPreferenceCount()).isEqualTo(0); 154 } 155 156 @Test removeOneAssociation_preferenceShouldBeRemoved()157 public void removeOneAssociation_preferenceShouldBeRemoved() { 158 addFakeAssociation(PACKAGE_NAME_ONE, APP_NAME_ONE); 159 160 removeAssociation(PACKAGE_NAME_ONE); 161 162 assertThat(mProfiles.getPreferenceCount()).isEqualTo(0); 163 } 164 165 @Test addMultipleAssociations_preferencesShouldBeAdded()166 public void addMultipleAssociations_preferencesShouldBeAdded() { 167 for (int i = 0; i < mPackages.size(); i++) { 168 addFakeAssociation(mPackages.get(i), mAppNames.get(i)); 169 170 Preference preference = getPreference(i); 171 172 assertThat(preference.getClass()).isEqualTo(CompanionAppWidgetPreference.class); 173 assertThat(preference.getKey()).isEqualTo(mPackages.get(i)); 174 assertThat(preference.getTitle()).isEqualTo(mAppNames.get(i).toString()); 175 assertThat(mProfiles.getPreferenceCount()).isEqualTo(i + 1); 176 } 177 } 178 179 @Test removeMultipleAssociations_preferencesShouldBeRemoved()180 public void removeMultipleAssociations_preferencesShouldBeRemoved() { 181 for (int i = 0; i < mPackages.size(); i++) { 182 addFakeAssociation(mPackages.get(i), mAppNames.get(i).toString()); 183 } 184 185 for (int i = 0; i < mPackages.size(); i++) { 186 removeAssociation(mPackages.get(i)); 187 188 assertThat(mProfiles.getPreferenceCount()).isEqualTo(mPackages.size() - i - 1); 189 190 if (i == mPackages.size() - 1) { 191 break; 192 } 193 194 assertThat(getPreference(0).getKey()).isEqualTo(mPackages.get(i + 1)); 195 assertThat(getPreference(0).getTitle()).isEqualTo(mAppNames.get(i + 1).toString()); 196 } 197 } 198 } 199