1 /*
2 * Copyright (C) 2016 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 #include <stdint.h>
18 #include <inttypes.h>
19 #include <chre.h>
20
21 #define APP_LABEL "CHRE App 1: "
22
23 /* chre.h does not define printf format attribute for chreLog() */
24 void chreLog(enum chreLogLevel level, const char *str, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
25
26 #define EVT_LOCAL_SETUP CHRE_EVENT_FIRST_USER_VALUE
27
28 struct MyTimer {
29 uint32_t timerId;
30 };
31
32 struct ExtMsg
33 {
34 uint8_t msg;
35 uint32_t val;
36 } __attribute__((packed));
37
38 static const uint64_t kOneSecond = UINT64_C(1000000000); // in nanoseconds
39
40 static uint32_t mMyTid;
41 static uint64_t mMyAppId;
42 static int mCnt;
43 static struct MyTimer mTimer;
44
45 // Default implementation for message free
nanoappFreeMessage(void * msg,size_t size)46 static void nanoappFreeMessage(void *msg, size_t size)
47 {
48 chreHeapFree(msg);
49 }
50
nanoappStart(void)51 bool nanoappStart(void)
52 {
53 mMyAppId = chreGetAppId();
54 mMyTid = chreGetInstanceId();
55 mCnt = 3;
56 chreSendEvent(EVT_LOCAL_SETUP, NULL, NULL, mMyTid);
57 chreLog(CHRE_LOG_INFO, APP_LABEL "init");
58 return true;
59 }
60
nanoappEnd(void)61 void nanoappEnd(void)
62 {
63 chreLog(CHRE_LOG_INFO, APP_LABEL "terminating");
64 }
65
66 class A {
67 int *p;
68 public:
A(int _x)69 A(int _x) {
70 p = new int[1];
71 if (p != nullptr)
72 *p = _x;
73 chreLog(CHRE_LOG_INFO, APP_LABEL "A::A(int): *p=%d", p != nullptr ? *p : 0);
74 }
~A()75 ~A() {
76 chreLog(CHRE_LOG_INFO, APP_LABEL "A::~A(): *p=%d", p != nullptr ? *p : 0);
77 delete p;
78 p = nullptr;
79 }
80 };
81
82 static A global_with_ctor_dtor(1); // test the behavior of global static constructors/destructors
83
nanoappHandleEvent(uint32_t srcTid,uint16_t evtType,const void * evtData)84 void nanoappHandleEvent(uint32_t srcTid, uint16_t evtType, const void* evtData)
85 {
86 static A local_static_with_ctor_dtor(2); // test the behavior of local static constructors/destructors
87
88 switch (evtType) {
89 case EVT_LOCAL_SETUP:
90 mTimer.timerId = chreTimerSet(kOneSecond, &mTimer, false);
91 chreLog(CHRE_LOG_INFO, APP_LABEL "started with tid %04" PRIX32
92 " timerid %" PRIu32
93 "\n", mMyTid, mTimer.timerId);
94 break;
95 case CHRE_EVENT_TIMER:
96 {
97 const struct MyTimer *t = (const struct MyTimer *)evtData;
98 auto extMsg = new ExtMsg;
99
100 chreLog(CHRE_LOG_INFO, APP_LABEL "received timer %" PRIu32
101 " (TIME: %" PRIu64
102 ") cnt: %d\n", t->timerId, chreGetTime(), mCnt);
103 extMsg->msg = 0x01;
104 extMsg->val = mCnt;
105 chreSendMessageToHost(extMsg, sizeof(*extMsg), 0, nanoappFreeMessage);
106 if (mCnt-- <= 0)
107 chreTimerCancel(t->timerId);
108 break;
109 }
110 case CHRE_EVENT_MESSAGE_FROM_HOST:
111 {
112 const struct chreMessageFromHostData *msg = (const struct chreMessageFromHostData *)evtData;
113 const uint8_t *data = (const uint8_t *)msg->message;
114 const size_t size = msg->messageSize;
115 chreLog(CHRE_LOG_INFO, APP_LABEL "message=%p; code=%d; size=%zu",
116 data, (data && size) ? data[0] : 0, size);
117 break;
118 }
119 }
120 }
121