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 MacAddress.fromString(mCachedDevice.getAddress()), 108 /* displayName */ null, 109 /* deviceProfile */ "", 110 /* associatedDevice */ null, 111 /* selfManaged */ false, 112 /* notifyOnDeviceNearby */ true, 113 /* revoked */ false, 114 /* pending */ false, 115 /* timeApprovedMs */ System.currentTimeMillis(), 116 /* lastTimeConnected */ Long.MAX_VALUE, 117 /* systemDataSyncFlags */ -1, 118 /* deviceIcon */ null, 119 /* deviceId */ null); 120 121 mAssociations.add(association); 122 showScreen(mController); 123 } 124 getPreference(int index)125 private Preference getPreference(int index) { 126 PreferenceCategory preferenceCategory = mProfiles.findPreference( 127 mController.getPreferenceKey()); 128 return Objects.requireNonNull(preferenceCategory).getPreference(index); 129 } 130 removeAssociation(String packageName)131 private void removeAssociation(String packageName) { 132 mAssociations = mAssociations.stream() 133 .filter(a -> !a.getPackageName().equals(packageName)) 134 .collect(Collectors.toList()); 135 136 when(mCompanionDeviceManager.getAllAssociations()).thenReturn(mAssociations); 137 138 showScreen(mController); 139 } 140 141 @Test addOneAssociation_preferenceShouldBeAdded()142 public void addOneAssociation_preferenceShouldBeAdded() { 143 addFakeAssociation(PACKAGE_NAME_ONE, APP_NAME_ONE); 144 145 Preference preferenceOne = getPreference(0); 146 147 assertThat(preferenceOne.getClass()).isEqualTo(CompanionAppWidgetPreference.class); 148 assertThat(preferenceOne.getKey()).isEqualTo(PACKAGE_NAME_ONE); 149 assertThat(preferenceOne.getTitle()).isEqualTo(APP_NAME_ONE.toString()); 150 assertThat(mProfiles.getPreferenceCount()).isEqualTo(1); 151 152 removeAssociation(PACKAGE_NAME_ONE); 153 154 assertThat(mProfiles.getPreferenceCount()).isEqualTo(0); 155 } 156 157 @Test removeOneAssociation_preferenceShouldBeRemoved()158 public void removeOneAssociation_preferenceShouldBeRemoved() { 159 addFakeAssociation(PACKAGE_NAME_ONE, APP_NAME_ONE); 160 161 removeAssociation(PACKAGE_NAME_ONE); 162 163 assertThat(mProfiles.getPreferenceCount()).isEqualTo(0); 164 } 165 166 @Test addMultipleAssociations_preferencesShouldBeAdded()167 public void addMultipleAssociations_preferencesShouldBeAdded() { 168 for (int i = 0; i < mPackages.size(); i++) { 169 addFakeAssociation(mPackages.get(i), mAppNames.get(i)); 170 171 Preference preference = getPreference(i); 172 173 assertThat(preference.getClass()).isEqualTo(CompanionAppWidgetPreference.class); 174 assertThat(preference.getKey()).isEqualTo(mPackages.get(i)); 175 assertThat(preference.getTitle()).isEqualTo(mAppNames.get(i).toString()); 176 assertThat(mProfiles.getPreferenceCount()).isEqualTo(i + 1); 177 } 178 } 179 180 @Test removeMultipleAssociations_preferencesShouldBeRemoved()181 public void removeMultipleAssociations_preferencesShouldBeRemoved() { 182 for (int i = 0; i < mPackages.size(); i++) { 183 addFakeAssociation(mPackages.get(i), mAppNames.get(i).toString()); 184 } 185 186 for (int i = 0; i < mPackages.size(); i++) { 187 removeAssociation(mPackages.get(i)); 188 189 assertThat(mProfiles.getPreferenceCount()).isEqualTo(mPackages.size() - i - 1); 190 191 if (i == mPackages.size() - 1) { 192 break; 193 } 194 195 assertThat(getPreference(0).getKey()).isEqualTo(mPackages.get(i + 1)); 196 assertThat(getPreference(0).getTitle()).isEqualTo(mAppNames.get(i + 1).toString()); 197 } 198 } 199 } 200