void CaffeineClientHandler::OnLoadEnd(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    int httpStatusCode)
{
    REQUIRE_UI_THREAD();

    if ( browser->GetIdentifier() != 1 ) // NOT MAIN
    {
        //  TODO:  the ids should probably move to OnWebkitInitialized and the
        //  TODO:  startStub2() call should be moved to the JS.
        frame->ExecuteJavaScript(
                                 "browserID='" + uuid.ToString() + "';"
                                 "IPC_id='" + uuid.ToString() + "';"
                                 "myInitArg=unescape('"+ browserInitArg + "');"
                                 "window.startStub2 && startStub2();",
                                 frame->GetURL(),
                                 0
                                 );
    }
    if (m_BrowserId == browser->GetIdentifier() && frame->IsMain()) {
        // We've just finished loading a page
        SetLoading(false);
    }
}
Beispiel #2
0
bool ClientHandler::Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval, CefString& exception)
{
    if (name == "ChangeTextInJS") {
        if (arguments.size() == 1 && arguments[0]->IsString()) {
            CefString text = arguments[0]->GetStringValue();

            CefRefPtr<CefFrame> frame = this->GetBrowser()->GetMainFrame();

            std::string jscall = "ChangeText('";
            jscall += text;
            jscall += "');";

            frame->ExecuteJavaScript(jscall, frame->GetURL(), 0);

            /*
            * If you want your method to return a value, just use retval, like this:
            * retval = CefV8Value::CreateString("Hello World!");
            * you can use any CefV8Value, what means you can return arrays, objects or whatever you can create with CefV8Value::Create* methods
            */

            return true;
        }
    }

    return false;
}
Beispiel #3
0
// Inject webinos.js
// The file is loaded from the webinos\test\client folder if possible.
// If this fails, the current folder is used.
void ClientApp::InjectWebinos(CefRefPtr<CefFrame> frame)
{
  CefRefPtr<CefCommandLine> commandLine = AppGetCommandLine();

  // First try and load the platform-supplied webinos.js
  std::string pzpPath = AppGetWebinosWRTConfig(NULL,NULL);
  CefString wrtPath;

  // Make sure there is a trailing separator on the path.
  if (pzpPath.length() > 0) 
  {
    if (pzpPath.find_last_of('/') == pzpPath.length()-1 || pzpPath.find_last_of('\\') == pzpPath.length()-1)
      wrtPath = pzpPath + "wrt/webinos.js";
    else
      wrtPath = pzpPath + "/wrt/webinos.js";
  }

#if defined(OS_WIN)
  base::FilePath webinosJSPath(wrtPath.ToWString().c_str());
#else
  base::FilePath webinosJSPath(wrtPath);
#endif

  LOG(INFO) << "webinos.js path is " << wrtPath;

  int64 webinosJSCodeSize;
  bool gotJSFile = base::GetFileSize(webinosJSPath, &webinosJSCodeSize);
  if (gotJSFile)
  {
    char* webinosJSCode = new char[webinosJSCodeSize+1];
    base::ReadFile(webinosJSPath, webinosJSCode, webinosJSCodeSize);
    webinosJSCode[webinosJSCodeSize] = 0;

    if (frame == NULL)
    {
      // Register as a Cef extension.
      CefRegisterExtension("webinos", webinosJSCode, NULL);
    }
    else
    {
      // Run the code in the frame javascript context right now,
      // but only if the URL refers to the widget server.
      int widgetServerPort;
      AppGetWebinosWRTConfig(NULL,&widgetServerPort);

      char injectionCandidate[MAX_URL_LENGTH];
      sprintf(injectionCandidate,"http://localhost:%d",widgetServerPort);

      std::string url = frame->GetURL();
      if (url.substr(0,strlen(injectionCandidate)) == injectionCandidate)
        frame->ExecuteJavaScript(webinosJSCode, url, 0);
    }

    delete[] webinosJSCode;
  }
  else
  {
    	LOG(ERROR) << "Can't find webinos.js";
  }
}
bool RenderProcessHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                                    CefProcessId source_process,
                                                    CefRefPtr<CefProcessMessage> message) {
    const auto& messageName = message->GetName();
    if (messageName == "SignalEmit") {
        CefRefPtr<CefFrame> frame = browser->GetMainFrame();

        // [signalName: str, resultArray: jsonStr]
        const auto arguments = message->GetArgumentList();
        std::string exec = "onSignalEmit(\"" +
                           arguments->GetString(0).ToString() + "\", " +
                           arguments->GetString(1).ToString() + ");";
        LOG(INFO) << "EXEC " << exec;
        frame->ExecuteJavaScript(exec, frame->GetURL(), 0);
        return true;
    }

    if (messageName == "CallReturn") {
        CefRefPtr<CefFrame> frame = browser->GetMainFrame();

        // [callId: int, resultArray: jsonStr]
        const auto arguments = message->GetArgumentList();
        std::ostringstream exec;
        exec << "onCallReturn(" <<
        arguments->GetInt(0) << ", " <<
        arguments->GetString(1).ToString() << ");";
        LOG(INFO) << "EXEC " << exec.str();
        frame->ExecuteJavaScript(exec.str(), frame->GetURL(), 0);
        return true;
    }

    if (messageName == "CallFailed") {
        CefRefPtr<CefFrame> frame = browser->GetMainFrame();

        // [callId: int, resultArray: jsonStr]
        const auto arguments = message->GetArgumentList();
        std::ostringstream exec;
        exec << "onCallFailed(" <<
        arguments->GetInt(0) << ", " <<
        arguments->GetString(1).ToString() << ");";
        LOG(INFO) << "EXEC " << exec.str();
        frame->ExecuteJavaScript(exec.str(), frame->GetURL(), 0);
        return true;
    }

    return false;
}
void FCEFWebBrowserWindow::ExecuteJavascript(const FString& Script)
{
	if (IsValid())
	{
		CefRefPtr<CefFrame> frame = InternalCefBrowser->GetMainFrame();
		frame->ExecuteJavaScript(TCHAR_TO_UTF8(*Script), frame->GetURL(), 0);
	}
}
Beispiel #6
0
void CMainFrame::OnCefCallJavaScriptFunction()
{
  CCEFView *pView = CCEFView::GetView();
  CefRefPtr<CefBrowser> browser = pView->m_clientHandler->GetBrowser();
  CefRefPtr<CefFrame> frame = browser->GetMainFrame();
  CefPostTask(TID_UI, NewCefRunnableMethod(pView->m_clientHandler.get(), &ClientHandler::GetURL));
  frame->ExecuteJavaScript("foo();", "", 0);
  CefPostTask(TID_UI, NewCefRunnableMethod(pView->m_clientHandler.get(), &ClientHandler::JavaScriptTest));
}
Beispiel #7
0
void CTransChatWebWnd::ExecuteJavascript(const std::wstring& strCode)
{
	if (m_cWebClient.get())
	{
		CefRefPtr<CefFrame> frame = m_cWebClient->GetBrowser()->GetMainFrame();
		if (frame.get())
		{
			CefString strCode(strCode.c_str()), strUrl(L"");
			frame->ExecuteJavaScript(strCode, strUrl, 0);
		}
	}
}
void CaffeineClientHandler::CreateAndDispatchCustomEvent(const CefString &eventName, const CefString &obj)
{
    if (this->GetBrowser())
    {
        CefRefPtr<CefFrame> frame = this->GetBrowser()->GetMainFrame();
        if (frame.get() && frame->IsValid())
        {
            string jsCode =
                "var event = new CustomEvent(\"" + eventName.ToString() + "\", {bubbles: true, cancelable: true, detail: JSON.parse('" + obj.ToString() + "')});"
                "window.dispatchEvent(event);";
            frame->ExecuteJavaScript(jsCode, frame->GetURL(), 0);
        }
    }
}
Beispiel #9
0
void Application::runJavaScript( const std::string& js )
{
    // ToDo: call the cordova.xxxx JS functions directly via the context


    // if there is no _exposedJSObject do nothing
    if(_exposedJSObject.get())
    {
        //if (CefCurrentlyOn(TID_UI))
        {
            CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
            CefRefPtr<CefFrame> frame = context->GetFrame();
            frame->ExecuteJavaScript(js, frame->GetURL(), 0);
        }
        //else
        //{
        //  CefPostTask(TID_UI, NewCefRunnableMethod(this, &Application::runJavaScript, js));
        //}
    }
}
Beispiel #10
0
//
//  FUNCTION: MainWindowWndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
LRESULT CALLBACK MainWindowWndProc(
    HWND hWnd, 
    UINT message, 
    WPARAM wParam,
    LPARAM lParam) 
{
    PAINTSTRUCT ps;
    HDC hdc;
    HMENU sysMenu;

    // Callback for the main window
    switch (message) 
    {
        case WM_CREATE: 
        {
            DWORD bufferSize = 65535;
            wstring buff;
            buff.resize(bufferSize);
            bufferSize = ::GetEnvironmentVariable(L"lala", &buff[0], bufferSize);

            if (bufferSize)
            {
                buff.resize(bufferSize);
                SetEnvironmentVariable(L"lala", NULL);
            }

            // Add exit option to system menu
            TCHAR szDescription[INFOTIPSIZE];
            StringManager.LoadString(IDS_EXIT_CAFFEINE, szDescription, INFOTIPSIZE);

            sysMenu = GetSystemMenu(hWnd, FALSE);
            InsertMenu(sysMenu, 2, MF_SEPARATOR, 0, L"-");
            AppendMenu(sysMenu, MF_STRING, IDS_EXIT_CAFFEINE, szDescription);

            WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
            app->m_WindowHandler[mainUUID] = new CaffeineClientHandler();
            app->m_WindowHandler[mainUUID]->SetMainHwnd(hWnd);

            // Create the child windows used for navigation
            RECT rect;

            GetClientRect(hWnd, &rect);

            CefWindowInfo info;
            CefBrowserSettings browser_settings;
            browser_settings.universal_access_from_file_urls = STATE_ENABLED;
//            browser_settings.file_access_from_file_urls = STATE_ENABLED;
            browser_settings.web_security = STATE_DISABLED;
            browser_settings.local_storage = STATE_ENABLED;
            browser_settings.application_cache = STATE_DISABLED;
            browser_settings.javascript_open_windows = STATE_DISABLED;
//            browser_settings.accelerated_compositing = STATE_DISABLED;
            
            // Initialize window info to the defaults for a child window
            info.SetAsChild(hWnd, rect);

            // Create the new child browser window
            wstring URL(L"file:///stub.html?" + AppGetCommandLine()->GetSwitchValue("querystring").ToWString());
            if (AppGetCommandLine()->HasSwitch("yid"))
            {
                URL += L"&yid=" + ExtractYID(AppGetCommandLine()->GetSwitchValue("yid").ToWString());
            }
            //  TODO:  Can we just use the same window handler (assuming we get rid of the globals and add some sync)?
            CefRefPtr<CefBrowser> browser = CefBrowserHost::CreateBrowserSync(info, app->m_WindowHandler[mainUUID].get(), URL, browser_settings, NULL);
            app->m_WindowHandler[mainUUID]->m_MainBrowser = browser;
            mainWinBrowser = browser;

            app->hwndRender = hWnd; // setup current handle to use in Show/HideWindow
        
            CefRefPtr<CefProcessMessage> process_message = CefProcessMessage::Create("setHandle");
            process_message->GetArgumentList()->SetInt(0, reinterpret_cast<int>(hWnd));
            browser->SendProcessMessage(PID_RENDERER, process_message);

            // Send the main window creation start time to the renderer
            process_message = CefProcessMessage::Create("mainWindowCreationTime");
            CefRefPtr<CefBinaryValue> startTime = CefBinaryValue::Create(&beginMainWindowCreationTime, sizeof(CefTime));
            process_message->GetArgumentList()->SetBinary(0, startTime);
            browser->SendProcessMessage(PID_RENDERER, process_message);

            if (bufferSize)
            {
                process_message = CefProcessMessage::Create("lala");
                process_message->GetArgumentList()->SetString(0, buff);
                browser->SendProcessMessage(PID_RENDERER, process_message);
            }

            SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(new WindowExtras));

            SetTimer(hWnd, IDLETIMER, IdleTimerPollIntervalMS, NULL);
            SetTimer(hWnd, NETWORKTIMER, NetworkTimerPollIntervalMS, NULL);

            return 0;
        }

        case WM_MOVE:
            if (app->m_WindowHandler[mainUUID].get())
            {
                //  TODO:  Below is a hack to work around the fact that CEF isn't updating screenX and screenY.  Periodically,
                //  TODO:  check to see if they fix it.  
                //  TODO:  See issue https://code.google.com/p/chromiumembedded/issues/detail?id=1303&thanks=1303&ts=1402082749
                WINDOWINFO wi = {sizeof(WINDOWINFO), 0};
                GetWindowInfo(hWnd, &wi);
                RECT rClient = wi.rcWindow;

                CefString JS = "window.screenLeft = window.screenX = " + to_string(_Longlong(rClient.left)) + "; window.screenTop = window.screenY = " + 
                    to_string(_Longlong(rClient.top)) + ";";
                CefRefPtr<CefFrame> frame = app->m_WindowHandler[mainUUID]->GetBrowser()->GetMainFrame();
                frame->ExecuteJavaScript(JS, frame->GetURL(), 0);

                //  TODO:  Another workaround.  For whatever reason, the window positions get updated when the size changes,
                //  TODO:  but not when the window is moved.
                CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) 
                {
                    wi.cbSize = sizeof(WINDOWINFO);
                    GetWindowInfo(hwnd, &wi);
                    RECT rWindow = wi.rcWindow;

                    MoveWindow(hwnd, 0, 0, rWindow.right - rWindow.left, rWindow.bottom - rWindow.top + 1, FALSE);
                    MoveWindow(hwnd, 0, 0, rWindow.right - rWindow.left, rWindow.bottom - rWindow.top, FALSE);
                }

                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent("move");
            }

            break;

        case WM_POWERBROADCAST:
            if (app->m_WindowHandler[mainUUID].get())
            {
                if (wParam == PBT_APMRESUMEAUTOMATIC || wParam == PBT_APMSUSPEND)
                {
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(wParam == PBT_APMSUSPEND? "suspend" : "resume");
                    //  Do we really need a return value?
                    return TRUE;
                }
            }
            break;

        case WM_WTSSESSION_CHANGE:
            if (app->m_WindowHandler[mainUUID].get())
            {
                string eventName;

                switch(wParam)
                {
                    //  Used
                    case WTS_SESSION_LOGON:
                        eventName = "os:logon";
                        break;
                    //  Used
                    case WTS_SESSION_LOGOFF:
                        eventName = "os:logoff";
                        break;
                    //  Used
                    case WTS_SESSION_LOCK:
                        eventName = "os:locked";
                        break;
                    //  Used
                    case WTS_SESSION_UNLOCK:
                        eventName = "os:unlocked";
                        break;
                }

                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(eventName);
            }
            break;

        case WM_PAINT:
            {
                //RECT cr = {0,};
                //::GetClientRect(hWnd, &cr);
                //::InvalidateRect(hWnd, &cr, FALSE);
                hdc = BeginPaint(hWnd, &ps);
                EndPaint(hWnd, &ps);
                return 0;
            }

        case WM_ACTIVATE:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent((LOWORD(wParam)>0)? "activated" : "deactivated");
            }
            break;
        case WM_SETFOCUS:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                // Pass focus to the browser window
                CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) PostMessage(hwnd, message, wParam, lParam);
            }
            return 0;

        case WM_SIZE:
            // Minimizing resizes the window to 0x0 which causes our layout to go all
            // screwy, so we just ignore it.
            if (wParam != SIZE_MINIMIZED && app->m_WindowHandler[mainUUID].get() && 
                app->m_WindowHandler[mainUUID]->GetBrowser()) 
            {
                    CefWindowHandle hwnd = app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                    if (hwnd) 
                    {
                        //  This will send a WM_SIZE and WM_PAINT message to the render process
                        SetWindowPos(hwnd, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); 
                        return 0;
                    }
            }
            break;

        case WM_ERASEBKGND:
            if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) {
                CefWindowHandle hwnd =
                    app->m_WindowHandler[mainUUID]->GetBrowser()->GetHost()->GetWindowHandle();
                if (hwnd) {
                    // Dont erase the background if the browser window has been loaded
                    // (this avoids flashing)
                    return 0;
                }
            }
            break;

        case WM_SYSCOMMAND:
            if (wParam == IDS_EXIT_CAFFEINE) {
                PostMessage(hWnd, WM_CLOSE, g_exitCode, 0);
                return 0;
            }
            break;

        case WM_COMMAND:
            // Currently only option from the context menu is to exit, hence the fall through to the WM_CLOSE
            wParam = g_exitCode;

        case WM_CLOSE:
        {
            if (devMode || enableClose)
            {
                wParam = g_exitCode;
            }

            CefRefPtr<CaffeineClientHandler> handler = app->m_WindowHandler[mainUUID].get();

            if (handler && !handler->IsClosing()) {
                if (wParam == g_exitCode) // Jump list exit
                {
                    for (map<string, CefRefPtr<CaffeineClientHandler> >::iterator it=app->m_WindowHandler.begin(); it!=app->m_WindowHandler.end(); ++it)
                    {
                        if(it->second.get()) 
                        {
                            CefRefPtr<CefBrowser> browser = it->second->GetBrowser();
                            browser->GetHost()->CloseBrowser(false);
                        }
                    }

					//CefRefPtr<CefBrowser> browser = handler->GetBrowser();
					//if (browser.get()) {
					//	browser->GetHost()->CloseBrowser(false);
					//}
				} else {
                    ShowWindow(hWnd, SW_MINIMIZE);
                }
                return 0;
            }

            break;
        }

        case WM_TIMER:
        {
            if(IDLETIMER == wParam)
            {
                //  TODO:  Check timer id
                LASTINPUTINFO lif = {sizeof(LASTINPUTINFO), 0};
                GetLastInputInfo(&lif);
                UINT IdleTimePassed = GetTickCount() - lif.dwTime;
                
                WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
                bool CurrentlyIdle = (pWE->IdleTimeThreshold < IdleTimePassed);
                if(CurrentlyIdle != pWE->IsIdle)
                {
                    const CefString EventName = (CurrentlyIdle? "startIdle" : "stopIdle");
                    pWE->IsIdle = CurrentlyIdle;
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(EventName);
                }
            }
            //  TODO:  When we drop XP support, we can use COM and get network connectivity events.
            else if(NETWORKTIMER == wParam)
            {
                WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
                bool CurrentlyConnected = pWE->NetworkAvailable();
                if(CurrentlyConnected != pWE->IsConnected)
                {
                    const CefString EventName = (CurrentlyConnected? "os:online" : "os:offline");
                    pWE->IsConnected = CurrentlyConnected;
                    app->m_WindowHandler[mainUUID]->CreateAndDispatchCustomEvent(EventName);
                }
            }
            break;
        }

        case WM_DESTROY:
        {
            WTSUnRegisterSessionNotification(hWnd);
            // The frame window has exited

            if (!devMode)
            {
                jumpList.RemoveAllTasks();
            }

            KillTimer(hWnd, IDLETIMER);
            KillTimer(hWnd, NETWORKTIMER);
            WindowExtras *pWE = reinterpret_cast<WindowExtras *>(::GetWindowLongPtr(hWnd, 0));
            delete pWE;
            SetWindowLongPtr(hWnd, 0, 0);
            SetShutdownFlag(true);
            PostQuitMessage(0);
            return 0;
        }

        case WM_GETMINMAXINFO:
        {
            LPMINMAXINFO minmaxInfoPtr = (LPMINMAXINFO) lParam;
            minmaxInfoPtr->ptMinTrackSize.x = MAIN_WINDOW_MIN_WIN_WIDTH;
            minmaxInfoPtr->ptMinTrackSize.y = MAIN_WINDOW_MIN_WIN_HEIGHT;

            // Keep the width the same
            RECT rect;
            GetWindowRect(hWnd, &rect);
            minmaxInfoPtr->ptMaxSize.x = (rect.right - rect.left);

            // Keep window at same position
            minmaxInfoPtr->ptMaxPosition.x = rect.left;
            minmaxInfoPtr->ptMaxPosition.y = 0;

            SystemParametersInfo( SPI_GETWORKAREA, 0, &rect, 0 );
            minmaxInfoPtr->ptMaxSize.y = (rect.bottom - rect.top);

            return 0;
        }

        case WM_COPYDATA:
        {
            BOOL retval = FALSE;
            PCOPYDATASTRUCT pCds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
            if (pCds->dwData == WM_PENDING_YID) 
            {
                if (app->m_WindowHandler[mainUUID].get() && app->m_WindowHandler[mainUUID]->GetBrowser()) 
                {
                    CefRefPtr<CefFrame> frame = app->m_WindowHandler[mainUUID]->GetBrowser()->GetMainFrame();
                    wstring code = L"Caffeine.pendingYIDs.push(\"";
                    //  TODO:  Escape this ... otherwise there's an XSS
                    code += static_cast<LPWSTR>(pCds->lpData);
                    code += L"\");";
                    frame->ExecuteJavaScript(code, frame->GetURL(), 0);
                }

                retval = TRUE;
            }
            return retval;
        }

        case CAFFEINE_SOCKETS_MSG:
            CefRefPtr<CefProcessMessage> process_message = CefProcessMessage::Create("invokeSocketMethod");
            process_message->GetArgumentList()->SetInt(0, wParam);
            if (WSAGETSELECTERROR(lParam))
            {
                process_message->GetArgumentList()->SetString(1, "error");
                process_message->GetArgumentList()->SetInt(2, WSAGETSELECTERROR(lParam));
            }
            else
            {
                //  No error
                switch(WSAGETSELECTEVENT(lParam))
                {
                    case FD_CONNECT:
                        process_message->GetArgumentList()->SetString(1, "connect");
                        break;
                    case FD_CLOSE:
                        process_message->GetArgumentList()->SetString(1, "close");
                        break;
                    case FD_READ:
                        process_message->GetArgumentList()->SetString(1, "read");
                        break;
                    case FD_WRITE:
                        process_message->GetArgumentList()->SetString(1, "write");
                        break;
                }
            }
            mainWinBrowser->SendProcessMessage(PID_RENDERER, process_message);
            break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}
