Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / tabs / tabs_api.cc
index 71c441c..40e84dd 100644 (file)
 #include "chrome/browser/extensions/api/tabs/windows_util.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
-#include "chrome/browser/extensions/script_executor.h"
 #include "chrome/browser/extensions/tab_helper.h"
 #include "chrome/browser/extensions/window_controller.h"
 #include "chrome/browser/extensions/window_controller_list.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
-#include "chrome/browser/ui/apps/chrome_app_window_delegate.h"
+#include "chrome/browser/ui/apps/chrome_app_delegate.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
@@ -44,6 +43,7 @@
 #include "chrome/browser/ui/panels/panel_manager.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/window_sizer/window_sizer.h"
+#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
 #include "extensions/browser/extension_function_util.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/file_reader.h"
+#include "extensions/browser/script_executor.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/extension.h"
-#include "extensions/common/extension_l10n_util.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/message_bundle.h"
@@ -163,6 +163,29 @@ void AssignOptionalValue(const scoped_ptr<T>& source,
 
 }  // namespace
 
+void ZoomModeToZoomSettings(ZoomController::ZoomMode zoom_mode,
+                            api::tabs::ZoomSettings* zoom_settings) {
+  DCHECK(zoom_settings);
+  switch (zoom_mode) {
+    case ZoomController::ZOOM_MODE_DEFAULT:
+      zoom_settings->mode = api::tabs::ZoomSettings::MODE_AUTOMATIC;
+      zoom_settings->scope = api::tabs::ZoomSettings::SCOPE_PER_ORIGIN;
+      break;
+    case ZoomController::ZOOM_MODE_ISOLATED:
+      zoom_settings->mode = api::tabs::ZoomSettings::MODE_AUTOMATIC;
+      zoom_settings->scope = api::tabs::ZoomSettings::SCOPE_PER_TAB;
+      break;
+    case ZoomController::ZOOM_MODE_MANUAL:
+      zoom_settings->mode = api::tabs::ZoomSettings::MODE_MANUAL;
+      zoom_settings->scope = api::tabs::ZoomSettings::SCOPE_PER_TAB;
+      break;
+    case ZoomController::ZOOM_MODE_DISABLED:
+      zoom_settings->mode = api::tabs::ZoomSettings::MODE_DISABLED;
+      zoom_settings->scope = api::tabs::ZoomSettings::SCOPE_PER_TAB;
+      break;
+  }
+}
+
 // Windows ---------------------------------------------------------------------
 
 bool WindowsGetFunction::RunSync() {
@@ -181,7 +204,7 @@ bool WindowsGetFunction::RunSync() {
   }
 
   if (populate_tabs)
-    SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
+    SetResult(controller->CreateWindowValueWithTabs(extension()));
   else
     SetResult(controller->CreateWindowValue());
   return true;
@@ -203,7 +226,7 @@ bool WindowsGetCurrentFunction::RunSync() {
     return false;
   }
   if (populate_tabs)
-    SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
+    SetResult(controller->CreateWindowValueWithTabs(extension()));
   else
     SetResult(controller->CreateWindowValue());
   return true;
@@ -230,7 +253,7 @@ bool WindowsGetLastFocusedFunction::RunSync() {
   WindowController* controller =
       browser->extension_window_controller();
   if (populate_tabs)
-    SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
+    SetResult(controller->CreateWindowValueWithTabs(extension()));
   else
     SetResult(controller->CreateWindowValue());
   return true;
@@ -254,7 +277,7 @@ bool WindowsGetAllFunction::RunSync() {
     if (!this->CanOperateOnWindow(*iter))
       continue;
     if (populate_tabs)
-      window_list->Append((*iter)->CreateWindowValueWithTabs(GetExtension()));
+      window_list->Append((*iter)->CreateWindowValueWithTabs(extension()));
     else
       window_list->Append((*iter)->CreateWindowValue());
   }
@@ -332,8 +355,7 @@ bool WindowsCreateFunction::RunSync() {
     // Second, resolve, validate and convert them to GURLs.
     for (std::vector<std::string>::iterator i = url_strings.begin();
          i != url_strings.end(); ++i) {
-      GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
-          *i, GetExtension());
+      GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(*i, extension());
       if (!url.is_valid()) {
         error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, *i);
         return false;
@@ -392,15 +414,12 @@ bool WindowsCreateFunction::RunSync() {
     switch (create_data->type) {
       case windows::Create::Params::CreateData::TYPE_POPUP:
         window_type = Browser::TYPE_POPUP;
-        extension_id = GetExtension()->id();
+        extension_id = extension()->id();
         break;
       case windows::Create::Params::CreateData::TYPE_PANEL:
       case windows::Create::Params::CreateData::TYPE_DETACHED_PANEL: {
-        extension_id = GetExtension()->id();
-        bool use_panels = false;
-#if !defined(OS_ANDROID)
-        use_panels = PanelManager::ShouldUsePanels(extension_id);
-#endif
+        extension_id = extension()->id();
+        bool use_panels = PanelManager::ShouldUsePanels(extension_id);
         if (use_panels) {
           create_panel = true;
           // Non-ash supports both docked and detached panel types.
@@ -475,12 +494,12 @@ bool WindowsCreateFunction::RunSync() {
       create_params.window_type = AppWindow::WINDOW_TYPE_V1_PANEL;
       create_params.window_spec.bounds = window_bounds;
       create_params.focused = saw_focus_key && focused;
-      AppWindow* app_window = new AppWindow(
-          window_profile, new ChromeAppWindowDelegate(), GetExtension());
+      AppWindow* app_window =
+          new AppWindow(window_profile, new ChromeAppDelegate(), extension());
       AshPanelContents* ash_panel_contents = new AshPanelContents(app_window);
       app_window->Init(urls[0], ash_panel_contents, create_params);
-      SetResult(ash_panel_contents->GetExtensionWindowController()->
-                CreateWindowValueWithTabs(GetExtension()));
+      SetResult(ash_panel_contents->GetExtensionWindowController()
+                    ->CreateWindowValueWithTabs(extension()));
       return true;
     }
 #endif
@@ -496,9 +515,8 @@ bool WindowsCreateFunction::RunSync() {
     else
       panel->Show();
 
-    SetResult(
-        panel->extension_window_controller()->CreateWindowValueWithTabs(
-            GetExtension()));
+    SetResult(panel->extension_window_controller()->CreateWindowValueWithTabs(
+        extension()));
     return true;
   }
 
@@ -568,7 +586,7 @@ bool WindowsCreateFunction::RunSync() {
   } else {
     SetResult(
         new_window->extension_window_controller()->CreateWindowValueWithTabs(
-            GetExtension()));
+            extension()));
   }
 
   return true;
@@ -607,7 +625,7 @@ bool WindowsUpdateFunction::RunSync() {
 
   if (show_state != ui::SHOW_STATE_FULLSCREEN &&
       show_state != ui::SHOW_STATE_DEFAULT)
-    controller->SetFullscreenMode(false, GetExtension()->url());
+    controller->SetFullscreenMode(false, extension()->url());
 
   switch (show_state) {
     case ui::SHOW_STATE_MINIMIZED:
@@ -620,7 +638,7 @@ bool WindowsUpdateFunction::RunSync() {
       if (controller->window()->IsMinimized() ||
           controller->window()->IsMaximized())
         controller->window()->Restore();
-      controller->SetFullscreenMode(true, GetExtension()->url());
+      controller->SetFullscreenMode(true, extension()->url());
       break;
     case ui::SHOW_STATE_NORMAL:
       controller->window()->Restore();
@@ -736,10 +754,8 @@ bool TabsGetSelectedFunction::RunSync() {
     error_ = keys::kNoSelectedTabError;
     return false;
   }
-  SetResult(ExtensionTabUtil::CreateTabValue(contents,
-                                             tab_strip,
-                                             tab_strip->active_index(),
-                                             GetExtension()));
+  SetResult(ExtensionTabUtil::CreateTabValue(
+      contents, tab_strip, tab_strip->active_index(), extension()));
   return true;
 }
 
@@ -756,7 +772,7 @@ bool TabsGetAllInWindowFunction::RunSync() {
   if (!GetBrowserFromWindowID(this, window_id, &browser))
     return false;
 
-  SetResult(ExtensionTabUtil::CreateTabList(browser, GetExtension()));
+  SetResult(ExtensionTabUtil::CreateTabList(browser, extension()));
 
   return true;
 }
@@ -868,7 +884,7 @@ bool TabsQueryFunction::RunSync() {
         continue;
 
       result->Append(ExtensionTabUtil::CreateTabValue(
-          web_contents, tab_strip, i, GetExtension()));
+          web_contents, tab_strip, i, extension()));
     }
   }
 
@@ -943,8 +959,7 @@ bool TabsDuplicateFunction::RunSync() {
 
   // Return data about the newly created tab.
   SetResult(ExtensionTabUtil::CreateTabValue(
-      new_contents,
-      new_tab_strip, new_tab_index, GetExtension()));
+      new_contents, new_tab_strip, new_tab_index, extension()));
 
   return true;
 }
@@ -967,19 +982,20 @@ bool TabsGetFunction::RunSync() {
                   &error_))
     return false;
 
-  SetResult(ExtensionTabUtil::CreateTabValue(contents,
-                                             tab_strip,
-                                             tab_index,
-                                             GetExtension()));
+  SetResult(ExtensionTabUtil::CreateTabValue(
+      contents, tab_strip, tab_index, extension()));
   return true;
 }
 
 bool TabsGetCurrentFunction::RunSync() {
   DCHECK(dispatcher());
 
-  WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents();
-  if (contents)
-    SetResult(ExtensionTabUtil::CreateTabValue(contents, GetExtension()));
+  // Return the caller, if it's a tab. If not the result isn't an error but an
+  // empty tab (hence returning true).
+  WebContents* caller_contents =
+      WebContents::FromRenderViewHost(render_view_host());
+  if (caller_contents && ExtensionTabUtil::GetTabId(caller_contents) >= 0)
+    SetResult(ExtensionTabUtil::CreateTabValue(caller_contents, extension()));
 
   return true;
 }
