1 /* 2 * Copyright 2022 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.bluetooth.opp; 18 19 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 21 import static android.content.pm.PackageManager.DONT_KILL_APP; 22 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyString; 25 import static org.mockito.Mockito.doAnswer; 26 import static org.mockito.Mockito.doReturn; 27 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.database.Cursor; 31 32 import org.mockito.internal.util.MockUtil; 33 34 import java.util.List; 35 import java.util.Objects; 36 37 public class BluetoothOppTestUtils { 38 39 /** 40 * A class containing the data to be return by a cursor. Intended to be use with setUpMockCursor 41 * 42 * @attr columnName is name of column to be used as a parameter in cursor.getColumnIndexOrThrow 43 * @attr mIndex should be returned from cursor.getColumnIndexOrThrow 44 * @attr mValue should be returned from cursor.getInt() or cursor.getString() or 45 * cursor.getLong() 46 */ 47 public static class CursorMockData { 48 public final String mColumnName; 49 public final int mColumnIndex; 50 public final Object mValue; 51 CursorMockData(String columnName, int index, Object value)52 public CursorMockData(String columnName, int index, Object value) { 53 mColumnName = columnName; 54 mColumnIndex = index; 55 mValue = value; 56 } 57 } 58 59 /** 60 * Set up a mock single-row Cursor that work for common use cases in the OPP package. It mocks 61 * the database column index and value of the cell in that column of the current row 62 * 63 * <pre> 64 * cursorMockDataList.add( 65 * new CursorMockData(BluetoothShare.DIRECTION, 2, BluetoothShare.DIRECTION_INBOUND 66 * ); 67 * ... 68 * setUpMockCursor(cursor, cursorMockDataList); 69 * // This will return 2 70 * int index = cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION); 71 * int direction = cursor.getInt(index); // This will return BluetoothShare.DIRECTION_INBOUND 72 * </pre> 73 * 74 * @param cursor a mock/spy cursor to be setup 75 * @param cursorMockDataList a list representing what cursor will return 76 */ setUpMockCursor(Cursor cursor, List<CursorMockData> cursorMockDataList)77 public static void setUpMockCursor(Cursor cursor, List<CursorMockData> cursorMockDataList) { 78 assert (MockUtil.isMock(cursor)); 79 80 doAnswer( 81 invocation -> { 82 String name = invocation.getArgument(0); 83 return cursorMockDataList.stream() 84 .filter( 85 mockCursorData -> 86 Objects.equals( 87 mockCursorData.mColumnName, name)) 88 .findFirst() 89 .orElse(new CursorMockData("", -1, null)) 90 .mColumnIndex; 91 }) 92 .when(cursor) 93 .getColumnIndexOrThrow(anyString()); 94 95 doAnswer( 96 invocation -> { 97 int index = invocation.getArgument(0); 98 return cursorMockDataList.stream() 99 .filter(mockCursorData -> mockCursorData.mColumnIndex == index) 100 .findFirst() 101 .orElse(new CursorMockData("", -1, -1)) 102 .mValue; 103 }) 104 .when(cursor) 105 .getInt(anyInt()); 106 107 doAnswer( 108 invocation -> { 109 int index = invocation.getArgument(0); 110 return cursorMockDataList.stream() 111 .filter(mockCursorData -> mockCursorData.mColumnIndex == index) 112 .findFirst() 113 .orElse(new CursorMockData("", -1, -1)) 114 .mValue; 115 }) 116 .when(cursor) 117 .getLong(anyInt()); 118 119 doAnswer( 120 invocation -> { 121 int index = invocation.getArgument(0); 122 return cursorMockDataList.stream() 123 .filter(mockCursorData -> mockCursorData.mColumnIndex == index) 124 .findFirst() 125 .orElse(new CursorMockData("", -1, null)) 126 .mValue; 127 }) 128 .when(cursor) 129 .getString(anyInt()); 130 131 doReturn(true).when(cursor).moveToFirst(); 132 doReturn(true).when(cursor).moveToLast(); 133 doReturn(true).when(cursor).moveToNext(); 134 doReturn(true).when(cursor).moveToPrevious(); 135 doReturn(true).when(cursor).moveToPosition(anyInt()); 136 } 137 138 /** 139 * Enable/Disable an activity for testing 140 * 141 * @param activityClass the activity class to enable/disable 142 * @param enable true to enable, false to disable 143 * @param mTargetContext target context 144 */ enableActivity(Class activityClass, boolean enable, Context mTargetContext)145 public static void enableActivity(Class activityClass, boolean enable, Context mTargetContext) { 146 int enabledState = 147 enable ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DEFAULT; 148 149 mTargetContext 150 .getPackageManager() 151 .setApplicationEnabledSetting( 152 mTargetContext.getPackageName(), enabledState, DONT_KILL_APP); 153 154 ComponentName activityName = new ComponentName(mTargetContext, activityClass); 155 mTargetContext 156 .getPackageManager() 157 .setComponentEnabledSetting(activityName, enabledState, DONT_KILL_APP); 158 } 159 } 160