summaryrefslogtreecommitdiffstats
path: root/chrome/test/accessibility/browser_impl.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/accessibility/browser_impl.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/accessibility/browser_impl.cc')
-rw-r--r--chrome/test/accessibility/browser_impl.cc551
1 files changed, 551 insertions, 0 deletions
diff --git a/chrome/test/accessibility/browser_impl.cc b/chrome/test/accessibility/browser_impl.cc
new file mode 100644
index 0000000..50eb9f7
--- /dev/null
+++ b/chrome/test/accessibility/browser_impl.cc
@@ -0,0 +1,551 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/test/accessibility/browser_impl.h"
+
+#include <shellapi.h>
+
+#include "chrome/test/accessibility/accessibility_util.h"
+#include "chrome/test/accessibility/keyboard_util.h"
+#include "chrome/test/accessibility/registry_util.h"
+
+bool CBrowserImpl::Launch(void) {
+ // TODO: Check if chrome already running.
+ BSTR chrome_path = SysAllocString(GetChromeExePath());
+ BOOL bool_return = FALSE;
+
+ // Initialize and fill up structure.
+ SHELLEXECUTEINFO shell_execute_info;
+ memset(&shell_execute_info, 0, sizeof(SHELLEXECUTEINFO));
+ shell_execute_info.cbSize = sizeof(SHELLEXECUTEINFO);
+ // To get Process handle.
+ shell_execute_info.fMask = SEE_MASK_NOCLOSEPROCESS;
+ shell_execute_info.nShow = SW_SHOW;
+ shell_execute_info.lpFile =
+ reinterpret_cast<TCHAR*>(malloc(sizeof(TCHAR) *
+ SysStringLen(chrome_path)));
+ _tcscpy_s((TCHAR*)(shell_execute_info.lpFile), SysStringLen(chrome_path),
+ chrome_path);
+
+ // Execute.
+ bool_return = ShellExecuteEx(&shell_execute_info);
+
+ if (bool_return &&
+ (INT64(shell_execute_info.hInstApp) > 32) ) {
+ // TODO: Maintain instance and process handle.
+
+ // Maintain active tab index.
+ SetActiveTabIndex(1);
+
+ // Create initial tab collection.
+ UpdateTabCollection();
+
+ // Chrome launched.
+ return true;
+ }
+
+ return false;
+}
+
+bool CBrowserImpl::Quit(void) {
+ // Cleanup.
+ EraseTabCollection();
+
+ // Send close message to browser window.
+ HWND hwnd = GetChromeBrowserWnd(NULL);
+ if (!hwnd)
+ return false;
+ SendMessage(hwnd, WM_CLOSE, 0, 0);
+ return true;
+}
+
+bool CBrowserImpl::ActivateTab(const INT64 index) {
+ // Validate index specified.
+ if (index < 1) {
+ return false;
+ }
+
+ // Goto next tab till focused at desired tab.
+ // TODO: Change implementation when DoDefaultAction() for Tab is exported.
+ while (active_tab_index_ != index) {
+ GoToNextTab(NULL);
+ }
+ return true;
+}
+
+bool CBrowserImpl::GetActiveTabURL(BSTR* url) {
+ // Validate input.
+ if (!url)
+ return false;
+
+ // TODO: Implement.
+ return true;
+}
+
+bool CBrowserImpl::GetActiveTabTitle(BSTR* title) {
+ if (!title)
+ return false;
+
+ BSTR tab_title = SysAllocString(GetTabName(active_tab_index_));
+ *title = SysAllocString(tab_title);
+ return true;
+}
+
+bool CBrowserImpl::GetActiveTabIndex(INT64* index) {
+ if (!index)
+ return false;
+
+ *index = active_tab_index_;
+ return true;
+}
+
+void CBrowserImpl::SetActiveTabIndex(INT64 index) {
+ if ((index >= MIN_TAB_INDEX_DIGIT) && (index <= GetTabCnt()))
+ active_tab_index_ = index;
+ return;
+}
+
+bool CBrowserImpl::GetActiveTab(CTabImpl** tab) {
+ return GetTab(active_tab_index_, tab);
+}
+
+bool CBrowserImpl::GetTabCount(INT64* count) {
+ if (!count)
+ return false;
+
+ *count = GetTabCnt();
+ return true;
+}
+
+bool CBrowserImpl::GetBrowserProcessCount(INT64* count) {
+ if (!count)
+ return false;
+
+ // TODO: Add your implementation code here
+
+ return true;
+}
+
+bool CBrowserImpl::GetBrowserTitle(BSTR* title) {
+ if (!title)
+ return false;
+
+ HWND hwnd = GetChromeBrowserWnd(NULL);
+ if (!hwnd)
+ return false;
+
+ int text_length = GetWindowTextLength(hwnd);
+ *title = SysAllocStringLen(NULL, text_length);
+ GetWindowText(hwnd, *title, text_length);
+ return true;
+}
+
+bool CBrowserImpl::AddTab(CTabImpl** tab) {
+ // Add new tab.
+ HWND hwnd = GetChromeBrowserWnd(NULL);
+ if (!hwnd)
+ return false;
+ ClickKey(hwnd, VK_CONTROL, 'T');
+
+ // Update active tab index.
+ INT64 new_tab_index = GetTabCnt();
+ if (-1 == new_tab_index)
+ return false;
+ SetActiveTabIndex(new_tab_index);
+
+ // Fill object.
+ CTabImpl *new_tab = new CTabImpl();
+ if (!new_tab)
+ return false;
+ ChromeTab* tab_data = new_tab->InitTabData();
+ new_tab->PutIndex(new_tab_index);
+ new_tab->PutTitle(GetTabName(new_tab_index));
+ new_tab->SetBrowser(this);
+
+ // Update tab collection.
+ tab_collection_.push_back(tab_data);
+
+ // Create tab object, if requested.
+ if (tab)
+ *tab = new_tab;
+
+ return true;
+}
+
+bool CBrowserImpl::GetTab(const INT64 index, CTabImpl** tab) {
+ // Create tab object, if requested.
+ if (!tab)
+ return false;
+
+ if (index > GetTabCnt())
+ return false;
+
+ *tab = new CTabImpl();
+ if (!*tab)
+ return false;
+
+ // Fill object.
+ ChromeTab* tab_data = (*tab)->InitTabData();
+ (*tab)->PutIndex(index);
+ (*tab)->PutTitle(GetTabName(index));
+ (*tab)->SetBrowser(this);
+
+ return true;
+}
+
+bool CBrowserImpl::GoToTab(const INT64 index, CTabImpl** tab) {
+ // Validate input.
+ if (index > MAX_TAB_INDEX_DIGIT)
+ return false;
+
+ // Stay on current tab, if index doesnot exist.
+ if ((0 == index) || (GetTabCnt() < index))
+ return true;
+
+ // Move to a tab (indexed 1 to 9).
+ IAccessible *pi_access = NULL;
+ HWND hwnd = GetChromeBrowserWnd(&pi_access);
+ if (pi_access && hwnd) {
+ // Activate main window and operate key Ctrl+digit.
+ ActivateWnd(pi_access, hwnd);
+ ClickKey(hwnd, VK_CONTROL, WORD('0'+index));
+ CHK_RELEASE(pi_access);
+
+ // Set focused tab index.
+ active_tab_index_ = index;
+ // Return tab object.
+ if (tab) {
+ return GetTab(active_tab_index_, tab);
+ }
+ }
+
+ return false;
+}
+
+bool CBrowserImpl::GoToNextTab(CTabImpl** tab) {
+ IAccessible *pi_access = NULL;
+ HWND hwnd = GetChromeBrowserWnd(&pi_access);
+ if (pi_access && hwnd) {
+ // Activate main window and operate key Ctrl+Tab.
+ ActivateWnd(pi_access, hwnd);
+ ClickKey(hwnd, VK_CONTROL, VK_TAB);
+ CHK_RELEASE(pi_access);
+
+ // Set focused tab index.
+ if (active_tab_index_ == GetTabCnt()) {
+ active_tab_index_ = 1;
+ } else {
+ active_tab_index_ = active_tab_index_ + 1;
+ }
+
+ // Return tab object.
+ if (tab) {
+ return GetTab(active_tab_index_, tab);
+ }
+ }
+
+ return false;
+}
+
+bool CBrowserImpl::GoToPrevTab(CTabImpl** tab) {
+ IAccessible *pi_access = NULL;
+ HWND hwnd = GetChromeBrowserWnd(&pi_access);
+ if (pi_access && hwnd) {
+ // Activate main window and operate key Ctrl+Tab.
+ ActivateWnd(pi_access, hwnd);
+ ClickKey(hwnd, VK_SHIFT, VK_CONTROL, VK_TAB);
+ CHK_RELEASE(pi_access);
+
+ // Set focused tab index.
+ if (active_tab_index_ == 1) {
+ active_tab_index_ = GetTabCnt();
+ } else {
+ active_tab_index_ = active_tab_index_ - 1;
+ }
+
+ // Return tab object.
+ if (tab) {
+ return GetTab(active_tab_index_, tab);
+ }
+ }
+
+ return false;
+}
+
+bool CBrowserImpl::WaitForChromeToBeVisible(const INT64 interval,
+ const INT64 timeout,
+ bool* visible) {
+ IAccessible *pi_access = NULL;
+ INT64 time_elapsed = 0;
+ *visible = false;
+
+ // Check and wait.
+ while (timeout >= time_elapsed) {
+ GetTabStripWnd(&pi_access);
+ if (pi_access) {
+ *visible = true;
+ CHK_RELEASE(pi_access);
+ return true;
+ }
+ Sleep(DWORD(interval));
+ time_elapsed = time_elapsed + interval;
+ }
+
+ return false;
+}
+
+bool CBrowserImpl::WaitForTabCountToChange(const INT64 interval,
+ const INT64 timeout,
+ bool* changed) {
+ // TODO: Add your implementation code here
+
+ return true;
+}
+
+bool CBrowserImpl::WaitForTabToBecomeActive(const INT64 index,
+ const INT64 interval,
+ const INT64 timeout,
+ bool* activated) {
+ // TODO: Add your implementation code here
+
+ return true;
+}
+
+bool CBrowserImpl::ApplyAccelerator(VARIANT keys) {
+ // Input should be -array of enum or strings
+ // or -IDispatch (jscript array object).
+ if ((keys.vt != (VT_ARRAY|VT_BSTR)) && // Array of string values.
+ (keys.vt != (VT_ARRAY|VT_I4)) && // Array of enum values.
+ (!(keys.vt & VT_DISPATCH)) ) { // Object.
+ return false;
+ }
+
+ // Array to store keys in a single combination. Currently, valid keyboard
+ // -input combination can constitute of at the most 3 keys.
+ KEYBD_KEYS key_value[3];
+ // Initialize key count.
+ int key_cnt = 0;
+ // Get variant array from object.
+ IDispatch *disp = NULL;
+
+ // Not array of string values or integers.
+ if ((keys.vt != (VT_ARRAY|VT_BSTR)) &&
+ (keys.vt != (VT_ARRAY|VT_I4)) ) {
+ // Retrive IDispatch.
+ if (keys.vt & VT_BYREF)
+ disp = *(keys.ppdispVal);
+ else
+ disp = keys.pdispVal;
+
+ // Get array length.
+ DISPPARAMS params;
+ FillMemory(&params, sizeof(DISPPARAMS), 0);
+ VARIANT res;
+ DISPID id;
+ LPOLESTR ln = L"length";
+ if (S_OK != disp->GetIDsOfNames(IID_NULL, &ln, 1, LOCALE_USER_DEFAULT,
+ &id)) {
+ return false;
+ }
+
+ if (S_OK != disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT,
+ DISPATCH_PROPERTYGET, &params, &res, NULL,
+ NULL)) {
+ return false;
+ }
+
+ VARIANT len;
+ VariantInit(&len);
+ VariantChangeType(&len, &res, 0, VT_I4);
+ if (len.lVal > 3)
+ return false;
+ key_cnt = len.lVal;
+
+ // Add elements to safe array.
+ for (int i = 0; i < len.lVal; i++) {
+ // Fetch element.
+ wchar_t wstr[5];
+ memset(wstr, 0, 5*sizeof(wchar_t));
+ wsprintf(wstr, L"%d", i);
+ LPOLESTR olestr = wstr;
+
+ if (S_OK != disp->GetIDsOfNames(IID_NULL, &olestr, 1,
+ LOCALE_USER_DEFAULT, &id)) {
+ return false;
+ }
+
+ if (S_OK != disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT,
+ DISPATCH_PROPERTYGET, &params, &res, NULL,
+ NULL)) {
+ return false;
+ }
+
+ VARIANT value;
+ VariantInit(&value);
+ VariantChangeType(&value, &res, 0, VT_BSTR);
+
+ // Translate and add key to array.
+ key_value[i] = GetKeybdKeysVal(value.bstrVal);
+
+ VariantClear(&value);
+ }
+
+ VariantClear(&len);
+ } else {
+ // Directly fetch array.
+ SAFEARRAY *key_safe = NULL;
+ key_safe = V_ARRAY(&keys);
+
+ // Operate on Variant Array.
+ HRESULT hr = S_OK;
+ LONG cElements, lLBound, lUBound;
+
+ // Array is not 1-dimentional.
+ if (SafeArrayGetDim(key_safe) != 1)
+ return false;
+
+ // Get array bounds.
+ hr = SafeArrayGetLBound(key_safe, 1, &lLBound);
+ if (S_OK !=hr)
+ return false;
+ hr = SafeArrayGetUBound(key_safe, 1, &lUBound);
+ if (S_OK !=hr)
+ return false;
+
+ // Key combination can be of maximum 3 keys.
+ cElements = lUBound-lLBound+1;
+ if (cElements > 3)
+ return false;
+ key_cnt = cElements;
+
+ // Read the data in array.
+ if (keys.vt == (VT_ARRAY|VT_I4)) {
+ KEYBD_KEYS *read_keys;
+ hr = SafeArrayAccessData(key_safe,
+ reinterpret_cast<void **>(&read_keys));
+ if (S_OK !=hr)
+ return false;
+ for (int i = 0; i < cElements; i++) {
+ key_value[i] = read_keys[i];
+ }
+ } else if (keys.vt == (VT_ARRAY|VT_BSTR)) {
+ BSTR *key_str_value;
+ hr = SafeArrayAccessData(key_safe,
+ reinterpret_cast<void **>(&key_str_value));
+ if (S_OK !=hr)
+ return false;
+
+ // Translate and add key to array.
+ for (int i = 0; i < cElements; i++) {
+ key_value[i] = GetKeybdKeysVal(key_str_value[i]);
+ }
+ }
+ }
+
+ // Focus on main window and operate keys.
+ IAccessible *pi_access = NULL;
+ HWND hwnd = GetChromeBrowserWnd(&pi_access);
+ if (pi_access || hwnd)
+ ActivateWnd(pi_access, hwnd);
+
+ if (1 == key_cnt)
+ ClickKey(hwnd, key_value[0]);
+ else if (2 == key_cnt)
+ ClickKey(hwnd, key_value[0], key_value[1]);
+ else if (3 == key_cnt)
+ ClickKey(hwnd, key_value[0], key_value[1], key_value[2]);
+
+ CHK_RELEASE(pi_access);
+
+ return true;
+}
+
+void CBrowserImpl::UpdateTabCollection(void) {
+ // Get tab count and browser title.
+ INT64 tab_cnt = GetTabCnt();
+ BSTR browser_title;
+ GetBrowserTitle(&browser_title);
+
+ // Check tab-collection size and no. of existing tabs,
+ // work accordingly.
+
+ // First time creation
+ if (0 == tab_collection_.size()) {
+ EraseTabCollection();
+ for (int i = 0; i < tab_cnt; i++) {
+ tab_collection_[i]->index_ = i + 1;
+ tab_collection_[i]->title_ =
+ SysAllocString(GetTabName(tab_collection_[i]->index_));
+ if (browser_title == tab_collection_[i]->title_) {
+ active_tab_index_ = tab_collection_[i]->index_;
+ }
+ }
+ }
+
+ // TODO: If tabs are swapped.
+ // Add implementation here.
+}
+
+void CBrowserImpl::EraseTabCollection(void) {
+ std::vector<ChromeTab*>::iterator tab_iterator;
+ for (tab_iterator = tab_collection_.begin();
+ tab_iterator != tab_collection_.end();
+ tab_iterator++) {
+ // Relese memory used for data.
+ CHK_DELETE(*tab_iterator);
+ }
+ tab_collection_.clear();
+}
+
+void CBrowserImpl::CloseTabFromCollection(INT64 index) {
+ std::vector <ChromeTab*>::size_type collection_size = tab_collection_.size();
+ // Validate tab index.
+ if ((index < MIN_TAB_INDEX_DIGIT) ||
+ (static_cast<unsigned int>(index) > collection_size) )
+ return;
+
+ // Index starts from 1.
+ tab_collection_.erase(tab_collection_.begin() + static_cast<int>(index) - 1);
+
+ // Now update tab collection data.
+ collection_size = tab_collection_.size();
+
+ // Check if tab deleted is last tab.
+ if (index-1 == collection_size) {
+ // Change active tab index, only if tab deleted is last tab.
+ active_tab_index_ = index - 1;
+ } else {
+ for (std::vector <ChromeTab*>::size_type i =
+ static_cast<unsigned int>(index) - 1;
+ i < collection_size;
+ i++) {
+ tab_collection_[i]->index_--;
+ }
+ }
+}