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', [
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
) {
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');
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
34 * A stash client registration.
37 * @alias module:stash_client~Registration
39 function Registration(id
, type
, callback
) {
48 * The type of the objects to be stashed.
55 * The callback to invoke to obtain the objects to stash.
56 * @type {module:stash_client.StashCallback}
59 this.callback_
= callback
;
63 * Serializes and returns this client's stashable objects.
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
) {
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({
80 data
: new Uint8Array(encoded
.buffer
.arrayBuffer
),
81 stashed_handles
: encoded
.handles
,
82 monitor_handles
: stashed
.monitorHandles
,
85 }, this)).catch(function(e
) { return []; });
89 * The registered stash clients.
90 * @type {!Array<!Registration>}
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
)
112 $Array
.forEach(result
.stash
, function(stashed
) {
113 if (!stashById
[stashed
.id
])
114 stashById
[stashed
.id
] = [];
115 stashById
[stashed
.id
].push(stashed
);
119 // If the stash is not available, act as if the stash was empty.
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
];
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
);
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
);
166 registerClient
: registerClient
,