1 /* 2 * Copyright (C) 2023 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.example.android.vdmdemo.host; 18 19 import android.companion.virtual.sensor.VirtualSensor; 20 import android.companion.virtual.sensor.VirtualSensorCallback; 21 import android.companion.virtual.sensor.VirtualSensorEvent; 22 import android.os.SystemClock; 23 import android.util.SparseArray; 24 25 import androidx.annotation.NonNull; 26 27 import com.example.android.vdmdemo.common.RemoteEventProto.RemoteEvent; 28 import com.example.android.vdmdemo.common.RemoteEventProto.RemoteSensorEvent; 29 import com.example.android.vdmdemo.common.RemoteEventProto.SensorConfiguration; 30 import com.example.android.vdmdemo.common.RemoteIo; 31 import com.google.common.primitives.Floats; 32 33 import java.time.Duration; 34 import java.util.List; 35 import java.util.concurrent.TimeUnit; 36 import java.util.function.Consumer; 37 38 final class RemoteSensorManager implements AutoCloseable { 39 40 private final RemoteIo mRemoteIo; 41 private final SparseArray<VirtualSensor> mVirtualSensors = new SparseArray<>(); // Keyed by type 42 private final Consumer<RemoteEvent> mRemoteEventConsumer = this::processRemoteEvent; 43 44 private final VirtualSensorCallback mVirtualSensorCallback = new SensorCallback(); 45 46 private class SensorCallback implements VirtualSensorCallback { 47 @Override onConfigurationChanged( VirtualSensor sensor, boolean enabled, @NonNull Duration samplingPeriod, @NonNull Duration batchReportLatency)48 public void onConfigurationChanged( 49 VirtualSensor sensor, 50 boolean enabled, 51 @NonNull Duration samplingPeriod, 52 @NonNull Duration batchReportLatency) { 53 mRemoteIo.sendMessage(RemoteEvent.newBuilder() 54 .setSensorConfiguration(SensorConfiguration.newBuilder() 55 .setSensorType(sensor.getType()) 56 .setEnabled(enabled) 57 .setSamplingPeriodUs( 58 (int) TimeUnit.MICROSECONDS.convert(samplingPeriod)) 59 .setBatchReportingLatencyUs( 60 (int) TimeUnit.MICROSECONDS.convert(batchReportLatency))) 61 .build()); 62 } 63 } 64 RemoteSensorManager(RemoteIo remoteIo)65 RemoteSensorManager(RemoteIo remoteIo) { 66 this.mRemoteIo = remoteIo; 67 remoteIo.addMessageConsumer(mRemoteEventConsumer); 68 } 69 70 @Override close()71 public void close() { 72 mVirtualSensors.clear(); 73 mRemoteIo.removeMessageConsumer(mRemoteEventConsumer); 74 } 75 getVirtualSensorCallback()76 VirtualSensorCallback getVirtualSensorCallback() { 77 return mVirtualSensorCallback; 78 } 79 setVirtualSensors(List<VirtualSensor> virtualSensorList)80 void setVirtualSensors(List<VirtualSensor> virtualSensorList) { 81 for (VirtualSensor virtualSensor : virtualSensorList) { 82 mVirtualSensors.put(virtualSensor.getType(), virtualSensor); 83 } 84 } 85 processRemoteEvent(RemoteEvent remoteEvent)86 void processRemoteEvent(RemoteEvent remoteEvent) { 87 if (remoteEvent.hasSensorEvent()) { 88 RemoteSensorEvent sensorEvent = remoteEvent.getSensorEvent(); 89 VirtualSensor sensor = mVirtualSensors.get(sensorEvent.getSensorType()); 90 if (sensor != null) { 91 sensor.sendEvent( 92 new VirtualSensorEvent.Builder(Floats.toArray(sensorEvent.getValuesList())) 93 .setTimestampNanos(SystemClock.elapsedRealtimeNanos()) 94 .build()); 95 } 96 } 97 } 98 } 99