// Copyright (c) 2010 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. // // Implementations for common functions for various API implementation modules. #include "ceee/ie/broker/common_api_module.h" #include <atlbase.h> #include <atlcom.h> // Must be included AFTER base. #include "base/string_number_conversions.h" #include "ceee/ie/broker/api_module_constants.h" #include "ceee/ie/broker/tab_api_module.h" #include "ceee/ie/common/ie_util.h" #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/common/extensions/extension_error_utils.h" #include "ceee/common/com_utils.h" #include "ceee/common/window_utils.h" #include "ceee/common/windows_constants.h" namespace ext = extension_tabs_module_constants; namespace common_api { bool CommonApiResult::IsTabWindowClass(HWND window) { return window_utils::IsWindowClass(window, windows::kIeTabWindowClass); } bool CommonApiResult::IsIeFrameClass(HWND window) { return window_utils::IsWindowClass(window, windows::kIeFrameWindowClass); } HWND CommonApiResult::TopIeWindow() { HWND window = NULL; if (window_utils::FindDescendentWindow(NULL, windows::kIeFrameWindowClass, true, &window)) { return window; } NOTREACHED() << "How come we can't find a Top IE Window???"; return NULL; } void CommonApiResult::SetResultFromWindowInfo( HWND window, const CeeeWindowInfo& window_info, bool populate_tabs) { scoped_ptr<DictionaryValue> dict(new DictionaryValue()); ApiDispatcher* dispatcher = GetDispatcher(); DCHECK(dispatcher != NULL); int window_id = dispatcher->GetWindowIdFromHandle(window); dict->SetInteger(ext::kIdKey, window_id); dict->SetBoolean(ext::kFocusedKey, window_info.focused != FALSE); dict->SetInteger(ext::kLeftKey, window_info.rect.left); dict->SetInteger(ext::kTopKey, window_info.rect.top); dict->SetInteger(ext::kWidthKey, window_info.rect.right - window_info.rect.left); dict->SetInteger(ext::kHeightKey, window_info.rect.bottom - window_info.rect.top); if (populate_tabs) { DCHECK(window_info.tab_list != NULL); Value* tab_list_value = CreateTabList(window_info.tab_list); // DCHECK yet continue if we get a NULL tab list since we may get here // before it is available. DCHECK(tab_list_value != NULL); if (!tab_list_value) tab_list_value = Value::CreateNullValue(); dict->Set(ext::kTabsKey, tab_list_value); } dict->SetBoolean(ext::kIncognitoKey, ie_util::GetIEIsInPrivateBrowsing()); // TODO(mad@chromium.org): for now, always setting to "normal" since we don't // yet have a way to tell if the window is a popup or not. dict->SetString(ext::kWindowTypeKey, ext::kWindowTypeValueNormal); DCHECK(value_ == NULL); value_.reset(dict.release()); } Value* CommonApiResult::CreateTabList(BSTR tab_list) { // No need for a request_id. tab_api::GetAllTabsInWindowResult result(kNoRequestId); result.Execute(tab_list); const Value* tab_list_value = result.value(); // No DCHECK as this will happen if we try to update a window // that has been closed. if (tab_list_value) { return tab_list_value->DeepCopy(); } LOG(WARNING) << "Can't get info for tab_ids: '" << tab_list << "'."; return NULL; } bool CommonApiResult::CreateWindowValue(HWND window, bool populate_tabs) { ApiDispatcher* dispatcher = GetDispatcher(); DCHECK(dispatcher != NULL); int window_id = dispatcher->GetWindowIdFromHandle(window); if (window_utils::WindowHasNoThread(window)) { PostError(ExtensionErrorUtils::FormatErrorMessage( ext::kWindowNotFoundError, base::IntToString(window_id))); return false; } if (!IsIeFrameClass(window)) { PostError(ExtensionErrorUtils::FormatErrorMessage( ext::kWindowNotFoundError, base::IntToString(window_id))); return false; } CComPtr<ICeeeWindowExecutor> executor; dispatcher->GetExecutor(window, IID_ICeeeWindowExecutor, reinterpret_cast<void**>(&executor)); if (executor == NULL) { LOG(WARNING) << "Failed to get an executor to get window info."; PostError(api_module_constants::kInternalErrorError); return false; } common_api::WindowInfo window_info; HRESULT hr = executor->GetWindow(populate_tabs, &window_info); if (FAILED(hr)) { // No DCHECK, this may happen if the window/thread dies on the way. LOG(ERROR) << "Can't get info for window: " << std::hex << window << ". " << com::LogHr(hr); PostError(api_module_constants::kInternalErrorError); return false; } SetResultFromWindowInfo(window, window_info, populate_tabs); return true; } WindowInfo::WindowInfo() { focused = FALSE; rect.bottom = -1; rect.top = -1; rect.left = -1; rect.right = -1; tab_list = NULL; } WindowInfo::~WindowInfo() { // SysFreeString accepts NULL pointers. ::SysFreeString(tab_list); } } // namespace common_api