1e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/*
2e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Copyright (C) 2016 The Android Open Source Project
3e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
4e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Licensed under the Apache License, Version 2.0 (the "License");
5e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * you may not use this file except in compliance with the License.
6e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * You may obtain a copy of the License at
7e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
8e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *      http://www.apache.org/licenses/LICENSE-2.0
9e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
10e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Unless required by applicable law or agreed to in writing, software
11e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * distributed under the License is distributed on an "AS IS" BASIS,
12e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * See the License for the specific language governing permissions and
14e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * limitations under the License.
15e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */
16e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
17e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event.h"
18e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event_loop.h"
19b1c45b9446bd6bf2e95b0768353165e8009594f6Andrew Rossignol#include "chre/core/event_loop_manager.h"
20e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/init.h"
21e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/nanoapp.h"
22f53ddfb0683e210f9cf803d968c2d8c5d3b00a55Andrew Rossignol#include "chre/core/static_nanoapps.h"
23d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol#include "chre/platform/platform_audio.h"
24388d81b80425f66acb306c774e46d53221d36b33Andrew Rossignol#include "chre/platform/context.h"
25d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol#include "chre/platform/fatal_error.h"
26e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/platform/log.h"
272003cdc07c3ad198d58ba26524d215c9a1b3bdd9Andrew Rossignol#include "chre/platform/shared/platform_log.h"
28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/platform/system_timer.h"
29e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/time.h"
30e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
31e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include <csignal>
32b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol#include <tclap/CmdLine.h>
33cc39d7566ed61c7127020228e1439a49e07074f9Brian Duddie#include <thread>
34e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
359526b7b52ed3e6cb198c649f582877acb27f1c56Andrew Rossignolusing chre::EventLoopManagerSingleton;
36e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieusing chre::Milliseconds;
37e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
38b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol//! A description of the simulator.
39b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignolconstexpr char kSimDescription[] = "A simulation environment for the Context "
40b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol                                   "Hub Runtime Environment (CHRE)";
41b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol
42b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol//! The version of the simulator. This is not super important but is assigned by
43b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol//! rules of semantic versioning.
44b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignolconstexpr char kSimVersion[] = "0.1.0";
45b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol
46e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace {
47e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
48e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieextern "C" void signalHandler(int sig) {
49e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  (void) sig;
50e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  LOGI("Stop request received");
519526b7b52ed3e6cb198c649f582877acb27f1c56Andrew Rossignol  EventLoopManagerSingleton::get()->getEventLoop().stop();
52e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}
53e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
54e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}
55e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
56b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignolint main(int argc, char **argv) {
57b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol  try {
58fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol    // Parse command-line arguments.
59b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    TCLAP::CmdLine cmd(kSimDescription, ' ', kSimVersion);
60d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    TCLAP::SwitchArg noStaticNanoappsArg("", "no_static_nanoapps",
61fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol        "disable running static nanoapps", cmd, false);
62d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    TCLAP::MultiArg<std::string> nanoappsArg("", "nanoapp",
63d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol        "nanoapp shared object to load and execute", false, "path", cmd);
64816ef8939db90c01f550ef4392ec66ec255c65faAndrew Rossignol#ifdef CHRE_AUDIO_SUPPORT_ENABLED
65d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    TCLAP::ValueArg<std::string> audioFileArg("", "audio_file",
66d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol        "WAV file to open for audio simulation", false, "", "path", cmd);
67d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    TCLAP::ValueArg<double> minAudioBufSizeArg("", "min_audio_buf_size",
68d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol        "min buffer size for audio simulation", false, 1.0, "seconds", cmd);
69d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    TCLAP::ValueArg<double> maxAudioBufSizeArg("", "max_audio_buf_size",
70d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol        "max buffer size for audio simulation", false, 10.0, "seconds", cmd);
71816ef8939db90c01f550ef4392ec66ec255c65faAndrew Rossignol#endif  // CHRE_AUDIO_SUPPORT_ENABLED
72b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    cmd.parse(argc, argv);
73b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol
74d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    // Initialize logging.
75b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    chre::PlatformLogSingleton::init();
76d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol
77816ef8939db90c01f550ef4392ec66ec255c65faAndrew Rossignol#ifdef CHRE_AUDIO_SUPPORT_ENABLED
78d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    // Initialize audio sources.
79d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    if (!audioFileArg.getValue().empty()) {
80d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol      auto audioSource = chre::MakeUnique<chre::AudioSource>(
81d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol          audioFileArg.getValue(), minAudioBufSizeArg.getValue(),
82d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol          maxAudioBufSizeArg.getValue());
83d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol      chre::PlatformAudio::addAudioSource(audioSource);
84d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    }
85d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol
86d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    // TODO(P1-d24c82): Add another command line argument that takes a json
87d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    // configuration to support multiple sources.
88816ef8939db90c01f550ef4392ec66ec255c65faAndrew Rossignol#endif  // CHRE_AUDIO_SUPPORT_ENABLED
89d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol
90d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol    // Initialize the system.
91b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    chre::init();
92b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol
93b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    // Register a signal handler.
94b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    std::signal(SIGINT, signalHandler);
95e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
96b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    // Load any static nanoapps and start the event loop.
97b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    std::thread chreThread([&]() {
98fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol      // Load static nanoapps unless they are disabled by a command-line flag.
99d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol      if (!noStaticNanoappsArg.getValue()) {
100fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol        chre::loadStaticNanoapps();
101fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol      }
102fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol
103fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol      // Load dynamic nanoapps specified on the command-line.
104fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol      chre::DynamicVector<chre::UniquePtr<chre::Nanoapp>> dynamicNanoapps;
105d443a3b57becd166852c4c08bb279866a4ab913dAndrew Rossignol      for (const auto& nanoapp : nanoappsArg.getValue()) {
106fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol        dynamicNanoapps.push_back(chre::MakeUnique<chre::Nanoapp>());
107fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol        dynamicNanoapps.back()->loadFromFile(nanoapp);
108fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol        EventLoopManagerSingleton::get()->getEventLoop()
109fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol            .startNanoapp(dynamicNanoapps.back());
110fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol      }
111fc4d354a2ad34172f508a9017b49747b9193eaf8Andrew Rossignol
112b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol      EventLoopManagerSingleton::get()->getEventLoop().run();
113b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    });
114b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    chreThread.join();
115e969b9be8eca27ffc875167879ab0ec093b3e313Andrew Rossignol
116b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    chre::deinit();
117b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol    chre::PlatformLogSingleton::deinit();
118b70b2e230d5976533ea70dbb3077a5d28f4d8debAndrew Rossignol  } catch (TCLAP::ExitException) {}
119e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
120e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  return 0;
121e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}
122