@@ -1027,15 +1043,14 @@ bool TabsHighlightFunction::RunSync() {
 
   selection.set_active(active_index);
   browser->tab_strip_model()->SetSelectionFromModel(selection);
-  SetResult(
-      browser->extension_window_controller()->CreateWindowValueWithTabs(
-          GetExtension()));
+  SetResult(browser->extension_window_controller()->CreateWindowValueWithTabs(
+      extension()));
   return true;
 }
 
 bool TabsHighlightFunction::HighlightTab(TabStripModel* tabstrip,
                                          ui::ListSelectionModel* selection,
-                                         int *active_index,
+                                         intactive_index,
                                          int index) {
   // Make sure the index is in range.
   if (!tabstrip->ContainsIndex(index)) {
@@ -1160,8 +1175,8 @@ bool TabsUpdateFunction::RunAsync() {
 bool TabsUpdateFunction::UpdateURL(const std::string &url_string,
                                    int tab_id,
                                    bool* is_async) {
-  GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
-      url_string, GetExtension());
+  GURL url =
+      ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, extension());
 
   if (!url.is_valid()) {
     error_ = ErrorUtils::FormatErrorMessage(
@@ -1179,8 +1194,8 @@ bool TabsUpdateFunction::UpdateURL(const std::string &url_string,
   // we need to check host permissions before allowing them.
   if (url.SchemeIs(url::kJavaScriptScheme)) {
     content::RenderProcessHost* process = web_contents_->GetRenderProcessHost();
-    if (!GetExtension()->permissions_data()->CanAccessPage(
-            GetExtension(),
+    if (!extension()->permissions_data()->CanAccessPage(
+            extension(),
             web_contents_->GetURL(),
             web_contents_->GetURL(),
             tab_id,
@@ -1223,12 +1238,11 @@ void TabsUpdateFunction::PopulateResult() {
   if (!has_callback())
     return;
 
-  SetResult(ExtensionTabUtil::CreateTabValue(web_contents_, GetExtension()));
+  SetResult(ExtensionTabUtil::CreateTabValue(web_contents_, extension()));
 }
 
 void TabsUpdateFunction::OnExecuteCodeFinished(
     const std::string& error,
-    int32 on_page_id,
     const GURL& url,
     const base::ListValue& script_result) {
   if (error.empty())
@@ -1285,7 +1299,7 @@ bool TabsMoveFunction::RunSync() {
 }
 
 bool TabsMoveFunction::MoveTab(int tab_id,
-                               int *new_index,
+                               intnew_index,
                                int iteration,
                                base::ListValue* tab_values,
                                int* window_id) {
@@ -1357,10 +1371,7 @@ bool TabsMoveFunction::MoveTab(int tab_id,
 
       if (has_callback()) {
         tab_values->Append(ExtensionTabUtil::CreateTabValue(
-            web_contents,
-            target_tab_strip,
-            *new_index,
-            GetExtension()));
+            web_contents, target_tab_strip, *new_index, extension()));
       }
 
       return true;
@@ -1379,7 +1390,7 @@ bool TabsMoveFunction::MoveTab(int tab_id,
 
   if (has_callback()) {
     tab_values->Append(ExtensionTabUtil::CreateTabValue(
-        contents, source_tab_strip, *new_index, GetExtension()));
+        contents, source_tab_strip, *new_index, extension()));
   }
 
   return true;
@@ -1420,8 +1431,9 @@ bool TabsReloadFunction::RunSync() {
                     NULL,
                     &web_contents,
                     NULL,
-                    &error_))
-    return false;
+                    &error_)) {
+      return false;
+    }
   }
 
   if (web_contents->ShowingInterstitialPage()) {
@@ -1504,7 +1516,7 @@ WebContents* TabsCaptureVisibleTabFunction::GetWebContentsForID(int window_id) {
     return NULL;
   }
 
-  if (!GetExtension()->permissions_data()->CanCaptureVisiblePage(
+  if (!extension()->permissions_data()->CanCaptureVisiblePage(
           SessionID::IdForTab(contents), &error_)) {
     return NULL;
   }
@@ -1600,8 +1612,9 @@ void TabsDetectLanguageFunction::Observe(
     const content::NotificationDetails& details) {
   std::string language;
   if (type == chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED) {
-    const LanguageDetectionDetails* lang_det_details =
-        content::Details<const LanguageDetectionDetails>(details).ptr();
+    const translate::LanguageDetectionDetails* lang_det_details =
+        content::Details<const translate::LanguageDetectionDetails>(details)
+            .ptr();
     language = lang_det_details->adopted_language;
   }
 
@@ -1656,8 +1669,8 @@ bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage() {
   // NOTE: This can give the wrong answer due to race conditions, but it is OK,
   // we check again in the renderer.
   content::RenderProcessHost* process = contents->GetRenderProcessHost();
-  if (!GetExtension()->permissions_data()->CanAccessPage(
-          GetExtension(),
+  if (!extension()->permissions_data()->CanAccessPage(
+          extension(),
           contents->GetURL(),
           contents->GetURL(),
           execute_tab_id_,
@@ -1703,13 +1716,11 @@ bool TabsExecuteScriptFunction::ShouldInsertCSS() const {
 
 void TabsExecuteScriptFunction::OnExecuteCodeFinished(
     const std::string& error,
-    int32 on_page_id,
     const GURL& on_url,
     const base::ListValue& result) {
   if (error.empty())
     SetResult(result.DeepCopy());
-  ExecuteCodeInTabFunction::OnExecuteCodeFinished(error, on_page_id, on_url,
-                                                  result);
+  ExecuteCodeInTabFunction::OnExecuteCodeFinished(error, on_url, result);
 }
 
 bool ExecuteCodeInTabFunction::Init() {
@@ -1749,4 +1760,145 @@ bool TabsInsertCSSFunction::ShouldInsertCSS() const {
   return true;
 }
 
+content::WebContents* ZoomAPIFunction::GetWebContents(int tab_id) {
+  content::WebContents* web_contents = NULL;
+  if (tab_id != -1) {
+    // We assume this call leaves web_contents unchanged if it is unsuccessful.
+    GetTabById(tab_id,
+               GetProfile(),
+               include_incognito(),
+               NULL /* ignore Browser* output */,
+               NULL /* ignore TabStripModel* output */,
+               &web_contents,
+               NULL /* ignore int tab_index output */,
+               &error_);
+  } else {
+    Browser* browser = GetCurrentBrowser();
+    if (!browser)
+      error_ = keys::kNoCurrentWindowError;
+    else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, NULL))
+      error_ = keys::kNoSelectedTabError;
+  }
+  return web_contents;
+}
+
+bool TabsSetZoomFunction::RunAsync() {
+  scoped_ptr<tabs::SetZoom::Params> params(
+      tabs::SetZoom::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  int tab_id = params->tab_id ? *params->tab_id : -1;
+  WebContents* web_contents = GetWebContents(tab_id);
+  if (!web_contents)
+    return false;
+
+  GURL url(web_contents->GetVisibleURL());
+  if (PermissionsData::IsRestrictedUrl(url, url, extension(), &error_))
+    return false;
+
+  ZoomController* zoom_controller =
+      ZoomController::FromWebContents(web_contents);
+  double zoom_level = content::ZoomFactorToZoomLevel(params->zoom_factor);
+
+  if (!zoom_controller->SetZoomLevelByExtension(zoom_level, extension())) {
+    // Tried to zoom a tab in disabled mode.
+    error_ = keys::kCannotZoomDisabledTabError;
+    return false;
+  }
+
+  SendResponse(true);
+  return true;
+}
+
+bool TabsGetZoomFunction::RunAsync() {
+  scoped_ptr<tabs::GetZoom::Params> params(
+      tabs::GetZoom::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  int tab_id = params->tab_id ? *params->tab_id : -1;
+  WebContents* web_contents = GetWebContents(tab_id);
+  if (!web_contents)
+    return false;
+
+  double zoom_level =
+      ZoomController::FromWebContents(web_contents)->GetZoomLevel();
+  double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level);
+  results_ = tabs::GetZoom::Results::Create(zoom_factor);
+  SendResponse(true);
+  return true;
+}
+
+bool TabsSetZoomSettingsFunction::RunAsync() {
+  using api::tabs::ZoomSettings;
+
+  scoped_ptr<tabs::SetZoomSettings::Params> params(
+      tabs::SetZoomSettings::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  int tab_id = params->tab_id ? *params->tab_id : -1;
+  WebContents* web_contents = GetWebContents(tab_id);
+  if (!web_contents)
+    return false;
+
+  GURL url(web_contents->GetVisibleURL());
+  if (PermissionsData::IsRestrictedUrl(url, url, extension(), &error_))
+    return false;
+
+  // "per-origin" scope is only available in "automatic" mode.
+  if (params->zoom_settings.scope == ZoomSettings::SCOPE_PER_ORIGIN &&
+      params->zoom_settings.mode != ZoomSettings::MODE_AUTOMATIC &&
+      params->zoom_settings.mode != ZoomSettings::MODE_NONE) {
+    error_ = keys::kPerOriginOnlyInAutomaticError;
+    return false;
+  }
+
+  // Determine the correct internal zoom mode to set |web_contents| to from the
+  // user-specified |zoom_settings|.
+  ZoomController::ZoomMode zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
+  switch (params->zoom_settings.mode) {
+    case ZoomSettings::MODE_NONE:
+    case ZoomSettings::MODE_AUTOMATIC:
+      switch (params->zoom_settings.scope) {
+        case ZoomSettings::SCOPE_NONE:
+        case ZoomSettings::SCOPE_PER_ORIGIN:
+          zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
+          break;
+        case ZoomSettings::SCOPE_PER_TAB:
+          zoom_mode = ZoomController::ZOOM_MODE_ISOLATED;
+      }
+      break;
+    case ZoomSettings::MODE_MANUAL:
+      zoom_mode = ZoomController::ZOOM_MODE_MANUAL;
+      break;
+    case ZoomSettings::MODE_DISABLED:
+      zoom_mode = ZoomController::ZOOM_MODE_DISABLED;
+  }
+
+  ZoomController::FromWebContents(web_contents)->SetZoomMode(zoom_mode);
+
+  SendResponse(true);
+  return true;
+}
+
+bool TabsGetZoomSettingsFunction::RunAsync() {
+  scoped_ptr<tabs::GetZoomSettings::Params> params(
+      tabs::GetZoomSettings::Params::Create(*args_));
+  EXTENSION_FUNCTION_VALIDATE(params);
+
+  int tab_id = params->tab_id ? *params->tab_id : -1;
+  WebContents* web_contents = GetWebContents(tab_id);
+  if (!web_contents)
+    return false;
+  ZoomController* zoom_controller =
+      ZoomController::FromWebContents(web_contents);
+
+  ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode();
+  api::tabs::ZoomSettings zoom_settings;
+  ZoomModeToZoomSettings(zoom_mode, &zoom_settings);
+
+  results_ = api::tabs::GetZoomSettings::Results::Create(zoom_settings);
+  SendResponse(true);
+  return true;
+}
+
 }  // namespace extensions