// Inject webinos.js
// The file is loaded from the webinos\test\client folder if possible.
// If this fails, the current folder is used.
void ClientApp::InjectWebinos(CefRefPtr<CefFrame> frame)
{
  CefRefPtr<CefCommandLine> commandLine = AppGetCommandLine();

  // First try and load the platform-supplied webinos.js
#if defined(OS_WIN)
  FilePath workingDir(commandLine->GetProgram().ToWString().c_str());
  FilePath webinosJSPath = workingDir.DirName().Append(L"..\\..\\webinos\\web_root\\webinos.js");
#else
  FilePath workingDir(commandLine->GetProgram());
  FilePath webinosJSPath = workingDir.DirName().Append("..\\..\\webinos\\web_root\\webinos.js");
#endif

  int64 webinosJSCodeSize;
  bool gotJSFile = file_util::GetFileSize(webinosJSPath, &webinosJSCodeSize);
  if (!gotJSFile)
  {
    // Unable to load the platform-supplied webinos.js, use the installed version.
#if defined(OS_WIN)
    workingDir = FilePath(commandLine->GetProgram().ToWString().c_str());
    webinosJSPath = workingDir.DirName().Append(L"webinos.js");
#else
    workingDir = FilePath(commandLine->GetProgram());
    webinosJSPath = workingDir.DirName().Append("webinos.js");
#endif
    gotJSFile = file_util::GetFileSize(webinosJSPath, &webinosJSCodeSize);
  }

  if (gotJSFile)
  {
    char* webinosJSCode = new char[webinosJSCodeSize+1];
    file_util::ReadFile(webinosJSPath, webinosJSCode, webinosJSCodeSize);
    webinosJSCode[webinosJSCodeSize] = 0;

    if (frame == NULL)
    {
      // Register as a Cef extension.
      CefRegisterExtension("webinos", webinosJSCode, NULL);
    }
    else
    {
      // Run the code in the frame javascript context right now,
      // but only if the URL refers to the widget server.
      int widgetServerPort;
      AppGetWebinosWRTConfig(NULL,&widgetServerPort);

      char injectionCandidate[MAX_URL_LENGTH];
      sprintf(injectionCandidate,"http://localhost:%d",widgetServerPort);

      std::string url = frame->GetURL();
      if (url.substr(0,strlen(injectionCandidate)) == injectionCandidate)
        frame->ExecuteJavaScript(webinosJSCode, url, 0);
    }

    delete[] webinosJSCode;
  }
  else
  {
    	LOG(ERROR) << "Can't find webinos.js";
  }
}
//  This is the client message handler.
bool CaffeineClientHandler::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message)
{
    if(message->GetName() == "popupWindow" )
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();

        wstring msg = L"Window Creation Timing: ClientHandler popupWindow: " + retval->GetString(0).ToWString();
        app->ShellLog(msg);

        string uuid = retval->GetString(0);
        string initArg = retval->GetString(1).ToString();
        bool bCreateFrameless = retval->GetBool(2);

        int height = retval->GetInt(3);
        int width  = retval->GetInt(4);
        int left = retval->GetInt(5);
        int top = retval->GetInt(6);
        string target = (retval->GetSize()>7)?  retval->GetString(7) : "";
        bool bResizable = (retval->GetSize()>8)? retval->GetBool(8) : true;
        int minWidth = retval->GetInt(9);
        int minHeight = retval->GetInt(10);

        bool windowAlreadyExists = false;
        if ( target == "ymail" )
        {
            if (  mailUUID != "" )
                windowAlreadyExists = true;
            else
                mailUUID = uuid;
        }
        if ( ! windowAlreadyExists )
            CreateRemoteWindow(height, width, left, top, uuid, initArg, bCreateFrameless, bResizable, target, minWidth, minHeight);
        else
            ActivateWindow( uuid );
    }
    else if(message->GetName() == "setCookie" )
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();

        string name = retval->GetString(1);
        string value = retval->GetString(2);
        int callbackNumber = retval->GetInt(0);
        CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, name, value, callbackNumber) );
    }

    else if(message->GetName() == "toastWindow" )
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();

        string uuid = retval->GetString(0);
        string initArg = retval->GetString(1).ToString();
        CreateToastWindow(uuid, initArg);
    }

