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