• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #include <pixelstats/DropDetect.h>
17 
18 #include <chre/util/nanoapp/app_id.h>
19 #include <chre_host/host_protocol_host.h>
20 #include <chre_host/socket_client.h>
21 
22 #include <android/frameworks/stats/1.0/IStats.h>
23 #define LOG_TAG "pixelstats-vendor"
24 #include <log/log.h>
25 
26 #include <inttypes.h>
27 
28 using android::sp;
29 using android::chre::HostProtocolHost;
30 using android::chre::IChreMessageHandlers;
31 using android::chre::SocketClient;
32 using android::frameworks::stats::V1_0::IStats;
33 using android::frameworks::stats::V1_0::PhysicalDropDetected;
34 
35 // following convention of CHRE code.
36 namespace fbs = ::chre::fbs;
37 
38 namespace android {
39 namespace hardware {
40 namespace google {
41 namespace pixel {
42 
43 namespace {  // anonymous namespace for file-local definitions
44 
45 // This struct is defined in nanoapps/drop/messaging.h
46 // by the DropDetect nanoapp.
47 struct __attribute__((__packed__)) DropEventPayload {
48     float confidence;
49     float accel_magnitude_peak;
50     int32_t free_fall_duration_ns;
51 };
52 
53 // This enum is defined in nanoapps/drop/messaging.h
54 // by the DropDetect nanoapp.
55 enum DropConstants {
56     kDropEnableRequest = 1,
57     kDropEnableNotification = 2,
58     kDropDisableRequest = 3,
59     kDropDisableNotification = 4,
60     kDropEventDetection = 5,
61 };
62 
requestNanoappList(SocketClient & client)63 void requestNanoappList(SocketClient &client) {
64     flatbuffers::FlatBufferBuilder builder(64);
65     HostProtocolHost::encodeNanoappListRequest(builder);
66 
67     if (!client.sendMessage(builder.GetBufferPointer(), builder.GetSize())) {
68         ALOGE("Failed to send NanoappList request");
69     }
70 }
71 
72 }  // namespace
73 
DropDetect(const uint64_t drop_detect_app_id)74 DropDetect::DropDetect(const uint64_t drop_detect_app_id) : kDropDetectAppId(drop_detect_app_id) {}
75 
start(const uint64_t drop_detect_app_id,const char * const chre_socket)76 sp<DropDetect> DropDetect::start(const uint64_t drop_detect_app_id, const char *const chre_socket) {
77     sp<DropDetect> dropDetect = new DropDetect(drop_detect_app_id);
78     if (!dropDetect->connectInBackground(chre_socket, dropDetect)) {
79         ALOGE("Couldn't connect to CHRE socket");
80         return nullptr;
81     }
82     return dropDetect;
83 }
84 
onConnected()85 void DropDetect::onConnected() {
86     requestNanoappList(*this);
87 }
88 
89 /**
90  * Decode unix socket msgs to CHRE messages, and call the appropriate
91  * callback depending on the CHRE message.
92  */
onMessageReceived(const void * data,size_t length)93 void DropDetect::onMessageReceived(const void *data, size_t length) {
94     if (!HostProtocolHost::decodeMessageFromChre(data, length, *this)) {
95         ALOGE("Failed to decode message");
96     }
97 }
98 
99 /**
100  * Handle the response of a NanoappList request.
101  * Ensure that the Drop Detect nanoapp is running.
102  */
handleNanoappListResponse(const fbs::NanoappListResponseT & response)103 void DropDetect::handleNanoappListResponse(const fbs::NanoappListResponseT &response) {
104     for (const std::unique_ptr<fbs::NanoappListEntryT> &nanoapp : response.nanoapps) {
105         if (nanoapp->app_id == kDropDetectAppId) {
106             if (!nanoapp->enabled)
107                 ALOGE("Drop Detect app not enabled");
108             else
109                 ALOGI("Drop Detect enabled");
110             return;
111         }
112     }
113     ALOGE("Drop Detect app not found");
114 }
115 
116 /**
117  * listen for messages from the DropDetect nanoapp and report them to
118  * PixelStats.
119  */
handleNanoappMessage(const fbs::NanoappMessageT & message)120 void DropDetect::handleNanoappMessage(const fbs::NanoappMessageT &message) {
121     struct DropEventPayload *message_struct;
122 
123     if (message.app_id != kDropDetectAppId || message.message_type != kDropEventDetection ||
124         message.message.size() < sizeof(struct DropEventPayload))
125         return;
126     message_struct = (struct DropEventPayload *)&message.message[0];
127     ALOGI("Received drop detect message! Confidence %f Peak %f Duration %g",
128           message_struct->confidence, message_struct->accel_magnitude_peak,
129           message_struct->free_fall_duration_ns / 1e9);
130     uint8_t confidence = message_struct->confidence * 100;
131     confidence = std::min<int>(confidence, 100);
132     confidence = std::max<int>(0, confidence);
133 
134     int32_t accel_magnitude_peak_1000ths_g = message_struct->accel_magnitude_peak * 1000.0;
135     int32_t free_fall_duration_ms = message_struct->free_fall_duration_ns / 1000000;
136 
137     sp<IStats> stats_client = IStats::tryGetService();
138     if (stats_client) {
139         PhysicalDropDetected drop = {confidence, accel_magnitude_peak_1000ths_g,
140                                      free_fall_duration_ms};
141         Return<void> ret = stats_client->reportPhysicalDropDetected(drop);
142         if (!ret.isOk())
143             ALOGE("Unable to report physical drop to Stats service");
144     } else
145         ALOGE("Unable to connect to Stats service");
146 }
147 
148 }  // namespace pixel
149 }  // namespace google
150 }  // namespace hardware
151 }  // namespace android
152