1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <android/log.h>
16 #include <android_native_app_glue.h>
17
18 #include "amber/amber.h"
19 #include "amber/recipe.h"
20 #include "amber/result.h"
21 #include "amber_script.h"
22
23 namespace {
24
25 // TODO(jaebaek): Change this as a method rather than macro.
26 // Android log function wrappers
27 const char* kTAG = "Amber";
28 #define LOGE(...) \
29 ((void)__android_log_print(ANDROID_LOG_ERROR, kTAG, __VA_ARGS__))
30
amber_sample_main(android_app * app)31 void amber_sample_main(android_app* app) {
32 amber::android::AmberScriptLoader loader(app);
33
34 amber::Result r = loader.LoadAllScriptsFromAsset();
35 if (!r.IsSuccess()) {
36 LOGE("%s", r.Error().c_str());
37 return;
38 }
39
40 const auto& script_info = loader.GetScripts();
41
42 std::vector<std::string> failures;
43 for (const auto& info : script_info) {
44 LOGE("\ncase %s: run...", info.asset_name.c_str());
45
46 amber::Amber am;
47 amber::Recipe recipe;
48 amber::Result r = am.Parse(info.script_content, &recipe);
49 if (!r.IsSuccess()) {
50 LOGE("\ncase %s: fail\n\t%s", info.asset_name.c_str(), r.Error().c_str());
51 failures.push_back(info.asset_name);
52 continue;
53 }
54
55 amber::Options amber_options;
56 r = am.ExecuteWithShaderData(&recipe, amber_options, info.shader_map);
57 if (!r.IsSuccess()) {
58 LOGE("\ncase %s: fail\n\t%s", info.asset_name.c_str(), r.Error().c_str());
59 failures.push_back(info.asset_name);
60 continue;
61 }
62
63 LOGE("\ncase %s: pass", info.asset_name.c_str());
64 }
65
66 if (!failures.empty()) {
67 LOGE("\nSummary of Failures:");
68 for (const auto& failure : failures)
69 LOGE("%s", failure.c_str());
70 }
71 LOGE("\nsummary: %u pass, %u fail",
72 static_cast<uint32_t>(script_info.size() - failures.size()),
73 static_cast<uint32_t>(failures.size()));
74 }
75
76 // Process the next main command.
handle_cmd(android_app * app,int32_t cmd)77 void handle_cmd(android_app* app, int32_t cmd) {
78 switch (cmd) {
79 case APP_CMD_INIT_WINDOW:
80 amber_sample_main(app);
81 break;
82 case APP_CMD_TERM_WINDOW:
83 break;
84 default:
85 break;
86 }
87 }
88
89 } // namespace
90
android_main(struct android_app * app)91 void android_main(struct android_app* app) {
92 // Set the callback to process system events
93 app->onAppCmd = handle_cmd;
94
95 // Used to poll the events in the main loop
96 int events;
97 android_poll_source* source;
98
99 // Main loop
100 while (app->destroyRequested == 0) {
101 if (ALooper_pollAll(1, nullptr, &events, (void**)&source) >= 0) {
102 if (source != NULL)
103 source->process(app, source);
104 }
105 }
106 }
107