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