Shaka Player Embedded
ShakaPlayerStorage.mm
Go to the documentation of this file.
1 // Copyright 2019 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 
16 
17 #include <unordered_map>
18 
19 #include "shaka/error_objc.h"
20 #include "shaka/storage.h"
22 #include "src/js/offline_externs.h"
24 #include "src/util/objc_utils.h"
25 
26 namespace {
27 
28 class NativeClient : public shaka::Storage::Client {
29  public:
30  NativeClient() {}
31 
32  id<ShakaPlayerStorageClient> client() const {
33  return _client;
34  }
35 
36  void set_client(id<ShakaPlayerStorageClient> client) {
37  _client = client;
38  }
39 
40 
41  void OnProgress(shaka::StoredContent stored_content, double progress) override {
42  ShakaStoredContent *objc = [[ShakaStoredContent alloc] initWithCpp:stored_content];
43  shaka::util::DispatchObjcEvent(_client, @selector(onStorageProgress:withContent:), objc,
44  progress);
45  }
46 
47  private:
48  __weak id<ShakaPlayerStorageClient> _client;
49 };
50 
51 std::unordered_map<std::string, std::string> ToUnorderedMap(
52  NSDictionary<NSString *, NSString *> *dict) {
53  std::unordered_map<std::string, std::string> ret;
54  ret.reserve([dict count]);
55  for (NSString *key in dict) {
56  ret.emplace(key.UTF8String, dict[key].UTF8String);
57  }
58  return ret;
59 }
60 
61 } // namespace
62 
63 @interface ShakaPlayerStorage () {
64  NativeClient _client;
66  std::shared_ptr<shaka::JsManager> _engine;
67 }
68 
69 @end
70 
71 @implementation ShakaPlayerStorage
72 
73 - (instancetype)init {
74  return [self initWithPlayer:nil andError:nil];
75 }
76 
77 - (instancetype)initWithError:(NSError *__autoreleasing *)error {
78  return [self initWithPlayer:nil andError:error];
79 }
80 
81 - (instancetype)initWithPlayer:(ShakaPlayer *)player andError:(NSError *__autoreleasing *)error {
82  if (!(self = [super init]))
83  return nil;
84 
85  _engine = ShakaGetGlobalEngine();
86  _storage = new shaka::Storage(_engine.get(), player ? [player playerInstance] : nullptr);
87 
88  auto results = _storage->Initialize(&_client);
89  if (results.has_error()) {
90  if (error)
91  *error = [[ShakaPlayerError alloc] initWithError:results.error()];
92  else
93  LOG(ERROR) << "Error creating Storage instance: " << results.error();
94  return nil;
95  }
96  return self;
97 }
98 
99 - (void)dealloc {
100  delete _storage;
101 }
102 
103 - (id<ShakaPlayerStorageClient>)client {
104  return _client.client();
105 }
106 
107 - (void)setClient:(id<ShakaPlayerStorageClient>)client {
108  _client.set_client(client);
109 }
110 
111 - (BOOL)storeInProgress {
112  auto results = _storage->GetStoreInProgress();
113  if (results.has_error())
114  return NO;
115  else
116  return results.results();
117 }
118 
119 - (void)destroyWithBlock:(ShakaPlayerAsyncBlock)block {
120  auto future = _storage->Destroy();
121  shaka::util::CallBlockForFuture(self, std::move(future), block);
122 }
123 
124 - (void)listWithBlock:(void (^)(NSArray<ShakaStoredContent *> *, ShakaPlayerError *))block {
125  auto results = _storage->List();
126  shaka::util::CallBlockForFuture(self, std::move(results), block);
127 }
128 
129 - (void)remove:(NSString *)content_uri withBlock:(ShakaPlayerAsyncBlock)block {
130  auto results = _storage->Remove(content_uri.UTF8String);
131  shaka::util::CallBlockForFuture(self, std::move(results), block);
132 }
133 
134 - (void)removeEmeSessionsWithBlock:(void (^)(BOOL, ShakaPlayerError *))block {
135  auto results = _storage->RemoveEmeSessions();
136  shaka::util::CallBlockForFuture(self, std::move(results), block);
137 }
138 
139 - (void)store:(NSString *)uri withBlock:(void (^)(ShakaStoredContent *, ShakaPlayerError *))block {
140  auto results = _storage->Store(uri.UTF8String);
141  shaka::util::CallBlockForFuture(self, std::move(results), block);
142 }
143 
144 - (void)store:(NSString *)uri
145  withAppMetadata:(NSDictionary<NSString *, NSString *> *)data
146  andBlock:(void (^)(ShakaStoredContent *, ShakaPlayerError *))block {
147  auto results = _storage->Store(uri.UTF8String, ToUnorderedMap(data));
148  shaka::util::CallBlockForFuture(self, std::move(results), block);
149 }
150 
151 
152 - (void)configure:(const NSString *)namePath withBool:(BOOL)value {
153  _storage->Configure(namePath.UTF8String, static_cast<bool>(value));
154 }
155 
156 - (void)configure:(const NSString *)namePath withDouble:(double)value {
157  _storage->Configure(namePath.UTF8String, value);
158 }
159 
160 - (void)configure:(const NSString *)namePath withString:(const NSString *)value {
161  _storage->Configure(namePath.UTF8String, value.UTF8String);
162 }
163 
164 - (void)configureWithDefault:(const NSString *)namePath {
165  _storage->Configure(namePath.UTF8String, shaka::DefaultValue);
166 }
167 
168 @end
shaka::Storage * _storage
void(^ ShakaPlayerAsyncBlock)(ShakaPlayerError *_Nullable)
Definition: ShakaPlayer.h:36
std::shared_ptr< shaka::JsManager > ShakaGetGlobalEngine()
Definition: ShakaPlayer.mm:219
id< ShakaPlayerClient > client
Definition: ShakaPlayer.h:241
AsyncResults< void > Initialize(Client *client=nullptr)
Definition: storage.cc:126
void DispatchObjcEvent(__weak id weak_client, SEL selector, Args... args)
Definition: objc_utils.h:140
void CallBlockForFuture(This that, AsyncResults< Ret > future, Func block)
Definition: objc_utils.h:179
const DefaultValueType DefaultValue
std::shared_ptr< shaka::JsManager > _engine