199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie/*
299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Copyright (C) 2017 The Android Open Source Project
399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie *
499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Licensed under the Apache License, Version 2.0 (the "License");
599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * you may not use this file except in compliance with the License.
699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * You may obtain a copy of the License at
799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie *
899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie *      http://www.apache.org/licenses/LICENSE-2.0
999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie *
1099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * Unless required by applicable law or agreed to in writing, software
1199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * distributed under the License is distributed on an "AS IS" BASIS,
1299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * See the License for the specific language governing permissions and
1499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * limitations under the License.
1599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */
1699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
1799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include <cinttypes>
1899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
1999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre_api/chre.h"
2099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/core/event_loop.h"
2199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/core/event_loop_manager.h"
2299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/platform/assert.h"
2399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/platform/log.h"
2499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/platform/static_nanoapp_init.h"
2599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/util/nanoapp/app_id.h"
2699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie#include "chre/util/time.h"
2799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
2899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie/**
2999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * @file
3099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * A nanoapp exclusively for testing, which unloads the spammer nanoapp after a
3199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie * short delay. Must only be compiled as a static/internal nanoapp.
3299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie */
3399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
3499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddienamespace chre {
3599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddienamespace {
3699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
3762f187d9d736346275492e916f6001576b68bb00Brian Duddieconstexpr uint32_t kAppVersion = 99;
3862f187d9d736346275492e916f6001576b68bb00Brian Duddie
3999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddievoid handleUnload(uint16_t /* eventType */, void * /* data */) {
4050d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol  EventLoop& eventLoop = EventLoopManagerSingleton::get()->getEventLoop();
4199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  uint32_t instanceId;
4299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
4399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  LOGD("About to unload spammer nanoapp");
4450d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol  if (!eventLoop.findNanoappInstanceIdByAppId(kSpammerAppId, &instanceId)) {
4599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    LOGE("Couldn't unload nanoapp: not found");
4650d7d95f1d8cae0e9c6202086b9bd432adff7bf1Andrew Rossignol  } else if (!eventLoop.unloadNanoapp(instanceId, true)) {
4799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    LOGE("Failed to unload nanoapp");
4899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  }
4999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie}
5099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
5199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddiebool nanoappStart() {
5299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  LOGI("Unload tester started as instance %" PRIu32, chreGetInstanceId());
5399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
5499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  constexpr uint64_t kTimerDuration = Seconds(2).toRawNanoseconds();
5599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  uint32_t timerHandle = chreTimerSet(kTimerDuration,
5699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie      nullptr, true /* oneShot */);
5799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  CHRE_ASSERT_LOG(timerHandle != CHRE_TIMER_INVALID, "Couldn't start timer!");
5899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
5962f187d9d736346275492e916f6001576b68bb00Brian Duddie  bool eventSent = chreSendEvent(CHRE_EVENT_FIRST_USER_VALUE, nullptr, nullptr,
6062f187d9d736346275492e916f6001576b68bb00Brian Duddie                                 chreGetInstanceId());
6162f187d9d736346275492e916f6001576b68bb00Brian Duddie  CHRE_ASSERT_LOG(eventSent, "Couldn't send event to self!");
6262f187d9d736346275492e916f6001576b68bb00Brian Duddie
6362f187d9d736346275492e916f6001576b68bb00Brian Duddie  struct chreNanoappInfo info;
6462f187d9d736346275492e916f6001576b68bb00Brian Duddie  bool gotInfo = chreGetNanoappInfoByInstanceId(chreGetInstanceId(), &info);
6562f187d9d736346275492e916f6001576b68bb00Brian Duddie  CHRE_ASSERT(gotInfo);
6662f187d9d736346275492e916f6001576b68bb00Brian Duddie  CHRE_ASSERT(info.appId == chreGetAppId());
67e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie  CHRE_ASSERT(info.appId == kUnloadTesterAppId);
6862f187d9d736346275492e916f6001576b68bb00Brian Duddie  CHRE_ASSERT(info.version == kAppVersion);
6962f187d9d736346275492e916f6001576b68bb00Brian Duddie  CHRE_ASSERT(info.instanceId == chreGetInstanceId());
7062f187d9d736346275492e916f6001576b68bb00Brian Duddie
716248f7a215a1625b71154bb723565f23fb1f26e6Andrew Rossignol  chreConfigureNanoappInfoEvents(true);
7299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  return true;
7399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie}
7499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
7599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddievoid nanoappHandleEvent(uint32_t senderInstanceId,
7699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie                        uint16_t eventType,
7799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie                        const void *eventData) {
7862f187d9d736346275492e916f6001576b68bb00Brian Duddie  if (eventType == CHRE_EVENT_FIRST_USER_VALUE
7962f187d9d736346275492e916f6001576b68bb00Brian Duddie      && senderInstanceId == chreGetInstanceId()) {
8062f187d9d736346275492e916f6001576b68bb00Brian Duddie    struct chreNanoappInfo info;
8162f187d9d736346275492e916f6001576b68bb00Brian Duddie    if (!chreGetNanoappInfoByAppId(kSpammerAppId, &info)) {
8262f187d9d736346275492e916f6001576b68bb00Brian Duddie      LOGW("Couldn't get spammer's app info - not running?");
8362f187d9d736346275492e916f6001576b68bb00Brian Duddie    }
8462f187d9d736346275492e916f6001576b68bb00Brian Duddie  } else if (eventType == CHRE_EVENT_TIMER) {
8599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    // We can't do the unload from the context of another nanoapp's handle
8699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    // event callback, so get into the system context
8799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    if (!EventLoopManagerSingleton::get()->deferCallback(
8899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie            SystemCallbackType::HandleUnloadNanoapp, nullptr, handleUnload)) {
8999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie      LOGE("Couldn't defer callback");
9099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie    }
91e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie  } else if (eventType == CHRE_EVENT_NANOAPP_STARTED
92e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie      || eventType == CHRE_EVENT_NANOAPP_STOPPED) {
93e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie    const auto *info = static_cast<const chreNanoappInfo *>(eventData);
94e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie    if (info->appId == kSpammerAppId) {
95e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie      LOGD("Received %s event for spammer instance %" PRIu32,
96e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie           (eventType == CHRE_EVENT_NANOAPP_STARTED) ? "start" : "stop",
97e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie           info->instanceId);
98e5d8b38a4814e88b04bcad8e8e9835c375e725bdBrian Duddie    }
9999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  }
10099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie}
10199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
10299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddievoid nanoappEnd() {}
10399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
10499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie}  // anonymous namespace
10599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie}  // namespace chre
10699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
10762f187d9d736346275492e916f6001576b68bb00Brian DuddieCHRE_STATIC_NANOAPP_INIT(UnloadTester, chre::kUnloadTesterAppId, kAppVersion);
108