Shaka Player Embedded
js_utils.cc
Go to the documentation of this file.
1 // Copyright 2018 Google LLC
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 // https://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 "src/mapping/js_utils.h"
16 
17 #include <memory>
18 
20 #include "src/core/task_runner.h"
21 #include "src/mapping/js_engine.h"
22 
23 namespace shaka {
24 
25 namespace {
26 
27 js::JsError MakeError(const Error& error) {
28  // Scheme plugins expect throwing shaka.util.Error instances.
29  const double severity = error.severity != 0 ? error.severity : 2; // CRITICAL
30  LocalVar<JsValue> ctor = GetDescendant(JsEngine::Instance()->global_handle(),
31  {"shaka", "util", "Error"});
33  LOG(DFATAL) << "Unable to find 'shaka.util.Error'";
34  return js::JsError::TypeError(error.message);
35  }
36  LocalVar<JsFunction> ctor_func = UnsafeJsCast<JsFunction>(ctor);
37 
38  LocalVar<JsValue> args[] = {ToJsValue(severity), ToJsValue(error.category),
39  ToJsValue(error.code)};
40  LocalVar<JsValue> results;
41  if (!InvokeConstructor(ctor_func, 3, args, &results)) {
42  LOG(DFATAL) << "Error creating shaka.util.Error: "
43  << ConvertToString(results);
44  return js::JsError::TypeError(error.message);
45  }
46 
47  return js::JsError::Rethrow(results);
48 }
49 
50 } // namespace
51 
52 ReturnVal<JsValue> GetDescendant(Handle<JsObject> root,
53  const std::vector<std::string>& names) {
54  if (names.empty())
55  return RawToJsValue(root);
56 
57  LocalVar<JsObject> cur = root;
58  for (size_t i = 0;; i++) {
59  LocalVar<JsValue> child = GetMemberRaw(cur, names[i]);
60  if (i == names.size() - 1)
61  return child;
62  if (!IsObject(child))
63  return {};
64  cur = UnsafeJsCast<JsObject>(child);
65  }
66 }
67 
68 void HandleNetworkFuture(Promise promise, std::future<optional<Error>> future,
69  std::function<void()> on_done) {
70  auto shared_future = future.share();
71  auto finish_future = [=]() {
72  Promise copy = promise; // By-value captures are const, so copy to edit.
73  auto error = shared_future.get();
74  if (error.has_value()) {
75  copy.RejectWith(MakeError(error.value()), /* raise_events= */ false);
76  } else {
77  on_done();
78  }
79  };
80 
81  auto* thread = JsManagerImpl::Instance()->MainThread();
82  if (shared_future.valid()) {
83  // Add the user-defined literal for seconds. "0s" is 0 seconds.
84  using std::operator""s;
85  if (shared_future.wait_for(0s) == std::future_status::timeout) {
86  // If the future isn't ready yet, poll it on the JS main thread until
87  // it is ready.
88  std::shared_ptr<int> id(new int);
89  auto poll = [=]() {
90  if (shared_future.wait_for(0s) == std::future_status::timeout)
91  return;
92  thread->CancelTimer(*id);
93  finish_future();
94  };
95  *id = thread->AddRepeatedTimer(250, std::move(poll));
96  } else {
97  thread->AddInternalTask(TaskPriority::Internal, "",
98  std::move(finish_future));
99  }
100  } else {
101  thread->AddInternalTask(TaskPriority::Internal, "", std::move(on_done));
102  }
103 }
104 
105 } // namespace shaka
bool IsObject(Handle< JsValue > value)
Definition: js_wrappers.cc:315
static JsError Rethrow(Handle< JsValue > error)
Definition: js_error.cc:105
ReturnVal< JsValue > GetDescendant(Handle< JsObject > root, const std::vector< std::string > &names)
Definition: js_utils.cc:52
ReturnVal< JsValue > ToJsValue(T &&source)
Definition: convert_js.h:381
void RejectWith(const js::JsError &error, bool run_events=true)
Definition: promise.cc:121
void HandleNetworkFuture(Promise promise, std::future< optional< Error >> future, std::function< void()> on_done)
Definition: js_utils.cc:68
ReturnVal< JsValue > RawToJsValue(Handle< T > source)
Definition: js_wrappers.h:405
proto::ValueType GetValueType(Handle< JsValue > value)
Definition: js_wrappers.cc:329
std::string ConvertToString(Handle< JsValue > value)
Definition: js_wrappers.cc:203
static JsError TypeError(const std::string &message)
Definition: js_error.cc:81
bool InvokeConstructor(Handle< JsFunction > ctor, int argc, LocalVar< JsValue > *argv, LocalVar< JsValue > *result_or_except)
Definition: js_wrappers.cc:165
ReturnVal< JsValue > GetMemberRaw(Handle< JsObject > object, const std::string &name, LocalVar< JsValue > *exception=nullptr)
Definition: js_wrappers.cc:136
TaskRunner * MainThread()