diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/accessibility/browser_impl.cc | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_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.cc | 551 |
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(¶ms, 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, ¶ms, &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, ¶ms, &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_--; + } + } +} |