Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / extensions / renderer / resources / stash_client.js
blob110e700ca12cd114131ff44261221f5957b782f8
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 define('stash_client', [
6 'async_waiter',
7 'content/public/renderer/service_provider',
8 'extensions/common/mojo/stash.mojom',
9 'mojo/public/js/buffer',
10 'mojo/public/js/codec',
11 'mojo/public/js/core',
12 'mojo/public/js/router',
13 ], function(asyncWaiter, serviceProvider, stashMojom, bufferModule,
14 codec, core, routerModule) {
15 /**
16 * @module stash_client
19 var service = new stashMojom.StashService.proxyClass(new routerModule.Router(
20 serviceProvider.connectToService(stashMojom.StashService.name)));
22 var unloadEvent = require('unload_event');
24 /**
25 * A callback invoked to obtain objects to stash from a particular client.
26 * @callback module:stash_client.StashCallback
27 * @return {!Promise<!Array<!Object>>|!Array<!Object>} An array of objects to
28 * stash or a promise that will resolve to an array of objects to stash.
29 * The exact type of each object should match the type passed alongside
30 * this callback.
33 /**
34 * A stash client registration.
35 * @constructor
36 * @private
37 * @alias module:stash_client~Registration
39 function Registration(id, type, callback) {
40 /**
41 * The client id.
42 * @type {string}
43 * @private
45 this.id_ = id;
47 /**
48 * The type of the objects to be stashed.
49 * @type {!Object}
50 * @private
52 this.type_ = type;
54 /**
55 * The callback to invoke to obtain the objects to stash.
56 * @type {module:stash_client.StashCallback}
57 * @private
59 this.callback_ = callback;
62 /**
63 * Serializes and returns this client's stashable objects.
64 * @return
65 * {!Promise<!Array<module:extensions/common/stash.mojom.StashedObject>>} The
66 * serialized stashed objects.
68 Registration.prototype.serialize = function() {
69 return Promise.resolve(this.callback_()).then($Function.bind(
70 function(stashedObjects) {
71 if (!stashedObjects)
72 return [];
73 return $Array.map(stashedObjects, function(stashed) {
74 var builder = new codec.MessageBuilder(
75 0, codec.align(this.type_.encodedSize));
76 builder.encodeStruct(this.type_, stashed.serialization);
77 var encoded = builder.finish();
78 return new stashMojom.StashedObject({
79 id: this.id_,
80 data: new Uint8Array(encoded.buffer.arrayBuffer),
81 stashed_handles: encoded.handles,
82 monitor_handles: stashed.monitorHandles,
83 });
84 }, this);
85 }, this)).catch(function(e) { return []; });
88 /**
89 * The registered stash clients.
90 * @type {!Array<!Registration>}
92 var clients = [];
94 /**
95 * Registers a client to provide objects to stash during shut-down.
97 * @param {string} id The id of the client. This can be passed to retrieve to
98 * retrieve the stashed objects.
99 * @param {!Object} type The type of the objects that callback will return.
100 * @param {module:stash_client.StashCallback} callback The callback that
101 * returns objects to stash.
102 * @alias module:stash_client.registerClient
104 function registerClient(id, type, callback) {
105 clients.push(new Registration(id, type, callback));
108 var retrievedStash = service.retrieveStash().then(function(result) {
109 if (!result || !result.stash)
110 return {};
111 var stashById = {};
112 $Array.forEach(result.stash, function(stashed) {
113 if (!stashById[stashed.id])
114 stashById[stashed.id] = [];
115 stashById[stashed.id].push(stashed);
117 return stashById;
118 }, function() {
119 // If the stash is not available, act as if the stash was empty.
120 return {};
124 * Retrieves the objects that were stashed with the given |id|, deserializing
125 * them into structs with type |type|.
127 * @param {string} id The id of the client. This should be unique to this
128 * client and should be passed as the id to registerClient().
129 * @param {!Object} type The mojo struct type that was serialized into the
130 * each stashed object.
131 * @return {!Promise<!Array<!Object>>} The stashed objects. The exact type of
132 * each object is that of the |type| parameter.
133 * @alias module:stash_client.retrieve
135 function retrieve(id, type) {
136 return retrievedStash.then(function(stash) {
137 var stashedObjects = stash[id];
138 if (!stashedObjects)
139 return Promise.resolve([]);
141 return Promise.all($Array.map(stashedObjects, function(stashed) {
142 var encodedData = new ArrayBuffer(stashed.data.length);
143 new Uint8Array(encodedData).set(stashed.data);
144 var reader = new codec.MessageReader(new codec.Message(
145 new bufferModule.Buffer(encodedData), stashed.stashed_handles));
146 var decoded = reader.decodeStruct(type);
147 return decoded;
148 }));
152 unloadEvent.addListener(function() {
153 Promise.all($Array.map(clients, function(client) {
154 return client.serialize();
155 })).then(function(stashedObjects) {
156 var flattenedObjectsToStash = [];
157 $Array.forEach(stashedObjects, function(stashedObjects) {
158 flattenedObjectsToStash =
159 $Array.concat(flattenedObjectsToStash, stashedObjects);
161 service.addToStash(flattenedObjectsToStash);
165 return {
166 registerClient: registerClient,
167 retrieve: retrieve,