• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 <cinttypes>
18 
19 #include "chre_api/chre.h"
20 #include "chre/core/event_loop.h"
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/platform/assert.h"
23 #include "chre/platform/log.h"
24 #include "chre/platform/static_nanoapp_init.h"
25 #include "chre/util/nanoapp/app_id.h"
26 #include "chre/util/time.h"
27 
28 /**
29  * @file
30  * A nanoapp exclusively for testing, which unloads the spammer nanoapp after a
31  * short delay. Must only be compiled as a static/internal nanoapp.
32  */
33 
34 namespace chre {
35 namespace {
36 
37 constexpr uint32_t kAppVersion = 99;
38 
handleUnload(uint16_t,void *)39 void handleUnload(uint16_t /* eventType */, void * /* data */) {
40   EventLoop& eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
41   uint32_t instanceId;
42 
43   LOGD("About to unload spammer nanoapp");
44   if (!eventLoop.findNanoappInstanceIdByAppId(kSpammerAppId, &instanceId)) {
45     LOGE("Couldn't unload nanoapp: not found");
46   } else if (!eventLoop.unloadNanoapp(instanceId, true)) {
47     LOGE("Failed to unload nanoapp");
48   }
49 }
50 
nanoappStart()51 bool nanoappStart() {
52   LOGI("Unload tester started as instance %" PRIu32, chreGetInstanceId());
53 
54   constexpr uint64_t kTimerDuration = Seconds(2).toRawNanoseconds();
55   uint32_t timerHandle = chreTimerSet(kTimerDuration,
56       nullptr, true /* oneShot */);
57   CHRE_ASSERT_LOG(timerHandle != CHRE_TIMER_INVALID, "Couldn't start timer!");
58 
59   bool eventSent = chreSendEvent(CHRE_EVENT_FIRST_USER_VALUE, nullptr, nullptr,
60                                  chreGetInstanceId());
61   CHRE_ASSERT_LOG(eventSent, "Couldn't send event to self!");
62 
63   struct chreNanoappInfo info;
64   bool gotInfo = chreGetNanoappInfoByInstanceId(chreGetInstanceId(), &info);
65   CHRE_ASSERT(gotInfo);
66   CHRE_ASSERT(info.appId == chreGetAppId());
67   CHRE_ASSERT(info.appId == kUnloadTesterAppId);
68   CHRE_ASSERT(info.version == kAppVersion);
69   CHRE_ASSERT(info.instanceId == chreGetInstanceId());
70 
71   chreConfigureNanoappInfoEvents(true);
72   return true;
73 }
74 
nanoappHandleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)75 void nanoappHandleEvent(uint32_t senderInstanceId,
76                         uint16_t eventType,
77                         const void *eventData) {
78   if (eventType == CHRE_EVENT_FIRST_USER_VALUE
79       && senderInstanceId == chreGetInstanceId()) {
80     struct chreNanoappInfo info;
81     if (!chreGetNanoappInfoByAppId(kSpammerAppId, &info)) {
82       LOGW("Couldn't get spammer's app info - not running?");
83     }
84   } else if (eventType == CHRE_EVENT_TIMER) {
85     // We can't do the unload from the context of another nanoapp's handle
86     // event callback, so get into the system context
87     if (!EventLoopManagerSingleton::get()->deferCallback(
88             SystemCallbackType::HandleUnloadNanoapp, nullptr, handleUnload)) {
89       LOGE("Couldn't defer callback");
90     }
91   } else if (eventType == CHRE_EVENT_NANOAPP_STARTED
92       || eventType == CHRE_EVENT_NANOAPP_STOPPED) {
93     const auto *info = static_cast<const chreNanoappInfo *>(eventData);
94     if (info->appId == kSpammerAppId) {
95       LOGD("Received %s event for spammer instance %" PRIu32,
96            (eventType == CHRE_EVENT_NANOAPP_STARTED) ? "start" : "stop",
97            info->instanceId);
98     }
99   }
100 }
101 
nanoappEnd()102 void nanoappEnd() {}
103 
104 }  // anonymous namespace
105 }  // namespace chre
106 
107 CHRE_STATIC_NANOAPP_INIT(UnloadTester, chre::kUnloadTesterAppId, kAppVersion);
108