#ifdef OS_WIN
    else if (message->GetName() == "triggerDump")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();

        crAddScreenshot2(CR_AS_VIRTUAL_SCREEN | CR_AS_USE_JPEG_FORMAT, 80);

        CR_EXCEPTION_INFO crDump = {0,};
        crDump.cb = sizeof(CR_EXCEPTION_INFO);
        crDump.exctype = CR_SEH_EXCEPTION;
        crDump.code = 10203040;
        crDump.pexcptrs = NULL;
        if(crGenerateErrorReport(&crDump) == 0)
        {
            StatusObject->SetString("status", "success");
        }
        else
        {
            StatusObject->SetString("status", "error");
        }

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
#endif
    else if(message->GetName() == "sendIPC")
    {
        //  Probably should have a few asserts around this
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString browser_handle = retval->GetString(0);
        CefRefPtr<CefFrame> frame = NULL;

        if (app->m_WindowHandler.find(browser_handle) != app->m_WindowHandler.end())
        {
            //  TODO:  Do we really need this look up?
            CefRefPtr<CefBrowser> target_browser = app->m_WindowHandler[browser_handle]->GetBrowser();
            if (target_browser.get())
            {
                frame = target_browser->GetMainFrame();

                if (frame != NULL && frame->IsValid())
                {
                    CefString snippet = L"Caffeine.Event.fire(Caffeine.CEFContext, 'ipcReceived', '" + 
                        (retval->GetString(2)).ToWString() + L"', unescape('" + (retval->GetString(1)).ToWString() + L"'));";
                    frame->ExecuteJavaScript(snippet, frame->GetURL(), 0);
                }
            }
        }
    }

    else if (message->GetName() == "getDownloadDirectoryFromUser")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();
        CefString DirectoryPicked;

        if(GetDirectoryFromUser(DirectoryPicked))
        {
            wstring empty = wstring(L"");
            //  TODO:  What about duplicate directory paths?
            AcceptableDownloadDirectories.push_front(DirectoryPicked);
            StatusObject->SetString("status", "success");
            StatusObject->SetString("downloadPath", DirectoryPicked);
            app->showFileSaveAsDialog = false;
        }
        else
        {
            StatusObject->SetString("status", "error");
        }

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "getDownloadPathFromUser")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();
        CefString filename = retval->GetString(1);
        CefString DirectoryPicked;

        if(GetPathFromUser(filename, DirectoryPicked))
        {
            //  TODO:  What about duplicate directory paths?
            wstring empty = wstring(L"");
            AcceptableDownloadDirectories.push_front(DirectoryPicked);
            StatusObject->SetString("status", "success");
            StatusObject->SetString("downloadPath", DirectoryPicked);
            StatusObject->SetString("filename", filename);
            app->showFileSaveAsDialog = false;
        }
        else
        {
            StatusObject->SetString("status", "error");
        }

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }

    else if (message->GetName() == "resetDownloadDirectory")
    {
        SetDownloadPath(L"");
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();
        StatusObject->SetString("status", "success");
        app->showFileSaveAsDialog = true;

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "getDownloadPath")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();

        StatusObject->SetString("status", "success");
        app->showFileSaveAsDialog = false;
        StatusObject->SetString("downloadPath", GetDownloadPath(L""));

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "setDownloadPath")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create();

        list<CefString>::iterator i = find(AcceptableDownloadDirectories.begin(), AcceptableDownloadDirectories.end(), retval->GetString(1));
        if (i != AcceptableDownloadDirectories.end())
        {
            StatusObject->SetString("status", "success");
            app->showFileSaveAsDialog = false;
            SetDownloadPath(retval->GetString(1));
        }
        else  //  Error case
        {
            StatusObject->SetString("status", "error");
            app->showFileSaveAsDialog = true;
        }

        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, message->GetName());
        callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0));
        callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "showDirectory")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString directory = retval->GetString(0);

        list<CefString>::iterator i = find(AcceptableDownloadDirectories.begin(), AcceptableDownloadDirectories.end(), directory);
        if (i != AcceptableDownloadDirectories.end())
        {
            if(retval->GetType(1) == VTYPE_LIST)
            {
                CefRefPtr<CefListValue> selected_files = retval->GetList(1);
                //  Probably could have just one function ShowFolders that checks the type of the second arg.
                ShowFolder2(directory.ToWString(), selected_files);
            }
            else  //  It's a string
            {
                CefString selected_file = retval->GetString(1);
                ShowFolder(directory.ToString(), selected_file);
            }
        }
        else
        {
            app->ShellLog(L"showDirectory called BUT no AcceptableDownloadDirectories value found");
        }
    }
    else if (message->GetName() == "startFlashing")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString browser_handle = retval->GetString(0);
        bool bAutoStop = retval->GetBool(1);
        StartFlashing(browser_handle, bAutoStop);
    }
    else if(message->GetName() == "stopFlashing")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString browser_handle = retval->GetString(0);
        StopFlashing(browser_handle);
    }
    else if(message->GetName() == "activateWindow")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString browser_handle = retval->GetString(0);
        ActivateWindow(browser_handle);
    }
    else if(message->GetName() == "activateApp")
    {
#ifdef __APPLE__
        activatesApp();
#endif
    }
    else if(message->GetName() == "showWindow")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString uuid = retval->GetString(0);
        ShowWindow(uuid);
        //  TODO:  Should probably handle this event from JS
        CreateAndDispatchCustomEvent("show");
    }
    else if(message->GetName() == "hideWindow")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString uuid = retval->GetString(0);
        HideWindow(uuid);
        //  TODO:  Should probably handle this event from JS
        CreateAndDispatchCustomEvent("hide");
    }
    else if (message->GetName() == "setUserAgent")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        CefString UA = retval->GetString(0);
        user_agent = UA;
    }
    else if (message->GetName() == "setPrefixMapping")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        requestPrefixMap[retval->GetString(0)] = retval->GetString(1);
    }
