Commit ed5b8e64 authored by hirono's avatar hirono Committed by Commit bot

Files.app: Show the notification when a user pins a drive file over cellular network.

Previously if drive sync over cellular network is disabled, pinning a drive file
is pending without notificaiton.

This CL lets Files.app show the notifiction.

BUG=279476
TEST=DriveSpecific/FileManagerBrowserTest.Test/4

Review URL: https://codereview.chromium.org/676653002

Cr-Commit-Position: refs/heads/master@{#302063}
parent b423f89f
......@@ -649,6 +649,12 @@ Press any key to continue exploring.
<message name="IDS_FILE_BROWSER_CONFIRM_MOBILE_DATA_USE_PLURAL" desc="Message informing the user that opening several files from Google Drive will use mobile data.">
Fetching these files will use approximately <ph name="FILE_SIZE">$1<ex>44 MB</ex></ph> of mobile data.
</message>
<message name="IDS_FILE_BROWSER_DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE" desc="Notification message shown when the drive sync is needed on mobile network, but it is disabled.">
Google Drive sync is disabled by default, when using mobile data.
</message>
<message name="IDS_FILE_BROWSER_DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON" desc="Button label to enable drive sync over, on the notifcation of |IDS_FILE_BROWSER_DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE|.">
Enable syncing over mobile data
</message>
<message name="IDS_FILE_BROWSER_OPEN_IN_OTHER_DESKTOP_MESSAGE" desc="Message of an alert dialog that is shown when a user opens a file in a desktop of another profile but the file is opened in the original desktop.">
This file opened on a different desktop. Move to <ph name="USER_NAME">$1<ex>John Doe</ex></ph> (<ph name="MAIL_ADDRESS">$2<ex>xxxxxx@gmail.com</ex></ph>) to view it.
</message>
......
......@@ -361,6 +361,10 @@ bool FileManagerPrivateGetStringsFunction::RunSync() {
IDS_FILE_BROWSER_CONFIRM_MOBILE_DATA_USE);
SET_STRING("CONFIRM_MOBILE_DATA_USE_PLURAL",
IDS_FILE_BROWSER_CONFIRM_MOBILE_DATA_USE_PLURAL);
SET_STRING("DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE",
IDS_FILE_BROWSER_DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE);
SET_STRING("DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON",
IDS_FILE_BROWSER_DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON);
SET_STRING("DRIVE_OUT_OF_SPACE_HEADER",
IDS_FILE_BROWSER_DRIVE_OUT_OF_SPACE_HEADER);
SET_STRING("DRIVE_OUT_OF_SPACE_MESSAGE",
......
......@@ -21,8 +21,10 @@
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/drive/drive_integration_service.h"
#include "chrome/browser/chromeos/drive/file_system_interface.h"
#include "chrome/browser/chromeos/drive/test_util.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/drive_test_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
......@@ -31,6 +33,8 @@
#include "chrome/browser/drive/fake_drive_service.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
......@@ -546,7 +550,7 @@ class FileManagerBrowserTestBase : public ExtensionApiTest {
virtual GuestMode GetGuestModeParam() const = 0;
virtual const char* GetTestCaseNameParam() const = 0;
virtual void OnMessage(const std::string& name,
const base::Value& value,
const base::DictionaryValue& value,
std::string* output);
scoped_ptr<LocalTestVolume> local_volume_;
......@@ -592,6 +596,8 @@ void FileManagerBrowserTestBase::SetUpOnMainThread() {
drive_volume_->ConfigureShareUrlBase(share_url_base);
test_util::WaitUntilDriveMountPointIsAdded(profile());
}
net::NetworkChangeNotifier::SetTestNotificationsOnly(true);
}
void FileManagerBrowserTestBase::SetUpCommandLine(CommandLine* command_line) {
......@@ -644,15 +650,16 @@ void FileManagerBrowserTestBase::RunTestMessageLoop() {
continue;
std::string output;
OnMessage(name, *value.get(), &output);
OnMessage(name, *message_dictionary, &output);
if (HasFatalFailure())
break;
entry.function->Reply(output);
}
}
void FileManagerBrowserTestBase::OnMessage(const std::string& name,
const base::Value& value,
const base::DictionaryValue& value,
std::string* output) {
if (name == "getTestName") {
// Pass the test case name.
......@@ -741,6 +748,29 @@ void FileManagerBrowserTestBase::OnMessage(const std::string& name,
return;
}
if (name == "useCellularNetwork") {
net::NetworkChangeNotifier::NotifyObserversOfConnectionTypeChangeForTests(
net::NetworkChangeNotifier::CONNECTION_3G);
return;
}
if (name == "clickNotificationButton") {
std::string extension_id;
std::string notification_id;
int index;
ASSERT_TRUE(value.GetString("extensionId", &extension_id));
ASSERT_TRUE(value.GetString("notificationId", &notification_id));
ASSERT_TRUE(value.GetInteger("index", &index));
const std::string delegate_id = extension_id + "-" + notification_id;
const Notification* notification = g_browser_process->
notification_ui_manager()->FindById(delegate_id, profile());
ASSERT_TRUE(notification);
notification->delegate()->ButtonClick(index);
return;
}
FAIL() << "Unknown test message: " << name;
}
......@@ -877,11 +907,12 @@ WRAPPED_INSTANTIATE_TEST_CASE_P(
WRAPPED_INSTANTIATE_TEST_CASE_P(
MAYBE_DriveSpecific,
FileManagerBrowserTest,
::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
TestParameter(NOT_IN_GUEST_MODE,
"openSidebarSharedWithMe"),
TestParameter(NOT_IN_GUEST_MODE, "autocomplete")));
::testing::Values(
TestParameter(NOT_IN_GUEST_MODE, "openSidebarRecent"),
TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"),
TestParameter(NOT_IN_GUEST_MODE, "openSidebarSharedWithMe"),
TestParameter(NOT_IN_GUEST_MODE, "autocomplete"),
TestParameter(NOT_IN_GUEST_MODE, "pinFileOnMobileNetwork")));
// Slow tests are disabled on debug build. http://crbug.com/327719
#if !defined(NDEBUG)
......@@ -1229,7 +1260,7 @@ class GalleryBrowserTestBase : public FileManagerBrowserTestBase {
}
virtual void OnMessage(const std::string& name,
const base::Value& value,
const base::DictionaryValue& value,
std::string* output) override;
virtual const char* GetTestManifestName() const override {
......@@ -1252,7 +1283,7 @@ class GalleryBrowserTestBase : public FileManagerBrowserTestBase {
template <GuestMode M>
void GalleryBrowserTestBase<M>::OnMessage(const std::string& name,
const base::Value& value,
const base::DictionaryValue& value,
std::string* output) {
if (name == "getScripts") {
std::string jsonString;
......@@ -1440,7 +1471,7 @@ class VideoPlayerBrowserTestBase : public FileManagerBrowserTestBase {
}
virtual void OnMessage(const std::string& name,
const base::Value& value,
const base::DictionaryValue& value,
std::string* output) override;
virtual const char* GetTestManifestName() const override {
......@@ -1462,9 +1493,10 @@ class VideoPlayerBrowserTestBase : public FileManagerBrowserTestBase {
};
template <GuestMode M>
void VideoPlayerBrowserTestBase<M>::OnMessage(const std::string& name,
const base::Value& value,
std::string* output) {
void VideoPlayerBrowserTestBase<M>::OnMessage(
const std::string& name,
const base::DictionaryValue& value,
std::string* output) {
if (name == "getScripts") {
std::string jsonString;
base::JSONWriter::Write(&scripts_, output);
......
......@@ -167,3 +167,67 @@ testcase.autocomplete = function() {
}
]);
};
/**
* Tests pinning a file on mobile network.
*/
testcase.pinFileOnMobileNetwork = function() {
testPromise(setupAndWaitUntilReady(null, RootPath.DRIVE).then(
function(windowId) {
return sendTestMessage(
{name: 'useCellularNetwork'}).then(function(result) {
return remoteCall.callRemoteTestUtil(
'selectFile', windowId, ['hello.txt']);
}).then(function() {
return repeatUntil(function() {
return navigator.connection.type != 'cellular' ?
pending('Network state is not changed to cellular.') : null;
});
}).then(function() {
return remoteCall.waitForElement(windowId, ['.table-row[selected]']);
}).then(function() {
return remoteCall.callRemoteTestUtil(
'fakeMouseRightClick', windowId, ['.table-row[selected]']);
}).then(function(result) {
chrome.test.assertTrue(result);
return remoteCall.waitForElement(
windowId, '#file-context-menu:not([hidden])');
}).then(function() {
return remoteCall.callRemoteTestUtil(
'fakeMouseClick', windowId, ['[command="#toggle-pinned"]']);
}).then(function(result) {
return remoteCall.waitForElement(
windowId, '#file-context-menu[hidden]');
}).then(function() {
return remoteCall.callRemoteTestUtil(
'fakeEvent', windowId, ['#file-list', 'contextmenu']);
}).then(function(result) {
chrome.test.assertTrue(result);
return remoteCall.waitForElement(
windowId, '[command="#toggle-pinned"][checked]');
}).then(function() {
return repeatUntil(function() {
return remoteCall.callRemoteTestUtil(
'getNotificationIDs', null, []).then(function(idSet) {
return !idSet['disabled-mobile-sync'] ?
pending('Sync disable notification is not found.') : null;
});
});
}).then(function() {
return sendTestMessage({
name: 'clickNotificationButton',
extensionId: FILE_MANAGER_EXTENSIONS_ID,
notificationId: 'disabled-mobile-sync',
index: 0
});
}).then(function() {
return repeatUntil(function() {
return remoteCall.callRemoteTestUtil(
'getPreferences', null, []).then(function(preferences) {
return preferences.cellularDisabled ?
pending('Drive sync is still disabled.') : null;
});
});
});
}));
};
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* TODO(hirono): Remove this after the build-in extern supports it.
* @type {{type:string}}
*/
Navigator.prototype.connection;
......@@ -67,10 +67,9 @@ function FileBrowserBackground() {
/**
* Drive sync handler.
* @type {DriveSyncHandler}
* @private
*/
this.driveSyncHandler_ = new DriveSyncHandler(this.progressCenter);
this.driveSyncHandler_.addEventListener(
this.driveSyncHandler = new DriveSyncHandler(this.progressCenter);
this.driveSyncHandler.addEventListener(
DriveSyncHandler.COMPLETED_EVENT,
function() { this.tryClose(); }.bind(this));
......@@ -162,7 +161,7 @@ FileBrowserBackground.prototype.ready = function(callback) {
FileBrowserBackground.prototype.canClose = function() {
// If the file operation is going, the background page cannot close.
if (this.fileOperationManager.hasQueuedTasks() ||
this.driveSyncHandler_.syncing) {
this.driveSyncHandler.syncing) {
this.lastTimeCanClose_ = null;
return false;
}
......
......@@ -34,6 +34,7 @@
'<(CLOSURE_DIR)/externs/chrome_extensions.js',
'<(CLOSURE_DIR)/externs/file_manager_private.js',
'../../../externs/chrome_file_browser_handler.js',
'../../../externs/connection.js',
'../../../externs/css_rule.js',
'../../../externs/webview_tag.js',
],
......
......@@ -8,11 +8,14 @@
* progressing items.
* @constructor
* @extends {cr.EventTarget}
* @suppress {checkStructDictInheritance}
* @struct
*/
function DriveSyncHandler(progressCenter) {
/**
* Progress center to submit the progressing item.
* @type {ProgressCenter}
* @const
* @private
*/
this.progressCenter_ = progressCenter;
......@@ -27,6 +30,7 @@ function DriveSyncHandler(progressCenter) {
/**
* Progress center item.
* @type {ProgressCenterItem}
* @const
* @private
*/
this.item_ = new ProgressCenterItem();
......@@ -39,9 +43,17 @@ function DriveSyncHandler(progressCenter) {
*/
this.syncing_ = false;
/**
* Whether the sync is disabled on cellular network or not.
* @type {boolean}
* @private
*/
this.cellularDisabled_ = false;
/**
* Async queue.
* @type {AsyncUtil.Queue}
* @const
* @private
*/
this.queue_ = new AsyncUtil.Queue();
......@@ -51,6 +63,13 @@ function DriveSyncHandler(progressCenter) {
this.onFileTransfersUpdated_.bind(this));
chrome.fileManagerPrivate.onDriveSyncError.addListener(
this.onDriveSyncError_.bind(this));
chrome.notifications.onButtonClicked.addListener(
this.onNotificationButtonClicked_.bind(this));
chrome.fileManagerPrivate.onPreferencesChanged.addListener(
this.onPreferencesChanged_.bind(this));
// Set initial values.
this.onPreferencesChanged_();
}
/**
......@@ -67,7 +86,15 @@ DriveSyncHandler.COMPLETED_EVENT = 'completed';
*/
DriveSyncHandler.DRIVE_SYNC_ERROR_PREFIX = 'drive-sync-error-';
DriveSyncHandler.prototype = {
/**
* Notification ID of the disabled mobile sync notification.
* @type {string}
* @private
* @const
*/
DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_ = 'disabled-mobile-sync';
DriveSyncHandler.prototype = /** @struct */ {
__proto__: cr.EventTarget.prototype,
/**
......@@ -78,6 +105,35 @@ DriveSyncHandler.prototype = {
}
};
/**
* Returns whether the drive sync is currently suppressed or not.
* @private
* @return {boolean}
*/
DriveSyncHandler.prototype.isSyncSuppressed = function() {
return navigator.connection.type === 'cellular' &&
this.cellularDisabled_;
};
/**
* Shows the notification saying that the drive sync is disabled on cellular
* network.
*/
DriveSyncHandler.prototype.showDisabledMobileSyncNotification = function() {
chrome.notifications.create(
DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_,
{
type: 'basic',
title: chrome.runtime.getManifest().name,
message: str('DISABLED_MOBILE_SYNC_NOTIFICATION_MESSAGE'),
iconUrl: chrome.runtime.getURL('/common/images/icon96.png'),
buttons: [
{title: str('DISABLED_MOBILE_SYNC_NOTIFICATION_ENABLE_BUTTON')}
]
},
function() {});
};
/**
* Handles file transfer updated events.
* @param {FileTransferStatus} status Transfer status.
......@@ -183,3 +239,29 @@ DriveSyncHandler.prototype.onDriveSyncError_ = function(event) {
this.progressCenter_.updateItem(item);
}.bind(this));
};
/**
* Handles notification's button click.
* @param {string} notificationId Notification ID.
* @param {number} buttonIndex Index of the button.
* @private
*/
DriveSyncHandler.prototype.onNotificationButtonClicked_ = function(
notificationId, buttonIndex) {
if (notificationId !== DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_)
return;
chrome.notifications.clear(
DriveSyncHandler.DISABLED_MOBILE_SYNC_NOTIFICATION_ID_,
function() {});
chrome.fileManagerPrivate.setPreferences({cellularDisabled: false});
};
/**
* Handles preferences change.
* @private
*/
DriveSyncHandler.prototype.onPreferencesChanged_ = function() {
chrome.fileManagerPrivate.getPreferences(function(pref) {
this.cellularDisabled_ = pref.cellularDisabled;
}.bind(this));
};
......@@ -671,6 +671,24 @@ test.util.sync.unload = function(contentWindow) {
contentWindow.fileManager.onUnload_();
};
/**
* Obtains the list of notification ID.
* @param {function(Object.<string, boolean>)} callback Callback function with
* results returned by the script.
*/
test.util.async.getNotificationIDs = function(callback) {
chrome.notifications.getAll(callback);
};
/**
* Obtains the preferences.
* @param {function(Object)} callback Callback function with results returned by
* the script.
*/
test.util.async.getPreferences = function(callback) {
chrome.fileManagerPrivate.getPreferences(callback);
};
/**
* Registers message listener, which runs test utility functions.
*/
......
......@@ -106,6 +106,7 @@
'../../../externs/chrome_echo_private.js',
'../../../externs/chrome_file_browser_handler.js',
'../../../externs/chrome_test.js',
'../../../externs/connection.js',
'../../../externs/css_rule.js',
'../../../externs/html_menu_item_element.js',
'../../../externs/webview_tag.js',
......
......@@ -687,10 +687,16 @@ CommandHandler.COMMANDS_['volume-switch-9'] =
* @type {Command}
*/
CommandHandler.COMMANDS_['toggle-pinned'] = /** @type {Command} */ ({
/**
* @param {Event} event
* @param {FileManager} fileManager
*/
execute: function(event, fileManager) {
var pin = !event.command.checked;
event.command.checked = pin;
var entries = CommandUtil.getPinTargetEntries();
if (entries.length == 0)
return;
var currentEntry;
var error = false;
var steps = {
......@@ -735,6 +741,11 @@ CommandHandler.COMMANDS_['toggle-pinned'] = /** @type {Command} */ ({
}
};
steps.start();
var driveSyncHandler =
fileManager.backgroundPage.background.driveSyncHandler;
if (pin && driveSyncHandler.isSyncSuppressed())
driveSyncHandler.showDisabledMobileSyncNotification();
},
canExecute: function(event, fileManager) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment