// Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights // reserved. Use of this source code is governed by a BSD-style license that // can be found in the LICENSE file. #include "tests/cefclient/browser/drm_test.h" #include #include #include "include/cef_parser.h" #include "include/cef_web_plugin.h" #include "tests/cefclient/browser/test_runner.h" namespace client { namespace drm_test { namespace { // Application-specific error codes. const int kMessageFormatError = 1; const int kCdmLoadError = 2; const char kTestUrlPath[] = "/drm"; const char kWidevineCdmPathKey[] = "widevine_cdm_path"; // Callback executed once CDM registration is complete. class CdmCallback : public CefRegisterCdmCallback { public: CdmCallback(CefRefPtr callback) : callback_(callback) {} void OnCdmRegistrationComplete(cef_cdm_registration_error_t result, const CefString& error_message) OVERRIDE { if (result == CEF_CDM_REGISTRATION_ERROR_NONE) callback_->Success(""); else callback_->Failure(kCdmLoadError, error_message); callback_ = nullptr; } private: CefRefPtr callback_; IMPLEMENT_REFCOUNTING(CdmCallback); DISALLOW_COPY_AND_ASSIGN(CdmCallback); }; // Handle messages in the browser process. class Handler : public CefMessageRouterBrowserSide::Handler { public: Handler() {} // Called due to cefQuery execution in drm.html. virtual bool OnQuery(CefRefPtr browser, CefRefPtr frame, int64 query_id, const CefString& request, bool persistent, CefRefPtr callback) OVERRIDE { // Only handle messages from the test URL. const std::string& url = frame->GetURL(); if (!test_runner::IsTestURL(url, kTestUrlPath)) return false; // Parse |request| as a JSON dictionary. CefRefPtr request_dict = ParseJSON(request); if (!request_dict) { callback->Failure(kMessageFormatError, "Incorrect message format"); return true; } // Verify the "widevine_cdm_path" key. if (!VerifyKey(request_dict, kWidevineCdmPathKey, VTYPE_STRING, callback)) return true; const std::string& widevine_cdm_path = request_dict->GetString(kWidevineCdmPathKey); if (widevine_cdm_path.empty()) { callback->Failure(kMessageFormatError, "Empty widevine CDM path"); return true; } // Register the Widvine CDM. CefRegisterWidevineCdm(widevine_cdm_path, new CdmCallback(callback)); return true; } private: // Convert a JSON string to a dictionary value. static CefRefPtr ParseJSON(const CefString& string) { CefRefPtr value = CefParseJSON(string, JSON_PARSER_RFC); if (value.get() && value->GetType() == VTYPE_DICTIONARY) return value->GetDictionary(); return nullptr; } // Verify that |key| exists in |dictionary| and has type |value_type|. Fails // |callback| and returns false on failure. static bool VerifyKey(CefRefPtr dictionary, const char* key, cef_value_type_t value_type, CefRefPtr callback) { if (!dictionary->HasKey(key) || dictionary->GetType(key) != value_type) { callback->Failure( kMessageFormatError, "Missing or incorrectly formatted message key: " + std::string(key)); return false; } return true; } }; } // namespace void CreateMessageHandlers(test_runner::MessageHandlerSet& handlers) { handlers.insert(new Handler()); } } // namespace drm_test } // namespace client