#ifdef ENABLE_MUSIC_SHARE
    else if (message->GetName() == "ITunesPlayPreview")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        wstring url = retval->GetString(0);
        ITunesPlayPreview(url);
    }
#if defined(OS_WIN)
    else if (message->GetName() == "isITunesOn")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        CefRefPtr<CefDictionaryValue> isOn = CefDictionaryValue::Create();
        isITunesOn(isOn);
        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");
        callbackMsg->GetArgumentList()->SetString(0, name);
        callbackMsg->GetArgumentList()->SetInt(1, retvalInt);

        callbackMsg->GetArgumentList()->SetDictionary(2, isOn);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "getITunesTrackInfo")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        CefRefPtr<CefDictionaryValue> TrackInfo = CefDictionaryValue::Create();
        getITunesTrackInfo(TrackInfo);
        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");

        callbackMsg->GetArgumentList()->SetString(0, name);
        callbackMsg->GetArgumentList()->SetInt(1, retvalInt);

        callbackMsg->GetArgumentList()->SetDictionary(2, TrackInfo);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
    else if (message->GetName() == "getInstalledPlayers")
    {
        ShellLog(L"FLAME CHART CaffeineClientHandler.getInstalledPlayers");

        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        CefRefPtr<CefDictionaryValue> InstalledPlayers = CefDictionaryValue::Create();
        getInstalledPlayers(InstalledPlayers);
        CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback");

        callbackMsg->GetArgumentList()->SetString(0, name);
        callbackMsg->GetArgumentList()->SetInt(1, retvalInt);

        callbackMsg->GetArgumentList()->SetDictionary(2, InstalledPlayers);
        browser->SendProcessMessage(PID_RENDERER, callbackMsg);
    }
