• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2012 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'use strict';
6
7/**
8 * Responsible for showing following banners in the file list.
9 *  - WelcomeBanner
10 *  - AuthFailBanner
11 * @param {DirectoryModel} directoryModel The model.
12 * @param {VolumeManagerWrapper} volumeManager The manager.
13 * @param {DOMDocument} document HTML document.
14 * @param {boolean} showOffers True if we should show offer banners.
15 * @constructor
16 */
17function FileListBannerController(
18    directoryModel, volumeManager, document, showOffers) {
19  this.directoryModel_ = directoryModel;
20  this.volumeManager_ = volumeManager;
21  this.document_ = document;
22  this.showOffers_ = showOffers;
23  this.driveEnabled_ = false;
24
25  this.initializeWelcomeBanner_();
26  this.privateOnDirectoryChangedBound_ =
27      this.privateOnDirectoryChanged_.bind(this);
28
29  var handler = this.checkSpaceAndMaybeShowWelcomeBanner_.bind(this);
30  this.directoryModel_.addEventListener('scan-completed', handler);
31  this.directoryModel_.addEventListener('rescan-completed', handler);
32  this.directoryModel_.addEventListener('directory-changed',
33      this.onDirectoryChanged_.bind(this));
34
35  this.unmountedPanel_ = this.document_.querySelector('#unmounted-panel');
36  this.volumeManager_.volumeInfoList.addEventListener(
37      'splice', this.onVolumeInfoListSplice_.bind(this));
38  this.volumeManager_.addEventListener('drive-connection-changed',
39      this.onDriveConnectionChanged_.bind(this));
40
41  chrome.storage.onChanged.addListener(this.onStorageChange_.bind(this));
42  this.welcomeHeaderCounter_ = WELCOME_HEADER_COUNTER_LIMIT;
43  this.warningDismissedCounter_ = 0;
44  chrome.storage.local.get([WELCOME_HEADER_COUNTER_KEY, WARNING_DISMISSED_KEY],
45                         function(values) {
46    this.welcomeHeaderCounter_ =
47        parseInt(values[WELCOME_HEADER_COUNTER_KEY]) || 0;
48    this.warningDismissedCounter_ =
49        parseInt(values[WARNING_DISMISSED_KEY]) || 0;
50  }.bind(this));
51
52  this.authFailedBanner_ =
53      this.document_.querySelector('#drive-auth-failed-warning');
54  var authFailedText = this.authFailedBanner_.querySelector('.drive-text');
55  authFailedText.innerHTML = util.htmlUnescape(str('DRIVE_NOT_REACHED'));
56  authFailedText.querySelector('a').addEventListener('click', function(e) {
57    chrome.fileBrowserPrivate.logoutUserForReauthentication();
58    e.preventDefault();
59  });
60  this.maybeShowAuthFailBanner_();
61}
62
63/**
64 * FileListBannerController extends cr.EventTarget.
65 */
66FileListBannerController.prototype.__proto__ = cr.EventTarget.prototype;
67
68/**
69 * Key in localStorage to keep number of times the Drive Welcome
70 * banner has shown.
71 */
72var WELCOME_HEADER_COUNTER_KEY = 'driveWelcomeHeaderCounter';
73
74// If the warning was dismissed before, this key stores the quota value
75// (as of the moment of dismissal).
76// If the warning was never dismissed or was reset this key stores 0.
77var WARNING_DISMISSED_KEY = 'driveSpaceWarningDismissed';
78
79/**
80 * Maximum times Drive Welcome banner could have shown.
81 */
82var WELCOME_HEADER_COUNTER_LIMIT = 25;
83
84/**
85 * Initializes the banner to promote DRIVE.
86 * This method must be called before any of showing banner functions, and
87 * also before registering them as callbacks.
88 * @private
89 */
90FileListBannerController.prototype.initializeWelcomeBanner_ = function() {
91  this.usePromoWelcomeBanner_ = !util.boardIs('x86-mario') &&
92                                !util.boardIs('x86-zgb') &&
93                                !util.boardIs('x86-alex');
94};
95
96/**
97 * @param {number} value How many times the Drive Welcome header banner
98 * has shown.
99 * @private
100 */
101FileListBannerController.prototype.setWelcomeHeaderCounter_ = function(value) {
102  var values = {};
103  values[WELCOME_HEADER_COUNTER_KEY] = value;
104  chrome.storage.local.set(values);
105};
106
107/**
108 * @param {number} value How many times the low space warning has dismissed.
109 * @private
110 */
111FileListBannerController.prototype.setWarningDismissedCounter_ =
112    function(value) {
113  var values = {};
114  values[WARNING_DISMISSED_KEY] = value;
115  chrome.storage.local.set(values);
116};
117
118/**
119 * chrome.storage.onChanged event handler.
120 * @param {Object.<string, Object>} changes Changes values.
121 * @param {string} areaName "local" or "sync".
122 * @private
123 */
124FileListBannerController.prototype.onStorageChange_ = function(changes,
125                                                               areaName) {
126  if (areaName == 'local' && WELCOME_HEADER_COUNTER_KEY in changes) {
127    this.welcomeHeaderCounter_ = changes[WELCOME_HEADER_COUNTER_KEY].newValue;
128  }
129  if (areaName == 'local' && WARNING_DISMISSED_KEY in changes) {
130    this.warningDismissedCounter_ = changes[WARNING_DISMISSED_KEY].newValue;
131  }
132};
133
134/**
135 * Invoked when the drive connection status is change in the volume manager.
136 * @private
137 */
138FileListBannerController.prototype.onDriveConnectionChanged_ = function() {
139  this.maybeShowAuthFailBanner_();
140};
141
142/**
143 * @param {string} type 'none'|'page'|'header'.
144 * @param {string} messageId Resource ID of the message.
145 * @private
146 */
147FileListBannerController.prototype.prepareAndShowWelcomeBanner_ =
148    function(type, messageId) {
149  this.showWelcomeBanner_(type);
150
151  var container = this.document_.querySelector('.drive-welcome.' + type);
152  if (container.firstElementChild)
153    return;  // Do not re-create.
154
155  if (!this.document_.querySelector('link[drive-welcome-style]')) {
156    var style = this.document_.createElement('link');
157    style.rel = 'stylesheet';
158    style.href = 'foreground/css/drive_welcome.css';
159    style.setAttribute('drive-welcome-style', '');
160    this.document_.head.appendChild(style);
161  }
162
163  var wrapper = util.createChild(container, 'drive-welcome-wrapper');
164  util.createChild(wrapper, 'drive-welcome-icon');
165
166  var close = util.createChild(wrapper, 'cr-dialog-close');
167  close.addEventListener('click', this.closeWelcomeBanner_.bind(this));
168
169  var message = util.createChild(wrapper, 'drive-welcome-message');
170
171  var title = util.createChild(message, 'drive-welcome-title');
172
173  var text = util.createChild(message, 'drive-welcome-text');
174  text.innerHTML = str(messageId);
175
176  var links = util.createChild(message, 'drive-welcome-links');
177
178  var more;
179  if (this.usePromoWelcomeBanner_) {
180    var welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE');
181    if (util.boardIs('link'))
182      welcomeTitle = str('DRIVE_WELCOME_TITLE_ALTERNATIVE_1TB');
183    title.textContent = welcomeTitle;
184    more = util.createChild(links,
185        'drive-welcome-button drive-welcome-start', 'a');
186    more.textContent = str('DRIVE_WELCOME_CHECK_ELIGIBILITY');
187    more.href = str('GOOGLE_DRIVE_REDEEM_URL');
188  } else {
189    title.textContent = str('DRIVE_WELCOME_TITLE');
190    more = util.createChild(links, 'plain-link', 'a');
191    more.textContent = str('DRIVE_LEARN_MORE');
192    more.href = str('GOOGLE_DRIVE_OVERVIEW_URL');
193  }
194  more.tabIndex = '14';  // See: go/filesapp-tabindex.
195  more.target = '_blank';
196
197  var dismiss;
198  if (this.usePromoWelcomeBanner_)
199    dismiss = util.createChild(links, 'drive-welcome-button');
200  else
201    dismiss = util.createChild(links, 'plain-link');
202
203  dismiss.classList.add('drive-welcome-dismiss');
204  dismiss.textContent = str('DRIVE_WELCOME_DISMISS');
205  dismiss.addEventListener('click', this.closeWelcomeBanner_.bind(this));
206
207  this.previousDirWasOnDrive_ = false;
208};
209
210/**
211 * Show or hide the "Low Google Drive space" warning.
212 * @param {boolean} show True if the box need to be shown.
213 * @param {Object} sizeStats Size statistics. Should be defined when showing the
214 *     warning.
215 * @private
216 */
217FileListBannerController.prototype.showLowDriveSpaceWarning_ =
218      function(show, sizeStats) {
219  var box = this.document_.querySelector('#volume-space-warning');
220
221  // Avoid showing two banners.
222  // TODO(kaznacheev): Unify the low space warning and the promo header.
223  if (show)
224    this.cleanupWelcomeBanner_();
225
226  if (box.hidden == !show)
227    return;
228
229  if (this.warningDismissedCounter_) {
230    if (this.warningDismissedCounter_ ==
231            sizeStats.totalSize && // Quota had not changed
232        sizeStats.remainingSize / sizeStats.totalSize < 0.15) {
233      // Since the last dismissal decision the quota has not changed AND
234      // the user did not free up significant space. Obey the dismissal.
235      show = false;
236    } else {
237      // Forget the dismissal. Warning will be shown again.
238      this.setWarningDismissedCounter_(0);
239    }
240  }
241
242  box.textContent = '';
243  if (show) {
244    var icon = this.document_.createElement('div');
245    icon.className = 'drive-icon';
246    box.appendChild(icon);
247
248    var text = this.document_.createElement('div');
249    text.className = 'drive-text';
250    text.textContent = strf('DRIVE_SPACE_AVAILABLE_LONG',
251        util.bytesToString(sizeStats.remainingSize));
252    box.appendChild(text);
253
254    var link = this.document_.createElement('a');
255    link.className = 'plain-link';
256    link.textContent = str('DRIVE_BUY_MORE_SPACE_LINK');
257    link.href = str('GOOGLE_DRIVE_BUY_STORAGE_URL');
258    link.target = '_blank';
259    box.appendChild(link);
260
261    var close = this.document_.createElement('div');
262    close.className = 'cr-dialog-close';
263    box.appendChild(close);
264    close.addEventListener('click', function(total) {
265      var values = {};
266      values[WARNING_DISMISSED_KEY] = total;
267      chrome.storage.local.set(values);
268      box.hidden = true;
269      this.requestRelayout_(100);
270    }.bind(this, sizeStats.totalSize));
271  }
272
273  if (box.hidden != !show) {
274    box.hidden = !show;
275    this.requestRelayout_(100);
276  }
277};
278/**
279 * Closes the Drive Welcome banner.
280 * @private
281 */
282FileListBannerController.prototype.closeWelcomeBanner_ = function() {
283  this.cleanupWelcomeBanner_();
284  // Stop showing the welcome banner.
285  this.setWelcomeHeaderCounter_(WELCOME_HEADER_COUNTER_LIMIT);
286};
287
288/**
289 * Shows or hides the welcome banner for drive.
290 * @private
291 */
292FileListBannerController.prototype.checkSpaceAndMaybeShowWelcomeBanner_ =
293    function() {
294  if (!this.isOnCurrentProfileDrive()) {
295    // We are not on the drive file system. Do not show (close) the welcome
296    // banner.
297    this.cleanupWelcomeBanner_();
298    this.previousDirWasOnDrive_ = false;
299    return;
300  }
301
302  var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
303      VolumeManagerCommon.VolumeType.DRIVE);
304  if (this.welcomeHeaderCounter_ >= WELCOME_HEADER_COUNTER_LIMIT ||
305      !driveVolume || driveVolume.error) {
306    // The banner is already shown enough times or the drive FS is not mounted.
307    // So, do nothing here.
308    return;
309  }
310
311  if (!this.showOffers_) {
312    // Because it is not necessary to show the offer, set
313    // |usePromoWelcomeBanner_| false here. Note that it probably should be able
314    // to do this in the constructor, but there remains non-trivial path,
315    // which may be causes |usePromoWelcomeBanner_| == true's behavior even
316    // if |showOffers_| is false.
317    // TODO(hidehiko): Make sure if it is expected or not, and simplify
318    // |showOffers_| if possible.
319    this.usePromoWelcomeBanner_ = false;
320  }
321
322  // Perform asynchronous tasks in parallel.
323  var group = new AsyncUtil.Group();
324
325  // Choose the offer basing on the board name. The default one is 100 GB.
326  var offerSize = 100;  // In GB.
327  var offerServiceId = 'drive.cros.echo.1';
328
329  if (util.boardIs('link')) {
330    offerSize = 1024;  // 1 TB.
331    offerServiceId = 'drive.cros.echo.2';
332  }
333
334  // If the offer has been checked, then do not show the promo anymore.
335  group.add(function(onCompleted) {
336    chrome.echoPrivate.getOfferInfo(offerServiceId, function(offerInfo) {
337      // If the offer has not been checked, then an error is raised.
338      if (!chrome.runtime.lastError)
339        this.usePromoWelcomeBanner_ = false;
340      onCompleted();
341    }.bind(this));
342  }.bind(this));
343
344  if (this.usePromoWelcomeBanner_) {
345    // getSizeStats for Drive file system accesses to the server, so we should
346    // minimize the invocation.
347    group.add(function(onCompleted) {
348      // Current directory must be set, since this code is called after
349      // scanning is completed. However, the volumeInfo may be gone.
350      chrome.fileBrowserPrivate.getSizeStats(
351          driveVolume.volumeId,
352          function(result) {
353            if (result && result.totalSize >= offerSize * 1024 * 1024 * 1024)
354              this.usePromoWelcomeBanner_ = false;
355            onCompleted();
356          }.bind(this));
357    }.bind(this));
358  }
359
360  group.run(this.maybeShowWelcomeBanner_.bind(this));
361};
362
363/**
364 * Decides which banner should be shown, and show it. This method is designed
365 * to be called only from checkSpaceAndMaybeShowWelcomeBanner_.
366 * @private
367 */
368FileListBannerController.prototype.maybeShowWelcomeBanner_ = function() {
369  if (this.directoryModel_.getFileList().length == 0 &&
370      this.welcomeHeaderCounter_ == 0) {
371    // Only show the full page banner if the header banner was never shown.
372    // Do not increment the counter.
373    // The timeout below is required because sometimes another
374    // 'rescan-completed' event arrives shortly with non-empty file list.
375    setTimeout(function() {
376      if (this.isOnCurrentProfileDrive() && this.welcomeHeaderCounter_ == 0) {
377        this.prepareAndShowWelcomeBanner_('page', 'DRIVE_WELCOME_TEXT_LONG');
378      }
379    }.bind(this), 2000);
380  } else {
381    // We do not want to increment the counter when the user navigates
382    // between different directories on Drive, but we increment the counter
383    // once anyway to prevent the full page banner from showing.
384    if (!this.previousDirWasOnDrive_ || this.welcomeHeaderCounter_ == 0) {
385      this.setWelcomeHeaderCounter_(this.welcomeHeaderCounter_ + 1);
386      this.prepareAndShowWelcomeBanner_('header', 'DRIVE_WELCOME_TEXT_SHORT');
387    }
388  }
389  this.previousDirWasOnDrive_ = true;
390};
391
392/**
393 * @return {boolean} True if current directory is on Drive root of current
394 * profile.
395 */
396FileListBannerController.prototype.isOnCurrentProfileDrive = function() {
397  var entry = this.directoryModel_.getCurrentDirEntry();
398  if (!entry || util.isFakeEntry(entry))
399    return false;
400  var locationInfo = this.volumeManager_.getLocationInfo(entry);
401  return locationInfo &&
402      locationInfo.rootType === VolumeManagerCommon.RootType.DRIVE &&
403      locationInfo.volumeInfo.profile.isCurrentProfile;
404};
405
406/**
407 * Shows the Drive Welcome banner.
408 * @param {string} type 'page'|'head'|'none'.
409 * @private
410 */
411FileListBannerController.prototype.showWelcomeBanner_ = function(type) {
412  var container = this.document_.querySelector('.dialog-container');
413  if (container.getAttribute('drive-welcome') != type) {
414    container.setAttribute('drive-welcome', type);
415    this.requestRelayout_(200);  // Resize only after the animation is done.
416  }
417};
418
419/**
420 * Update the UI when the current directory changes.
421 *
422 * @param {Event} event The directory-changed event.
423 * @private
424 */
425FileListBannerController.prototype.onDirectoryChanged_ = function(event) {
426  var rootVolume = this.volumeManager_.getVolumeInfo(event.newDirEntry);
427  var previousRootVolume = event.previousDirEntry ?
428      this.volumeManager_.getVolumeInfo(event.previousDirEntry) : null;
429
430  // Show (or hide) the low space warning.
431  this.maybeShowLowSpaceWarning_(rootVolume);
432
433  // Add or remove listener to show low space warning, if necessary.
434  var isLowSpaceWarningTarget = this.isLowSpaceWarningTarget_(rootVolume);
435  if (isLowSpaceWarningTarget !==
436      this.isLowSpaceWarningTarget_(previousRootVolume)) {
437    if (isLowSpaceWarningTarget) {
438      chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
439          this.privateOnDirectoryChangedBound_);
440    } else {
441      chrome.fileBrowserPrivate.onDirectoryChanged.removeListener(
442          this.privateOnDirectoryChangedBound_);
443    }
444  }
445
446  if (!this.isOnCurrentProfileDrive()) {
447    this.cleanupWelcomeBanner_();
448    this.authFailedBanner_.hidden = true;
449  }
450
451  this.updateDriveUnmountedPanel_();
452  if (this.isOnCurrentProfileDrive()) {
453    this.unmountedPanel_.classList.remove('retry-enabled');
454    this.maybeShowAuthFailBanner_();
455  }
456};
457
458/**
459 * @param {VolumeInfo} volumeInfo Volume info to be checked.
460 * @return {boolean} true if the file system specified by |root| is a target
461 *     to show low space warning. Otherwise false.
462 * @private
463 */
464FileListBannerController.prototype.isLowSpaceWarningTarget_ =
465    function(volumeInfo) {
466  return volumeInfo &&
467      volumeInfo.profile.isCurrentProfile &&
468      (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS ||
469       volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE);
470};
471
472/**
473 * Callback which is invoked when the file system has been changed.
474 * @param {Object} event chrome.fileBrowserPrivate.onDirectoryChanged event.
475 * @private
476 */
477FileListBannerController.prototype.privateOnDirectoryChanged_ = function(
478    event) {
479  if (!this.directoryModel_.getCurrentDirEntry())
480    return;
481
482  var currentDirEntry = this.directoryModel_.getCurrentDirEntry();
483  var currentVolume = currentDirEntry &&
484      this.volumeManager_.getVolumeInfo(currentDirEntry);
485  var eventVolume = this.volumeManager_.getVolumeInfo(event.entry);
486  if (currentVolume === eventVolume) {
487    // The file system we are currently on is changed.
488    // So, check the free space.
489    this.maybeShowLowSpaceWarning_(currentVolume);
490  }
491};
492
493/**
494 * Shows or hides the low space warning.
495 * @param {VolumeInfo} volume Type of volume, which we are interested in.
496 * @private
497 */
498FileListBannerController.prototype.maybeShowLowSpaceWarning_ = function(
499    volume) {
500  // TODO(kaznacheev): Unify the two low space warning.
501  var threshold = 0;
502  switch (volume.volumeType) {
503    case VolumeManagerCommon.VolumeType.DOWNLOADS:
504      this.showLowDriveSpaceWarning_(false);
505      threshold = 0.2;
506      break;
507    case VolumeManagerCommon.VolumeType.DRIVE:
508      this.showLowDownloadsSpaceWarning_(false);
509      threshold = 0.1;
510      break;
511    default:
512      // If the current file system is neither the DOWNLOAD nor the DRIVE,
513      // just hide the warning.
514      this.showLowDownloadsSpaceWarning_(false);
515      this.showLowDriveSpaceWarning_(false);
516      return;
517  }
518
519  // If not mounted correctly, then do not continue.
520  if (!volume.fileSystem)
521    return;
522
523  chrome.fileBrowserPrivate.getSizeStats(
524      volume.volumeId,
525      function(sizeStats) {
526        var currentVolume = this.volumeManager_.getVolumeInfo(
527            this.directoryModel_.getCurrentDirEntry());
528        if (volume !== currentVolume) {
529          // This happens when the current directory is moved during requesting
530          // the file system size. Just ignore it.
531          return;
532        }
533        // sizeStats is undefined, if some error occurs.
534        if (!sizeStats || sizeStats.totalSize == 0)
535          return;
536
537        var remainingRatio = sizeStats.remainingSize / sizeStats.totalSize;
538        var isLowDiskSpace = remainingRatio < threshold;
539        if (volume.volumeType === VolumeManagerCommon.VolumeType.DOWNLOADS)
540          this.showLowDownloadsSpaceWarning_(isLowDiskSpace);
541        else
542          this.showLowDriveSpaceWarning_(isLowDiskSpace, sizeStats);
543      }.bind(this));
544};
545
546/**
547 * removes the Drive Welcome banner.
548 * @private
549 */
550FileListBannerController.prototype.cleanupWelcomeBanner_ = function() {
551  this.showWelcomeBanner_('none');
552};
553
554/**
555 * Notifies the file manager what layout must be recalculated.
556 * @param {number} delay In milliseconds.
557 * @private
558 */
559FileListBannerController.prototype.requestRelayout_ = function(delay) {
560  var self = this;
561  setTimeout(function() {
562    cr.dispatchSimpleEvent(self, 'relayout');
563  }, delay);
564};
565
566/**
567 * Show or hide the "Low disk space" warning.
568 * @param {boolean} show True if the box need to be shown.
569 * @private
570 */
571FileListBannerController.prototype.showLowDownloadsSpaceWarning_ =
572    function(show) {
573  var box = this.document_.querySelector('.downloads-warning');
574
575  if (box.hidden == !show) return;
576
577  if (show) {
578    var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING'));
579    box.innerHTML = html;
580    box.querySelector('a').addEventListener('click', function(e) {
581      util.visitURL(str('DOWNLOADS_LOW_SPACE_WARNING_HELP_URL'));
582      e.preventDefault();
583    });
584  } else {
585    box.innerHTML = '';
586  }
587
588  box.hidden = !show;
589  this.requestRelayout_(100);
590};
591
592/**
593 * Creates contents for the DRIVE unmounted panel.
594 * @private
595 */
596FileListBannerController.prototype.ensureDriveUnmountedPanelInitialized_ =
597    function() {
598  var panel = this.unmountedPanel_;
599  if (panel.firstElementChild)
600    return;
601
602  var create = function(parent, tag, className, opt_textContent) {
603    var div = panel.ownerDocument.createElement(tag);
604    div.className = className;
605    div.textContent = opt_textContent || '';
606    parent.appendChild(div);
607    return div;
608  };
609
610  var loading = create(panel, 'div', 'loading', str('DRIVE_LOADING'));
611  var spinnerBox = create(loading, 'div', 'spinner-box');
612  create(spinnerBox, 'div', 'spinner');
613  create(panel, 'div', 'error', str('DRIVE_CANNOT_REACH'));
614
615  var learnMore = create(panel, 'a', 'learn-more plain-link',
616                         str('DRIVE_LEARN_MORE'));
617  learnMore.href = str('GOOGLE_DRIVE_ERROR_HELP_URL');
618  learnMore.target = '_blank';
619};
620
621/**
622 * Called when volume info list is updated.
623 * @param {Event} event Splice event data on volume info list.
624 * @private
625 */
626FileListBannerController.prototype.onVolumeInfoListSplice_ = function(event) {
627  var isDriveVolume = function(volumeInfo) {
628    return volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE;
629  };
630  if (event.removed.some(isDriveVolume) || event.added.some(isDriveVolume))
631    this.updateDriveUnmountedPanel_();
632};
633
634/**
635 * Shows the panel when current directory is DRIVE and it's unmounted.
636 * Hides it otherwise. The panel shows spinner if DRIVE is mounting or
637 * an error message if it failed.
638 * @private
639 */
640FileListBannerController.prototype.updateDriveUnmountedPanel_ = function() {
641  var node = this.document_.body;
642  if (this.isOnCurrentProfileDrive()) {
643    var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
644        VolumeManagerCommon.VolumeType.DRIVE);
645    if (driveVolume && driveVolume.error) {
646      this.ensureDriveUnmountedPanelInitialized_();
647      this.unmountedPanel_.classList.add('retry-enabled');
648    } else {
649      this.unmountedPanel_.classList.remove('retry-enabled');
650    }
651    node.setAttribute('drive', status);
652  } else {
653    node.removeAttribute('drive');
654  }
655};
656
657/**
658 * Updates the visibility of Drive Connection Warning banner, retrieving the
659 * current connection information.
660 * @private
661 */
662FileListBannerController.prototype.maybeShowAuthFailBanner_ = function() {
663  var connection = this.volumeManager_.getDriveConnectionState();
664  var showDriveNotReachedMessage =
665      this.isOnCurrentProfileDrive() &&
666      connection.type == VolumeManagerCommon.DriveConnectionType.OFFLINE &&
667      connection.reason == VolumeManagerCommon.DriveConnectionReason.NOT_READY;
668  this.authFailedBanner_.hidden = !showDriveNotReachedMessage;
669};
670