cros: Remove default pinned apps trial.
[chromium-blink-merge.git] / chrome / browser / resources / file_manager / foreground / js / drive_banners.js
blobdc1cd924d7a7dfa282089bfa3beef1c008513b72
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.
5 'use strict';
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  */
17 function 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;
25   this.initializeWelcomeBanner_();
26   this.privateOnDirectoryChangedBound_ =
27       this.privateOnDirectoryChanged_.bind(this);
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));
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));
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));
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_();
63 /**
64  * FileListBannerController extends cr.EventTarget.
65  */
66 FileListBannerController.prototype.__proto__ = cr.EventTarget.prototype;
68 /**
69  * Key in localStorage to keep number of times the Drive Welcome
70  * banner has shown.
71  */
72 var WELCOME_HEADER_COUNTER_KEY = 'driveWelcomeHeaderCounter';
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.
77 var WARNING_DISMISSED_KEY = 'driveSpaceWarningDismissed';
79 /**
80  * Maximum times Drive Welcome banner could have shown.
81  */
82 var WELCOME_HEADER_COUNTER_LIMIT = 25;
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  */
90 FileListBannerController.prototype.initializeWelcomeBanner_ = function() {
91   this.usePromoWelcomeBanner_ = !util.boardIs('x86-mario') &&
92                                 !util.boardIs('x86-zgb') &&
93                                 !util.boardIs('x86-alex');
96 /**
97  * @param {number} value How many times the Drive Welcome header banner
98  * has shown.
99  * @private
100  */
101 FileListBannerController.prototype.setWelcomeHeaderCounter_ = function(value) {
102   var values = {};
103   values[WELCOME_HEADER_COUNTER_KEY] = value;
104   chrome.storage.local.set(values);
108  * @param {number} value How many times the low space warning has dismissed.
109  * @private
110  */
111 FileListBannerController.prototype.setWarningDismissedCounter_ =
112     function(value) {
113   var values = {};
114   values[WARNING_DISMISSED_KEY] = value;
115   chrome.storage.local.set(values);
119  * chrome.storage.onChanged event handler.
120  * @param {Object.<string, Object>} changes Changes values.
121  * @param {string} areaName "local" or "sync".
122  * @private
123  */
124 FileListBannerController.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   }
135  * Invoked when the drive connection status is change in the volume manager.
136  * @private
137  */
138 FileListBannerController.prototype.onDriveConnectionChanged_ = function() {
139   this.maybeShowAuthFailBanner_();
143  * @param {string} type 'none'|'page'|'header'.
144  * @param {string} messageId Resource ID of the message.
145  * @private
146  */
147 FileListBannerController.prototype.prepareAndShowWelcomeBanner_ =
148     function(type, messageId) {
149   this.showWelcomeBanner_(type);
151   var container = this.document_.querySelector('.drive-welcome.' + type);
152   if (container.firstElementChild)
153     return;  // Do not re-create.
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   }
163   var wrapper = util.createChild(container, 'drive-welcome-wrapper');
164   util.createChild(wrapper, 'drive-welcome-icon');
166   var close = util.createChild(wrapper, 'cr-dialog-close');
167   close.addEventListener('click', this.closeWelcomeBanner_.bind(this));
169   var message = util.createChild(wrapper, 'drive-welcome-message');
171   var title = util.createChild(message, 'drive-welcome-title');
173   var text = util.createChild(message, 'drive-welcome-text');
174   text.innerHTML = str(messageId);
176   var links = util.createChild(message, 'drive-welcome-links');
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 = '13';  // See: go/filesapp-tabindex.
195   more.target = '_blank';
197   var dismiss;
198   if (this.usePromoWelcomeBanner_)
199     dismiss = util.createChild(links, 'drive-welcome-button');
200   else
201     dismiss = util.createChild(links, 'plain-link');
203   dismiss.classList.add('drive-welcome-dismiss');
204   dismiss.textContent = str('DRIVE_WELCOME_DISMISS');
205   dismiss.addEventListener('click', this.closeWelcomeBanner_.bind(this));
207   this.previousDirWasOnDrive_ = false;
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  */
217 FileListBannerController.prototype.showLowDriveSpaceWarning_ =
218       function(show, sizeStats) {
219   var box = this.document_.querySelector('#volume-space-warning');
221   // Avoid showing two banners.
222   // TODO(kaznacheev): Unify the low space warning and the promo header.
223   if (show)
224     this.cleanupWelcomeBanner_();
226   if (box.hidden == !show)
227     return;
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   }
242   box.textContent = '';
243   if (show) {
244     var icon = this.document_.createElement('div');
245     icon.className = 'drive-icon';
246     box.appendChild(icon);
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);
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);
261     var close = this.document_.createElement('div');
262     close.className = 'cr-dialog-close';
263     box.appendChild(close);
264     close.addEventListener('click', function(total) {
265       window.localStorage[WARNING_DISMISSED_KEY] = total;
266       box.hidden = true;
267       this.requestRelayout_(100);
268     }.bind(this, sizeStats.totalSize));
269   }
271   if (box.hidden != !show) {
272     box.hidden = !show;
273     this.requestRelayout_(100);
274   }
277  * Closes the Drive Welcome banner.
278  * @private
279  */
280 FileListBannerController.prototype.closeWelcomeBanner_ = function() {
281   this.cleanupWelcomeBanner_();
282   // Stop showing the welcome banner.
283   this.setWelcomeHeaderCounter_(WELCOME_HEADER_COUNTER_LIMIT);
287  * Shows or hides the welcome banner for drive.
288  * @private
289  */
290 FileListBannerController.prototype.checkSpaceAndMaybeShowWelcomeBanner_ =
291     function() {
292   if (!this.isOnCurrentProfileDrive()) {
293     // We are not on the drive file system. Do not show (close) the welcome
294     // banner.
295     this.cleanupWelcomeBanner_();
296     this.previousDirWasOnDrive_ = false;
297     return;
298   }
300   var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
301       util.VolumeType.DRIVE);
302   if (this.welcomeHeaderCounter_ >= WELCOME_HEADER_COUNTER_LIMIT ||
303       !driveVolume || driveVolume.error) {
304     // The banner is already shown enough times or the drive FS is not mounted.
305     // So, do nothing here.
306     return;
307   }
309   if (!this.showOffers_) {
310     // Because it is not necessary to show the offer, set
311     // |usePromoWelcomeBanner_| false here. Note that it probably should be able
312     // to do this in the constructor, but there remains non-trivial path,
313     // which may be causes |usePromoWelcomeBanner_| == true's behavior even
314     // if |showOffers_| is false.
315     // TODO(hidehiko): Make sure if it is expected or not, and simplify
316     // |showOffers_| if possible.
317     this.usePromoWelcomeBanner_ = false;
318   }
320   // Perform asynchronous tasks in parallel.
321   var group = new AsyncUtil.Group();
323   // Choose the offer basing on the board name. The default one is 100 GB.
324   var offerSize = 100;  // In GB.
325   var offerServiceId = 'drive.cros.echo.1';
327   if (util.boardIs('link')) {
328     offerSize = 1024;  // 1 TB.
329     offerServiceId = 'drive.cros.echo.2';
330   }
332   // If the offer has been checked, then do not show the promo anymore.
333   group.add(function(onCompleted) {
334     chrome.echoPrivate.getOfferInfo(offerServiceId, function(offerInfo) {
335       // If the offer has not been checked, then an error is raised.
336       if (!chrome.runtime.lastError)
337         this.usePromoWelcomeBanner_ = false;
338       onCompleted();
339     }.bind(this));
340   }.bind(this));
342   if (this.usePromoWelcomeBanner_) {
343     // getSizeStats for Drive file system accesses to the server, so we should
344     // minimize the invocation.
345     group.add(function(onCompleted) {
346       chrome.fileBrowserPrivate.getSizeStats(
347           util.makeFilesystemUrl(this.directoryModel_.getCurrentRootPath()),
348           function(result) {
349             if (result && result.totalSize >= offerSize * 1024 * 1024 * 1024)
350               this.usePromoWelcomeBanner_ = false;
351             onCompleted();
352           }.bind(this));
353     }.bind(this));
354   }
356   group.run(this.maybeShowWelcomeBanner_.bind(this));
360  * Decides which banner should be shown, and show it. This method is designed
361  * to be called only from checkSpaceAndMaybeShowWelcomeBanner_.
362  * @private
363  */
364 FileListBannerController.prototype.maybeShowWelcomeBanner_ = function() {
365   if (this.directoryModel_.getFileList().length == 0 &&
366       this.welcomeHeaderCounter_ == 0) {
367     // Only show the full page banner if the header banner was never shown.
368     // Do not increment the counter.
369     // The timeout below is required because sometimes another
370     // 'rescan-completed' event arrives shortly with non-empty file list.
371     setTimeout(function() {
372       if (this.isOnCurrentProfileDrive() && this.welcomeHeaderCounter_ == 0) {
373         this.prepareAndShowWelcomeBanner_('page', 'DRIVE_WELCOME_TEXT_LONG');
374       }
375     }.bind(this), 2000);
376   } else {
377     // We do not want to increment the counter when the user navigates
378     // between different directories on Drive, but we increment the counter
379     // once anyway to prevent the full page banner from showing.
380     if (!this.previousDirWasOnDrive_ || this.welcomeHeaderCounter_ == 0) {
381       this.setWelcomeHeaderCounter_(this.welcomeHeaderCounter_ + 1);
382       this.prepareAndShowWelcomeBanner_('header', 'DRIVE_WELCOME_TEXT_SHORT');
383     }
384   }
385   this.previousDirWasOnDrive_ = true;
389  * @return {boolean} True if current directory is on Drive root of current
390  * profile.
391  */
392 FileListBannerController.prototype.isOnCurrentProfileDrive = function() {
393   var entry = this.directoryModel_.getCurrentDirEntry();
394   if (!entry || util.isFakeEntry(entry))
395     return false;
396   var locationInfo = this.volumeManager_.getLocationInfo(entry);
397   return locationInfo &&
398       locationInfo.rootType === RootType.DRIVE &&
399       locationInfo.volumeInfo.profile.isCurrentProfile;
403  * Shows the Drive Welcome banner.
404  * @param {string} type 'page'|'head'|'none'.
405  * @private
406  */
407 FileListBannerController.prototype.showWelcomeBanner_ = function(type) {
408   var container = this.document_.querySelector('.dialog-container');
409   if (container.getAttribute('drive-welcome') != type) {
410     container.setAttribute('drive-welcome', type);
411     this.requestRelayout_(200);  // Resize only after the animation is done.
412   }
416  * Update the UI when the current directory changes.
418  * @param {Event} event The directory-changed event.
419  * @private
420  */
421 FileListBannerController.prototype.onDirectoryChanged_ = function(event) {
422   var rootVolume = this.volumeManager_.getVolumeInfo(event.newDirEntry);
423   var previousRootVolume = event.previousDirEntry ?
424       this.volumeManager_.getVolumeInfo(event.previousDirEntry) : null;
426   // Show (or hide) the low space warning.
427   this.maybeShowLowSpaceWarning_(rootVolume);
429   // Add or remove listener to show low space warning, if necessary.
430   var isLowSpaceWarningTarget = this.isLowSpaceWarningTarget_(rootVolume);
431   if (isLowSpaceWarningTarget !==
432       this.isLowSpaceWarningTarget_(previousRootVolume)) {
433     if (isLowSpaceWarningTarget) {
434       chrome.fileBrowserPrivate.onDirectoryChanged.addListener(
435           this.privateOnDirectoryChangedBound_);
436     } else {
437       chrome.fileBrowserPrivate.onDirectoryChanged.removeListener(
438           this.privateOnDirectoryChangedBound_);
439     }
440   }
442   if (!this.isOnCurrentProfileDrive()) {
443     this.cleanupWelcomeBanner_();
444     this.authFailedBanner_.hidden = true;
445   }
447   this.updateDriveUnmountedPanel_();
448   if (this.isOnCurrentProfileDrive()) {
449     this.unmountedPanel_.classList.remove('retry-enabled');
450     this.maybeShowAuthFailBanner_();
451   }
455  * @param {VolumeInfo} volumeInfo Volume info to be checked.
456  * @return {boolean} true if the file system specified by |root| is a target
457  *     to show low space warning. Otherwise false.
458  * @private
459  */
460 FileListBannerController.prototype.isLowSpaceWarningTarget_ =
461     function(volumeInfo) {
462   return volumeInfo &&
463       volumeInfo.profile.isCurrentProfile &&
464       (volumeInfo.volumeType === util.VolumeType.DOWNLOADS ||
465        volumeInfo.volumeType === util.VolumeType.DRIVE);
469  * Callback which is invoked when the file system has been changed.
470  * @param {Object} event chrome.fileBrowserPrivate.onDirectoryChanged event.
471  * @private
472  */
473 FileListBannerController.prototype.privateOnDirectoryChanged_ = function(
474     event) {
475   if (!this.directoryModel_.getCurrentDirEntry())
476     return;
478   var currentDirEntry = this.directoryModel_.getCurrentDirEntry();
479   var currentVolume = currentDirEntry &&
480       this.volumeManager_.getVolumeInfo(currentDirEntry);
481   var eventVolume = this.volumeManager_.getVolumeInfo(event.entry);
482   if (currentVolume === eventVolume) {
483     // The file system we are currently on is changed.
484     // So, check the free space.
485     this.maybeShowLowSpaceWarning_(currentVolume);
486   }
490  * Shows or hides the low space warning.
491  * @param {VolumeInfo} volume Type of volume, which we are interested in.
492  * @private
493  */
494 FileListBannerController.prototype.maybeShowLowSpaceWarning_ = function(
495     volume) {
496   // TODO(kaznacheev): Unify the two low space warning.
497   var threshold = 0;
498   switch (volume.volumeType) {
499     case util.VolumeType.DOWNLOADS:
500       this.showLowDriveSpaceWarning_(false);
501       threshold = 0.2;
502       break;
503     case util.VolumeType.DRIVE:
504       this.showLowDownloadsSpaceWarning_(false);
505       threshold = 0.1;
506       break;
507     default:
508       // If the current file system is neither the DOWNLOAD nor the DRIVE,
509       // just hide the warning.
510       this.showLowDownloadsSpaceWarning_(false);
511       this.showLowDriveSpaceWarning_(false);
512       return;
513   }
515   chrome.fileBrowserPrivate.getSizeStats(
516       volume.getDisplayRootDirectoryURL(),
517       function(sizeStats) {
518         var currentVolume = this.volumeManager_.getVolumeInfo(
519             this.directoryModel_.getCurrentDirEntry());
520         if (volume !== currentVolume) {
521           // This happens when the current directory is moved during requesting
522           // the file system size. Just ignore it.
523           return;
524         }
525         // sizeStats is undefined, if some error occurs.
526         if (!sizeStats || sizeStats.totalSize == 0)
527           return;
529         var remainingRatio = sizeStats.remainingSize / sizeStats.totalSize;
530         var isLowDiskSpace = remainingRatio < threshold;
531         if (volume.volumeType === util.VolumeType.DOWNLOADS)
532           this.showLowDownloadsSpaceWarning_(isLowDiskSpace);
533         else
534           this.showLowDriveSpaceWarning_(isLowDiskSpace, sizeStats);
535       }.bind(this));
539  * removes the Drive Welcome banner.
540  * @private
541  */
542 FileListBannerController.prototype.cleanupWelcomeBanner_ = function() {
543   this.showWelcomeBanner_('none');
547  * Notifies the file manager what layout must be recalculated.
548  * @param {number} delay In milliseconds.
549  * @private
550  */
551 FileListBannerController.prototype.requestRelayout_ = function(delay) {
552   var self = this;
553   setTimeout(function() {
554     cr.dispatchSimpleEvent(self, 'relayout');
555   }, delay);
559  * Show or hide the "Low disk space" warning.
560  * @param {boolean} show True if the box need to be shown.
561  * @private
562  */
563 FileListBannerController.prototype.showLowDownloadsSpaceWarning_ =
564     function(show) {
565   var box = this.document_.querySelector('.downloads-warning');
567   if (box.hidden == !show) return;
569   if (show) {
570     var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING'));
571     box.innerHTML = html;
572     var link = box.querySelector('a');
573     link.href = str('DOWNLOADS_LOW_SPACE_WARNING_HELP_URL');
574     link.target = '_blank';
575   } else {
576     box.innerHTML = '';
577   }
579   box.hidden = !show;
580   this.requestRelayout_(100);
584  * Creates contents for the DRIVE unmounted panel.
585  * @private
586  */
587 FileListBannerController.prototype.ensureDriveUnmountedPanelInitialized_ =
588     function() {
589   var panel = this.unmountedPanel_;
590   if (panel.firstElementChild)
591     return;
593   var create = function(parent, tag, className, opt_textContent) {
594     var div = panel.ownerDocument.createElement(tag);
595     div.className = className;
596     div.textContent = opt_textContent || '';
597     parent.appendChild(div);
598     return div;
599   };
601   var loading = create(panel, 'div', 'loading', str('DRIVE_LOADING'));
602   var spinnerBox = create(loading, 'div', 'spinner-box');
603   create(spinnerBox, 'div', 'spinner');
604   create(panel, 'div', 'error', str('DRIVE_CANNOT_REACH'));
606   var learnMore = create(panel, 'a', 'learn-more plain-link',
607                          str('DRIVE_LEARN_MORE'));
608   learnMore.href = str('GOOGLE_DRIVE_ERROR_HELP_URL');
609   learnMore.target = '_blank';
613  * Called when volume info list is updated.
614  * @param {Event} event Splice event data on volume info list.
615  * @private
616  */
617 FileListBannerController.prototype.onVolumeInfoListSplice_ = function(event) {
618   var isDriveVolume = function(volumeInfo) {
619     return volumeInfo.volumeType === util.VolumeType.DRIVE;
620   };
621   if (event.removed.some(isDriveVolume) || event.added.some(isDriveVolume))
622     this.updateDriveUnmountedPanel_();
626  * Shows the panel when current directory is DRIVE and it's unmounted.
627  * Hides it otherwise. The panel shows spinner if DRIVE is mounting or
628  * an error message if it failed.
629  * @private
630  */
631 FileListBannerController.prototype.updateDriveUnmountedPanel_ = function() {
632   var node = this.document_.body;
633   if (this.isOnCurrentProfileDrive()) {
634     var driveVolume = this.volumeManager_.getCurrentProfileVolumeInfo(
635         util.VolumeType.DRIVE);
636     if (driveVolume && driveVolume.error) {
637       this.ensureDriveUnmountedPanelInitialized_();
638       this.unmountedPanel_.classList.add('retry-enabled');
639     } else {
640       this.unmountedPanel_.classList.remove('retry-enabled');
641     }
642     node.setAttribute('drive', status);
643   } else {
644     node.removeAttribute('drive');
645   }
649  * Updates the visibility of Drive Connection Warning banner, retrieving the
650  * current connection information.
651  * @private
652  */
653 FileListBannerController.prototype.maybeShowAuthFailBanner_ = function() {
654   var connection = this.volumeManager_.getDriveConnectionState();
655   var showDriveNotReachedMessage =
656       this.isOnCurrentProfileDrive() &&
657       connection.type == util.DriveConnectionType.OFFLINE &&
658       connection.reason == util.DriveConnectionReason.NOT_READY;
659   this.authFailedBanner_.hidden = !showDriveNotReachedMessage;