#else //OS_MAC
    else if (message->GetName() == "isITunesOn")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        isITunesOn(name, retvalInt);
    }
    else if (message->GetName() == "getITunesTrackInfo")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        getITunesTrackInfo(name, retvalInt);
    }
    else if (message->GetName() == "getInstalledPlayers")
    {
        ShellLog(L"FLAME CHART CaffeineClientHandler.getInstalledPlayers");
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string name = message->GetName();
        int retvalInt = retval->GetInt(0);
        getInstalledPlayers(name, retvalInt);
    }
#endif  //OS_WIN

#endif  //ENABLE_MUSIC_SHARE

    else if (message->GetName() == "shakeWindow")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        ASSERT(retval->GetSize() == 1);
        
        string uuid = retval->GetString(0);
#ifdef __APPLE__
        ShakeWindow(uuid);
#endif
        
    }
    
    else if (message->GetName() == "moveWindowTo")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        ASSERT(retval->GetSize() == 5);

        string uuid = retval->GetString(0);
        int left  = retval->GetInt(1);
        int top  = retval->GetInt(2);
        int height  = retval->GetInt(3);
        int width  = retval->GetInt(4);

        MoveOrResizeWindow(uuid, left, top, height, width);
    }
    //  This needs to be broken up into two functions: one to determine if a
    //  window is the foreground window and another to pop up notifications.
    else if(message->GetName() == "messageReceived")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        wstring from = retval->GetString(0);
        wstring display = retval->GetString(1);
        wstring msg = retval->GetString(2);
        wstring convId = retval->GetString(3);
        MessageReceived(from, display, msg, convId);
    }
    else if(message->GetName() == "stateIsNowLoggedIn")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        stateIsNowLoggedIn(retval->GetBool(0));
    }
    else if(message->GetName() == "enableSessionMenus")
    {
#ifdef OS_MACOSX
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        enableSessionMenus(retval->GetBool(0));
#endif
    }

    else if (message->GetName() == "openFile")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        wstring path = retval->GetString(0);

        if (downloadedFiles.find(path) != downloadedFiles.end())
        {
            OpenFile(path);
        }
        else
        {
            wstringstream msg;
            msg << L"Attempt made to open file '";
            msg << path;
            msg << L"' that was not downloaded by the client";

            app->ShellLog(msg.str());
        }
    }
