Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / file_manager / file_manager / background / js / drive_sync_handler.js
1 // Copyright 2014 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.
4
5 /**
6  * Handler of the background page for the drive sync events.
7  * @param {ProgressCenter} progressCenter Progress center to submit the
8  *     progressing items.
9  * @constructor
10  * @extends {cr.EventTarget}
11  * @suppress {checkStructDictInheritance}
12  * @struct
13  */
14 function DriveSyncHandler(progressCenter) {
15   /**
16    * Progress center to submit the progressing item.
17    * @type {ProgressCenter}
18    * @const
19    * @private
20    */
21   this.progressCenter_ = progressCenter;
22
23   /**
24    * Counter for error ID.
25    * @type {number}
26    * @private
27    */
28   this.errorIdCounter_ = 0;
29
30   /**
31    * Progress center item.
32    * @type {ProgressCenterItem}
33    * @const
34    * @private
35    */
36   this.item_ = new ProgressCenterItem();
37   this.item_.id = 'drive-sync';
38
39   /**
40    * If the property is true, this item is syncing.
41    * @type {boolean}
42    * @private
43    */
44   this.syncing_ = false;
45
46   /**
47    * Whether the sync is disabled on cellular network or not.
48    * @type {boolean}
49    * @private
50    */
51   this.cellularDisabled_ = false;
52
53   /**
54    * Async queue.
55    * @type {AsyncUtil.Queue}
56    * @const
57    * @private
58    */
59   this.queue_ = new AsyncUtil.Queue();
60
61   // Register events.
62   chrome.fileManagerPrivate.onFileTransfersUpdated.addListener(
63       this.onFileTransfersUpdated_.bind(this));
64   chrome.fileManagerPrivate.onDriveSyncError.addListener(
65       this.onDriveSyncError_.bind(this));
66   chrome.notifications.onButtonClicked.addListener(
67       this.onNotificationButtonClicked_.bind(this));
68   chrome.fileManagerPrivate.onPreferencesChanged.addListener(
69       this.onPreferencesChanged_.bind(this));
70
71   // Set initial values.
72   this.onPreferencesChanged_();
73 }
74
75 /**
76  * Completed event name.
77  * @type {string}
78  * @const
79  */
80 DriveSyncHandler.COMPLETED_EVENT = 'completed';
81
82 /**
83  * Progress ID of the drive sync error.
84  * @type {string}
85  * @const
86  */
87 DriveSyncHandler.DRIVE_SYNC_ERROR_PREFIX = 'drive-sync-error-';
88
89 /**
90  * Notification ID of the disabled mobile sync notification.
91  * @type {string}
92  * @private
93  * @const
94  */
95 DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_ = 'disabled-mobile-sync';
96
97 DriveSyncHandler.prototype = /** @struct */ {
98   __proto__: cr.EventTarget.prototype,
99
100   /**
101    * @return {boolean} Whether the handler is having syncing items or not.
102    */
103   get syncing() {
104     return this.syncing_;
105   }
106 };
107
108 /**
109  * Returns whether the drive sync is currently suppressed or not.
110  * @private
111  * @return {boolean}
112  */
113 DriveSyncHandler.prototype.isSyncSuppressed = function() {
114   return navigator.connection.type === 'cellular' &&
115       this.cellularDisabled_;
116 };
117
118 /**
119  * Shows the notification saying that the drive sync is disabled on cellular
120  * network.
121  */
122 DriveSyncHandler.prototype.showDisabledMobileSyncNotification = function() {
123   chrome.notifications.create(
124       DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_,
125       {
126         type: 'basic',
127         title: chrome.runtime.getManifest().name,
128         message: str('DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE'),
129         iconUrl: chrome.runtime.getURL('/common/images/icon96.png'),
130         buttons: [
131           {title: str('DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON')}
132         ]
133       },
134       function() {});
135 };
136
137 /**
138  * Handles file transfer updated events.
139  * @param {FileTransferStatus} status Transfer status.
140  * @private
141  */
142 DriveSyncHandler.prototype.onFileTransfersUpdated_ = function(status) {
143   switch (status.transferState) {
144     case 'added':
145     case 'in_progress':
146     case 'started':
147       this.updateItem_(status);
148       break;
149     case 'completed':
150     case 'failed':
151       if (status.num_total_jobs === 1)
152         this.removeItem_(status);
153       break;
154     default:
155       throw new Error(
156           'Invalid transfer state: ' + status.transferState + '.');
157   }
158 };
159
160 /**
161  * Updates the item involved with the given status.
162  * @param {FileTransferStatus} status Transfer status.
163  * @private
164  */
165 DriveSyncHandler.prototype.updateItem_ = function(status) {
166   this.queue_.run(function(callback) {
167     window.webkitResolveLocalFileSystemURL(status.fileUrl, function(entry) {
168       this.item_.state = ProgressItemState.PROGRESSING;
169       this.item_.type = ProgressItemType.SYNC;
170       this.item_.quiet = true;
171       this.syncing_ = true;
172       if (status.num_total_jobs > 1)
173         this.item_.message = strf('SYNC_FILE_NUMBER', status.num_total_jobs);
174       else
175         this.item_.message = strf('SYNC_FILE_NAME', entry.name);
176       this.item_.cancelCallback = this.requestCancel_.bind(this, entry);
177       this.item_.progressValue = status.processed;
178       this.item_.progressMax = status.total;
179       this.progressCenter_.updateItem(this.item_);
180       callback();
181     }.bind(this), function(error) {
182       console.warn('Resolving URL ' + status.fileUrl + ' is failed: ', error);
183       callback();
184     });
185   }.bind(this));
186 };
187
188 /**
189  * Removes the item involved with the given status.
190  * @param {FileTransferStatus} status Transfer status.
191  * @private
192  */
193 DriveSyncHandler.prototype.removeItem_ = function(status) {
194   this.queue_.run(function(callback) {
195     this.item_.state = status.transferState === 'completed' ?
196         ProgressItemState.COMPLETED : ProgressItemState.CANCELED;
197     this.progressCenter_.updateItem(this.item_);
198     this.syncing_ = false;
199     this.dispatchEvent(new Event(DriveSyncHandler.COMPLETED_EVENT));
200     callback();
201   }.bind(this));
202 };
203
204 /**
205  * Requests to cancel for the given files' drive sync.
206  * @param {Entry} entry Entry to be canceled.
207  * @private
208  */
209 DriveSyncHandler.prototype.requestCancel_ = function(entry) {
210   // Cancel all jobs.
211   chrome.fileManagerPrivate.cancelFileTransfers();
212 };
213
214 /**
215  * Handles drive's sync errors.
216  * @param {DriveSyncErrorEvent} event Drive sync error event.
217  * @private
218  */
219 DriveSyncHandler.prototype.onDriveSyncError_ = function(event) {
220   window.webkitResolveLocalFileSystemURL(event.fileUrl, function(entry) {
221     var item = new ProgressCenterItem();
222     item.id =
223         DriveSyncHandler.DRIVE_SYNC_ERROR_PREFIX + (this.errorIdCounter_++);
224     item.type = ProgressItemType.SYNC;
225     item.quiet = true;
226     item.state = ProgressItemState.ERROR;
227     switch (event.type) {
228       case 'delete_without_permission':
229         item.message =
230             strf('SYNC_DELETE_WITHOUT_PERMISSION_ERROR', entry.name);
231         break;
232       case 'service_unavailable':
233         item.message = str('SYNC_SERVICE_UNAVAILABLE_ERROR');
234         break;
235       case 'misc':
236         item.message = strf('SYNC_MISC_ERROR', entry.name);
237         break;
238     }
239     this.progressCenter_.updateItem(item);
240   }.bind(this));
241 };
242
243 /**
244  * Handles notification's button click.
245  * @param {string} notificationId Notification ID.
246  * @param {number} buttonIndex Index of the button.
247  * @private
248  */
249 DriveSyncHandler.prototype.onNotificationButtonClicked_ = function(
250     notificationId, buttonIndex) {
251   if (notificationId !== DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_)
252     return;
253   chrome.notifications.clear(
254       DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_,
255       function() {});
256   chrome.fileManagerPrivate.setPreferences({cellularDisabled: false});
257 };
258
259 /**
260  * Handles preferences change.
261  * @private
262  */
263 DriveSyncHandler.prototype.onPreferencesChanged_ = function() {
264   chrome.fileManagerPrivate.getPreferences(function(pref) {
265     this.cellularDisabled_ = pref.cellularDisabled;
266   }.bind(this));
267 };