1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker *
4*84e33947SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker *
8*84e33947SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker *
10*84e33947SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker */
16*84e33947SAndroid Build Coastguard Worker
17*84e33947SAndroid Build Coastguard Worker #include <cinttypes>
18*84e33947SAndroid Build Coastguard Worker
19*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop.h"
20*84e33947SAndroid Build Coastguard Worker #include "chre/core/event_loop_manager.h"
21*84e33947SAndroid Build Coastguard Worker #include "chre/platform/assert.h"
22*84e33947SAndroid Build Coastguard Worker #include "chre/platform/log.h"
23*84e33947SAndroid Build Coastguard Worker #include "chre/platform/static_nanoapp_init.h"
24*84e33947SAndroid Build Coastguard Worker #include "chre/util/nanoapp/app_id.h"
25*84e33947SAndroid Build Coastguard Worker #include "chre/util/system/napp_permissions.h"
26*84e33947SAndroid Build Coastguard Worker #include "chre/util/time.h"
27*84e33947SAndroid Build Coastguard Worker
28*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre.h"
29*84e33947SAndroid Build Coastguard Worker /**
30*84e33947SAndroid Build Coastguard Worker * @file
31*84e33947SAndroid Build Coastguard Worker * A nanoapp exclusively for testing, which unloads the spammer nanoapp after a
32*84e33947SAndroid Build Coastguard Worker * short delay. Must only be compiled as a static/internal nanoapp, because it
33*84e33947SAndroid Build Coastguard Worker * accesses internal framework APIs to do the unload - generally, nanoapps are
34*84e33947SAndroid Build Coastguard Worker * not allowed to unload other nanoapps.
35*84e33947SAndroid Build Coastguard Worker */
36*84e33947SAndroid Build Coastguard Worker
37*84e33947SAndroid Build Coastguard Worker namespace chre {
38*84e33947SAndroid Build Coastguard Worker namespace {
39*84e33947SAndroid Build Coastguard Worker
40*84e33947SAndroid Build Coastguard Worker constexpr uint32_t kAppVersion = 99;
41*84e33947SAndroid Build Coastguard Worker
handleUnload(uint16_t,void *,void *)42*84e33947SAndroid Build Coastguard Worker void handleUnload(uint16_t /*type*/, void * /*data*/, void * /*extraData*/) {
43*84e33947SAndroid Build Coastguard Worker EventLoop &eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
44*84e33947SAndroid Build Coastguard Worker uint16_t instanceId;
45*84e33947SAndroid Build Coastguard Worker
46*84e33947SAndroid Build Coastguard Worker LOGD("About to unload spammer nanoapp");
47*84e33947SAndroid Build Coastguard Worker if (!eventLoop.findNanoappInstanceIdByAppId(kSpammerAppId, &instanceId)) {
48*84e33947SAndroid Build Coastguard Worker LOGE("Couldn't unload nanoapp: not found");
49*84e33947SAndroid Build Coastguard Worker } else if (!eventLoop.unloadNanoapp(instanceId, true)) {
50*84e33947SAndroid Build Coastguard Worker LOGE("Failed to unload nanoapp");
51*84e33947SAndroid Build Coastguard Worker }
52*84e33947SAndroid Build Coastguard Worker }
53*84e33947SAndroid Build Coastguard Worker
nanoappStart()54*84e33947SAndroid Build Coastguard Worker bool nanoappStart() {
55*84e33947SAndroid Build Coastguard Worker LOGI("Unload tester started as instance %" PRIu32, chreGetInstanceId());
56*84e33947SAndroid Build Coastguard Worker
57*84e33947SAndroid Build Coastguard Worker constexpr uint64_t kTimerDuration = Seconds(2).toRawNanoseconds();
58*84e33947SAndroid Build Coastguard Worker uint32_t timerHandle =
59*84e33947SAndroid Build Coastguard Worker chreTimerSet(kTimerDuration, nullptr, true /* oneShot */);
60*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT_LOG(timerHandle != CHRE_TIMER_INVALID, "Couldn't start timer!");
61*84e33947SAndroid Build Coastguard Worker
62*84e33947SAndroid Build Coastguard Worker bool eventSent = chreSendEvent(CHRE_EVENT_FIRST_USER_VALUE, nullptr, nullptr,
63*84e33947SAndroid Build Coastguard Worker chreGetInstanceId());
64*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT_LOG(eventSent, "Couldn't send event to self!");
65*84e33947SAndroid Build Coastguard Worker
66*84e33947SAndroid Build Coastguard Worker struct chreNanoappInfo info;
67*84e33947SAndroid Build Coastguard Worker bool gotInfo = chreGetNanoappInfoByInstanceId(chreGetInstanceId(), &info);
68*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(gotInfo);
69*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(info.appId == chreGetAppId());
70*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(info.appId == kUnloadTesterAppId);
71*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(info.version == kAppVersion);
72*84e33947SAndroid Build Coastguard Worker CHRE_ASSERT(info.instanceId == chreGetInstanceId());
73*84e33947SAndroid Build Coastguard Worker
74*84e33947SAndroid Build Coastguard Worker chreConfigureNanoappInfoEvents(true);
75*84e33947SAndroid Build Coastguard Worker return true;
76*84e33947SAndroid Build Coastguard Worker }
77*84e33947SAndroid Build Coastguard Worker
nanoappHandleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)78*84e33947SAndroid Build Coastguard Worker void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType,
79*84e33947SAndroid Build Coastguard Worker const void *eventData) {
80*84e33947SAndroid Build Coastguard Worker if (eventType == CHRE_EVENT_FIRST_USER_VALUE &&
81*84e33947SAndroid Build Coastguard Worker senderInstanceId == chreGetInstanceId()) {
82*84e33947SAndroid Build Coastguard Worker struct chreNanoappInfo info;
83*84e33947SAndroid Build Coastguard Worker if (!chreGetNanoappInfoByAppId(kSpammerAppId, &info)) {
84*84e33947SAndroid Build Coastguard Worker LOGW("Couldn't get spammer's app info - not running?");
85*84e33947SAndroid Build Coastguard Worker }
86*84e33947SAndroid Build Coastguard Worker } else if (eventType == CHRE_EVENT_TIMER) {
87*84e33947SAndroid Build Coastguard Worker // We can't do the unload from the context of another nanoapp's handle
88*84e33947SAndroid Build Coastguard Worker // event callback, so get into the system context
89*84e33947SAndroid Build Coastguard Worker EventLoopManagerSingleton::get()->deferCallback(
90*84e33947SAndroid Build Coastguard Worker SystemCallbackType::HandleUnloadNanoapp, nullptr, handleUnload);
91*84e33947SAndroid Build Coastguard Worker } else if (eventType == CHRE_EVENT_NANOAPP_STARTED ||
92*84e33947SAndroid Build Coastguard Worker eventType == CHRE_EVENT_NANOAPP_STOPPED) {
93*84e33947SAndroid Build Coastguard Worker const auto *info = static_cast<const chreNanoappInfo *>(eventData);
94*84e33947SAndroid Build Coastguard Worker if (info->appId == kSpammerAppId) {
95*84e33947SAndroid Build Coastguard Worker LOGD("Received %s event for spammer instance %" PRIu32,
96*84e33947SAndroid Build Coastguard Worker (eventType == CHRE_EVENT_NANOAPP_STARTED) ? "start" : "stop",
97*84e33947SAndroid Build Coastguard Worker info->instanceId);
98*84e33947SAndroid Build Coastguard Worker }
99*84e33947SAndroid Build Coastguard Worker }
100*84e33947SAndroid Build Coastguard Worker }
101*84e33947SAndroid Build Coastguard Worker
nanoappEnd()102*84e33947SAndroid Build Coastguard Worker void nanoappEnd() {}
103*84e33947SAndroid Build Coastguard Worker
104*84e33947SAndroid Build Coastguard Worker } // anonymous namespace
105*84e33947SAndroid Build Coastguard Worker } // namespace chre
106*84e33947SAndroid Build Coastguard Worker
107*84e33947SAndroid Build Coastguard Worker CHRE_STATIC_NANOAPP_INIT(UnloadTester, chre::kUnloadTesterAppId, kAppVersion,
108*84e33947SAndroid Build Coastguard Worker chre::NanoappPermissions::CHRE_PERMS_NONE);
109