#ifdef OS_MACOSX
    else if(message->GetName() == "setBadgeCount")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        ChangeBadgeCount(retval->GetInt(0), retval->GetBool(1));

    }
    else if(message->GetName() == "showViewMenu")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        ShowViewMenu(retval->GetBool(0));
    }

    else if(message->GetName() == "setUserToken")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string usr = retval->GetString(0);
        string tok = retval->GetString(1);
        SetUserToken(usr,tok);
    }
    else if(message->GetName() == "removeAllUserTokens" )
    {
        RemoveAllTokens();
    }
    else if(message->GetName() == "removeUserToken")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        string usr = retval->GetString(0);
        RemoveUserToken(usr);
    }
#endif

#ifdef OS_WIN
    else if (message->GetName() == "restartApplication")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        RestartApplication(retval->GetString(0));
    }

    else if (message->GetName() == "setEphemeralState")
    {
        CefRefPtr<CefListValue> retval = message->GetArgumentList();
        SetEphemeralState(retval->GetString(0));
    }
#endif


    else if (message->GetName() == "setBrowserValue")
    {
        CefRefPtr<CefListValue> args = message->GetArgumentList();

        switch (args->GetInt(0))
        {
            case SET_BROWSER_VALUE_FEEDBACK_LINK:
#ifdef __APPLE__
                setFeedbackLink( args->GetString(1).ToString());
#endif
                break;
        }
    }

#ifdef __APPLE__

#pragma mark === RTT2 Sockets - browser side ===

    else if ( message->GetName() == "createSocket" )
    {
        createSocket(message->GetArgumentList());
    }

    else if ( message->GetName() == "writeSocket" )
    {
        writeToSocket(message->GetArgumentList());
    }

    else if ( message->GetName() == "closeSocket" )
    {
        closeSocket(message->GetArgumentList()->GetInt(0));
    }

#endif

    return false;
}