1 /* 2 * Copyright (C) 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 android.nearby.fastpair.provider.simulator.app; 18 19 import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.ACCOUNT_KEY; 20 import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.ACKNOWLEDGE; 21 import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_ADDRESS_BLE; 22 import static android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event.Code.BLUETOOTH_ADDRESS_PUBLIC; 23 24 import android.nearby.fastpair.provider.FastPairSimulator; 25 import android.nearby.fastpair.provider.FastPairSimulator.BatteryValue; 26 import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Command; 27 import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Command.BatteryInfo; 28 import android.nearby.fastpair.provider.simulator.SimulatorStreamProtocol.Event; 29 import android.nearby.fastpair.provider.simulator.testing.InputStreamListener; 30 import android.util.Log; 31 32 import androidx.annotation.Nullable; 33 34 import com.google.protobuf.ByteString; 35 import com.google.protobuf.InvalidProtocolBufferException; 36 37 /** Listener for input stream of the remote device. */ 38 public class RemoteDeviceListener implements InputStreamListener { 39 private static final String TAG = RemoteDeviceListener.class.getSimpleName(); 40 41 private final MainActivity mMainActivity; 42 @Nullable 43 private FastPairSimulator mFastPairSimulator; 44 RemoteDeviceListener(MainActivity mainActivity)45 public RemoteDeviceListener(MainActivity mainActivity) { 46 this.mMainActivity = mainActivity; 47 } 48 49 @Override onInputData(ByteString byteString)50 public void onInputData(ByteString byteString) { 51 Command command; 52 try { 53 command = Command.parseFrom(byteString); 54 } catch (InvalidProtocolBufferException e) { 55 Log.w(TAG, String.format("%s input data is not a Command", 56 mMainActivity.mRemoteDeviceId), e); 57 return; 58 } 59 60 mMainActivity.runOnUiThread(() -> { 61 Log.d(TAG, String.format("%s new command %s", 62 mMainActivity.mRemoteDeviceId, command.getCode())); 63 switch (command.getCode()) { 64 case POLLING: 65 mMainActivity.sendEventToRemoteDevice( 66 Event.newBuilder().setCode(ACKNOWLEDGE)); 67 break; 68 case RESET: 69 mMainActivity.reset(); 70 break; 71 case SHOW_BATTERY: 72 onShowBattery(command.getBatteryInfo()); 73 break; 74 case HIDE_BATTERY: 75 onHideBattery(); 76 break; 77 case REQUEST_BLUETOOTH_ADDRESS_BLE: 78 onRequestBleAddress(); 79 break; 80 case REQUEST_BLUETOOTH_ADDRESS_PUBLIC: 81 onRequestPublicAddress(); 82 break; 83 case REQUEST_ACCOUNT_KEY: 84 ByteString accountKey = mMainActivity.getAccontKey(); 85 if (accountKey == null) { 86 break; 87 } 88 mMainActivity.sendEventToRemoteDevice( 89 Event.newBuilder().setCode(ACCOUNT_KEY) 90 .setAccountKey(accountKey)); 91 break; 92 } 93 }); 94 } 95 96 @Override onClose()97 public void onClose() { 98 Log.d(TAG, String.format("%s input stream is closed", mMainActivity.mRemoteDeviceId)); 99 } 100 setFastPairSimulator(FastPairSimulator fastPairSimulator)101 void setFastPairSimulator(FastPairSimulator fastPairSimulator) { 102 this.mFastPairSimulator = fastPairSimulator; 103 } 104 onShowBattery(@ullable BatteryInfo batteryInfo)105 private void onShowBattery(@Nullable BatteryInfo batteryInfo) { 106 if (mFastPairSimulator == null || batteryInfo == null) { 107 Log.w(TAG, "skip showing battery"); 108 return; 109 } 110 111 if (batteryInfo.getBatteryValuesCount() != 3) { 112 Log.w(TAG, String.format("skip showing battery: count is not valid %d", 113 batteryInfo.getBatteryValuesCount())); 114 return; 115 } 116 117 Log.d(TAG, String.format("Show battery %s", batteryInfo)); 118 119 if (batteryInfo.hasSuppressNotification()) { 120 mFastPairSimulator.setSuppressBatteryNotification( 121 batteryInfo.getSuppressNotification()); 122 } 123 mFastPairSimulator.setBatteryValues( 124 convertFrom(batteryInfo.getBatteryValues(0)), 125 convertFrom(batteryInfo.getBatteryValues(1)), 126 convertFrom(batteryInfo.getBatteryValues(2))); 127 mFastPairSimulator.startAdvertising(); 128 } 129 onHideBattery()130 private void onHideBattery() { 131 if (mFastPairSimulator == null) { 132 return; 133 } 134 135 mFastPairSimulator.clearBatteryValues(); 136 mFastPairSimulator.startAdvertising(); 137 } 138 onRequestBleAddress()139 private void onRequestBleAddress() { 140 if (mFastPairSimulator == null) { 141 return; 142 } 143 144 mMainActivity.sendEventToRemoteDevice( 145 Event.newBuilder() 146 .setCode(BLUETOOTH_ADDRESS_BLE) 147 .setBleAddress(mFastPairSimulator.getBleAddress())); 148 } 149 onRequestPublicAddress()150 private void onRequestPublicAddress() { 151 if (mFastPairSimulator == null) { 152 return; 153 } 154 155 mMainActivity.sendEventToRemoteDevice( 156 Event.newBuilder() 157 .setCode(BLUETOOTH_ADDRESS_PUBLIC) 158 .setPublicAddress(mFastPairSimulator.getBluetoothAddress())); 159 } 160 convertFrom(BatteryInfo.BatteryValue batteryValue)161 private static BatteryValue convertFrom(BatteryInfo.BatteryValue batteryValue) { 162 return new BatteryValue(batteryValue.getCharging(), batteryValue.getLevel()); 163 } 164 } 165