diff --git a/DEPS b/DEPS index 3aa588a8..affb7e8 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '9ea894b4d030b55e377fc3858ebde12198f205ce', + 'skia_revision': '67116384368195913ec014972b4fc38de2087fb8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '661a53a29a09544439cb49076cd9411f2c052e61', + 'v8_revision': 'a559520badecf7f9701fc1b20d027c19006f8259', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '4741b291f462c0c4a5de4abf1653c3b3c87b613a', + 'pdfium_revision': 'fff400a5df032c2203eef9f76a5dbb164672df3d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'a067dd2f2b17fc0cb7057ac4500b07590c596e34', + 'catapult_revision': '9e6944a8f3106212e60d36add9a357964bf55373', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/base/callback_list_unittest.nc b/base/callback_list_unittest.nc index 0ddc135..7347f76 100644 --- a/base/callback_list_unittest.nc +++ b/base/callback_list_unittest.nc
@@ -35,7 +35,7 @@ }; -#if defined(NCTEST_MOVE_ONLY_TYPE_PARAMETER) // [r"fatal error: call to deleted constructor"] +#if defined(NCTEST_MOVE_ONLY_TYPE_PARAMETER) // [r"fatal error: call to (implicitly-)?deleted( copy)? constructor"] // Callbacks run with a move-only typed parameter. //
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 30ad2e99..cf426e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -207,6 +207,8 @@ private boolean mDeferredStartupPosted; private boolean mTabModelsInitialized; + private boolean mNativeInitialized; + private boolean mRemoveWindowBackgroundDone; // The class cannot implement TouchExplorationStateChangeListener, // because it is only available for Build.VERSION_CODES.KITKAT and later. @@ -683,6 +685,9 @@ @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); + + maybeRemoveWindowBackground(); + Tab tab = getActivityTab(); if (tab == null) return; if (hasFocus) { @@ -1048,8 +1053,15 @@ ApiCompatibilityUtils.getColor(getResources(), R.color.light_background_color)); } - @Override - public void finishNativeInitialization() { + private void maybeRemoveWindowBackground() { + // Only need to do this logic once. + if (mRemoveWindowBackgroundDone) return; + + // Remove the window background only after native init and window getting focus. It's done + // after native init because before native init, a fake background gets shown. The window + // focus dependency is because doing it earlier can cause drawing bugs, e.g. crbug/673831. + if (!mNativeInitialized || !hasWindowFocus()) return; + // The window background color is used as the resizing background color in Android N+ // multi-window mode. See crbug.com/602366. if (Build.VERSION.CODENAME.equals("N") || Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { @@ -1059,6 +1071,14 @@ } else { removeWindowBackground(); } + + mRemoveWindowBackgroundDone = true; + } + + @Override + public void finishNativeInitialization() { + mNativeInitialized = true; + maybeRemoveWindowBackground(); DownloadManagerService.getDownloadManagerService( getApplicationContext()).onActivityLaunched();
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index fa618404..bced9689 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -684,9 +684,8 @@ #if !defined(OS_CHROMEOS) metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - SigninStatusMetricsProvider::CreateInstance(base::WrapUnique( - new ChromeSigninStatusMetricsProviderDelegate)))); + SigninStatusMetricsProvider::CreateInstance( + base::WrapUnique(new ChromeSigninStatusMetricsProviderDelegate))); #endif // !defined(OS_CHROMEOS) metrics_service_->RegisterMetricsProvider(
diff --git a/chrome/browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc b/chrome/browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc index 962c98f..1291a591 100644 --- a/chrome/browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc +++ b/chrome/browser/signin/chrome_signin_status_metrics_provider_delegate_unittest.cc
@@ -19,8 +19,8 @@ std::unique_ptr<ChromeSigninStatusMetricsProviderDelegate> delegate( new ChromeSigninStatusMetricsProviderDelegate); ChromeSigninStatusMetricsProviderDelegate* raw_delegate = delegate.get(); - std::unique_ptr<SigninStatusMetricsProvider> metrics_provider( - SigninStatusMetricsProvider::CreateInstance(std::move(delegate))); + std::unique_ptr<SigninStatusMetricsProvider> metrics_provider = + SigninStatusMetricsProvider::CreateInstance(std::move(delegate)); // Initial status is all signed in and then a signed-in browser is opened. metrics_provider->UpdateInitialSigninStatusForTesting(2, 2);
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index 80a1aee..4b36627f 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -322,7 +322,14 @@ FinishProfileSyncServiceSetup(); Initialize(new_profile, nullptr); DCHECK_EQ(profile_, new_profile); + +#if defined(OS_MACOSX) + // On macOS, the sync confirmation dialog is web-contents modal and thus + // it is dismissed on tab navigation (which always occurs when signing in + // to a new profile). + // Skip sync confirmation on macOS to workaround this issue. skip_sync_confirm_ = true; +#endif // We've transferred our credentials to the new profile - notify that // the signin for the original profile was cancelled (must do this after @@ -494,10 +501,6 @@ // Regardless of whether the account was successfully added or not, // continue with sync starting. - // TODO(zmin): Remove this hack once the https://crbug.com/657924 fixed. - // Skip the Sync confirmation dialog if user choose to create a new profile - // for the corp signin. This is because the dialog doesn't work properly - // after the corp signin. if (skip_sync_confirm_) { OnSyncConfirmationUIClosed(LoginUIService::ABORT_SIGNIN); return;
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.h b/chrome/browser/ui/sync/one_click_signin_sync_starter.h index efd09d5..a2cd1b7 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.h +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.h
@@ -260,8 +260,10 @@ // Prevents Sync from running until configuration is complete. std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_; - // Temporary flag to disable new sync confirm page if user choose to create a - // new profile after the corp account signin. + // Temporary flag used only on macOS to disable new sync confirm page if user + // choose to create a new profile. + // + // TODO(msarda): Remove this flag once the https://crbug.com/677012 fixed. bool skip_sync_confirm_; base::WeakPtrFactory<OneClickSigninSyncStarter> weak_pointer_factory_;
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc index cf9b6dc..06732fd 100644 --- a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc +++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.cc
@@ -9,10 +9,13 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" #include "content/public/browser/user_metrics.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h" #include "ui/base/l10n/l10n_util.h" @@ -32,19 +35,31 @@ const char kActionCreateNewUser[] = "createNewUser"; const char kActionStartSync[] = "startSync"; -class EmailConfirmationHandler : public content::WebUIMessageHandler { - public: - EmailConfirmationHandler(); - ~EmailConfirmationHandler() override; - void RegisterMessages() override; -}; - -EmailConfirmationHandler::EmailConfirmationHandler() {} -EmailConfirmationHandler::~EmailConfirmationHandler() {} -void EmailConfirmationHandler::RegisterMessages() {} - } // namespace +class SigninEmailConfirmationDialog::DialogWebContentsObserver + : public content::WebContentsObserver { + public: + DialogWebContentsObserver(content::WebContents* web_contents, + SigninEmailConfirmationDialog* dialog) + : content::WebContentsObserver(web_contents), + signin_email_confirmation_dialog_(dialog) {} + ~DialogWebContentsObserver() override {} + + private: + void WebContentsDestroyed() override { + // The dialog is already closed. No need to call CloseDialog() again. + // NOTE: |this| is deleted after |ResetDialogObserver| returns. + signin_email_confirmation_dialog_->ResetDialogObserver(); + } + + void RenderProcessGone(base::TerminationStatus status) override { + signin_email_confirmation_dialog_->CloseDialog(); + } + + SigninEmailConfirmationDialog* signin_email_confirmation_dialog_; +}; + SigninEmailConfirmationDialog::SigninEmailConfirmationDialog( content::WebContents* contents, Profile* profile, @@ -55,8 +70,7 @@ profile_(profile), last_email_(last_email), new_email_(new_email), - callback_(callback), - dialog_delegate_(NULL) {} + callback_(callback) {} SigninEmailConfirmationDialog::~SigninEmailConfirmationDialog() {} @@ -71,16 +85,45 @@ base::UserMetricsAction("Signin_Show_ImportDataPrompt")); SigninEmailConfirmationDialog* dialog = new SigninEmailConfirmationDialog( contents, profile, last_email, email, callback); - dialog->Show(); + dialog->ShowDialog(); } -void SigninEmailConfirmationDialog::Show() { +void SigninEmailConfirmationDialog::ShowDialog() { gfx::Size minSize(kDialogWidth, kDialogMinHeight); gfx::Size maxSize(kDialogWidth, kDialogMaxHeight); - dialog_delegate_ = ShowConstrainedWebDialogWithAutoResize( - profile_, this, web_contents_, minSize, maxSize); + ConstrainedWebDialogDelegate* dialog_delegate = + ShowConstrainedWebDialogWithAutoResize(profile_, this, web_contents_, + minSize, maxSize); + + content::WebContents* dialog_web_contents = dialog_delegate->GetWebContents(); + dialog_observer_.reset( + new DialogWebContentsObserver(dialog_web_contents, this)); } +void SigninEmailConfirmationDialog::CloseDialog() { + content::WebContents* dialog_web_contents = GetDialogWebContents(); + if (dialog_web_contents == nullptr) + return; + content::WebUI* web_ui = dialog_web_contents->GetWebUI(); + if (web_ui) { + SigninEmailConfirmationUI* signin_email_confirmation_ui = + static_cast<SigninEmailConfirmationUI*>(web_ui->GetController()); + if (signin_email_confirmation_ui) + signin_email_confirmation_ui->Close(); + } +} + +void SigninEmailConfirmationDialog::ResetDialogObserver() { + dialog_observer_.reset(); +} + +content::WebContents* SigninEmailConfirmationDialog::GetDialogWebContents() + const { + return dialog_observer_.get() ? dialog_observer_->web_contents() : nullptr; +} + +// ui::WebDialogDelegate implementation + ui::ModalType SigninEmailConfirmationDialog::GetDialogModalType() const { return ui::MODAL_TYPE_WINDOW; } @@ -94,9 +137,7 @@ } void SigninEmailConfirmationDialog::GetWebUIMessageHandlers( - std::vector<content::WebUIMessageHandler*>* handlers) const { - handlers->push_back(new EmailConfirmationHandler()); -} + std::vector<content::WebUIMessageHandler*>* handlers) const {} void SigninEmailConfirmationDialog::GetDialogSize(gfx::Size* size) const { // Avoid setting a dialog size in here as this dialog auto-resizes (see
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h index e47d102a..353cd21 100644 --- a/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h +++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h
@@ -46,6 +46,8 @@ const Callback& callback); private: + class DialogWebContentsObserver; + SigninEmailConfirmationDialog(content::WebContents* contents, Profile* profile, const std::string& last_email, @@ -68,7 +70,17 @@ // Shows the dialog and releases ownership of this object. It will // delete itself when the dialog is closed. - void Show(); + void ShowDialog(); + + // Closes the dialog. + void CloseDialog(); + + // Resets the dialog observer. + void ResetDialogObserver(); + + // Returns the media router dialog WebContents. + // Returns nullptr if there is no dialog. + content::WebContents* GetDialogWebContents() const; // Web contents from which the "Learn more" link should be opened. content::WebContents* const web_contents_; @@ -78,8 +90,8 @@ std::string new_email_; Callback callback_; - // Weak pointer to the dialog delegate. - ConstrainedWebDialogDelegate* dialog_delegate_; + // Observer for lifecycle events of the web contents of the dialog. + std::unique_ptr<DialogWebContentsObserver> dialog_observer_; DISALLOW_COPY_AND_ASSIGN(SigninEmailConfirmationDialog); };
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc index 1e13c590..127bb61 100644 --- a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc +++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chromium_strings.h" @@ -13,6 +14,7 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/base/webui/web_ui_util.h" +#include "ui/web_dialogs/web_dialog_delegate.h" SigninEmailConfirmationUI::SigninEmailConfirmationUI(content::WebUI* web_ui) : ConstrainedWebDialogUI(web_ui) { @@ -47,3 +49,11 @@ } SigninEmailConfirmationUI::~SigninEmailConfirmationUI() {} + +void SigninEmailConfirmationUI::Close() { + ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); + if (delegate) { + delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); + delegate->OnDialogCloseFromWebUI(); + } +}
diff --git a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h index b75d4df..9da37438 100644 --- a/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h +++ b/chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h
@@ -13,6 +13,9 @@ explicit SigninEmailConfirmationUI(content::WebUI* web_ui); ~SigninEmailConfirmationUI() override; + // Closes this sign-in email confirmation webUI. + void Close(); + private: DISALLOW_COPY_AND_ASSIGN(SigninEmailConfirmationUI); };
diff --git a/components/gcm_driver/crypto/p256_key_util.cc b/components/gcm_driver/crypto/p256_key_util.cc index daf7e0ff..18f927d 100644 --- a/components/gcm_driver/crypto/p256_key_util.cc +++ b/components/gcm_driver/crypto/p256_key_util.cc
@@ -51,8 +51,7 @@ // Export the encrypted private key with an empty password. This is not done // to provide any security, but rather to achieve a consistent private key // storage between the BoringSSL and NSS implementations. - if (!key_pair->ExportEncryptedPrivateKey( - "" /* password */, 1 /* iteration */, &private_key)) { + if (!key_pair->ExportEncryptedPrivateKey(&private_key)) { DLOG(ERROR) << "Unable to export the private key."; return false; } @@ -100,7 +99,6 @@ std::unique_ptr<crypto::ECPrivateKey> local_key_pair( crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - "" /* no password */, std::vector<uint8_t>(private_key.data(), private_key.data() + private_key.size()), std::vector<uint8_t>(
diff --git a/components/pdf/renderer/pepper_pdf_host.cc b/components/pdf/renderer/pepper_pdf_host.cc index c56d78e..af54693 100644 --- a/components/pdf/renderer/pepper_pdf_host.cc +++ b/components/pdf/renderer/pepper_pdf_host.cc
@@ -101,7 +101,7 @@ if (!render_frame) return PP_ERROR_FAILED; - render_frame->DidStartLoading(); + render_frame->PluginDidStartLoading(); return PP_OK; } @@ -111,7 +111,7 @@ if (!render_frame) return PP_ERROR_FAILED; - render_frame->DidStopLoading(); + render_frame->PluginDidStopLoading(); return PP_OK; }
diff --git a/components/signin/core/browser/signin_status_metrics_provider.cc b/components/signin/core/browser/signin_status_metrics_provider.cc index 04d54fa..699e61d 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.cc +++ b/components/signin/core/browser/signin_status_metrics_provider.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/location.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -45,9 +46,11 @@ } // static -SigninStatusMetricsProvider* SigninStatusMetricsProvider::CreateInstance( +std::unique_ptr<SigninStatusMetricsProvider> +SigninStatusMetricsProvider::CreateInstance( std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate) { - return new SigninStatusMetricsProvider(std::move(delegate), false); + return base::WrapUnique( + new SigninStatusMetricsProvider(std::move(delegate), false)); } void SigninStatusMetricsProvider::OnSigninManagerCreated(
diff --git a/components/signin/core/browser/signin_status_metrics_provider.h b/components/signin/core/browser/signin_status_metrics_provider.h index 859363e..9d6e663 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.h +++ b/components/signin/core/browser/signin_status_metrics_provider.h
@@ -37,7 +37,7 @@ metrics::ChromeUserMetricsExtension* uma_proto) override; // Factory method, creates a new instance of this class. - static SigninStatusMetricsProvider* CreateInstance( + static std::unique_ptr<SigninStatusMetricsProvider> CreateInstance( std::unique_ptr<SigninStatusMetricsProviderDelegate> delegate); // Update the sign-in status when a SigninManager is created.
diff --git a/content/browser/compositor/software_output_device_win.cc b/content/browser/compositor/software_output_device_win.cc index fd74052..0a1bc20 100644 --- a/content/browser/compositor/software_output_device_win.cc +++ b/content/browser/compositor/software_output_device_win.cc
@@ -178,8 +178,7 @@ style |= WS_EX_LAYERED; SetWindowLong(hwnd_, GWL_EXSTYLE, style); - skia::ScopedPlatformPaint spp(contents_.get()); - HDC dib_dc = spp.GetNativeDrawingContext(); + HDC dib_dc = skia::GetNativeDrawingContext(contents_.get()); ::UpdateLayeredWindow(hwnd_, NULL, &position, &size, dib_dc, &zero, RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); } else {
diff --git a/content/browser/webrtc/webrtc_datachannel_browsertest.cc b/content/browser/webrtc/webrtc_datachannel_browsertest.cc index 4c47f21..b4a789a 100644 --- a/content/browser/webrtc/webrtc_datachannel_browsertest.cc +++ b/content/browser/webrtc/webrtc_datachannel_browsertest.cc
@@ -16,19 +16,11 @@ namespace content { -#if defined(OS_WIN) || (defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)) -// GC does not work correctly in some cases under Android ASAN. -// See https://crbug.com/611620. -// This test has become flaky on Windows. See https://crbug.com/616388 -#define MAYBE_WebRtcDataChannelTest DISABLED_WebRtcDataChannelTest -#else -#define MAYBE_WebRtcDataChannelTest WebRtcDataChannelTest -#endif - -class MAYBE_WebRtcDataChannelTest : public WebRtcContentBrowserTestBase { +// This test is flaky, see https://crbug.com/611620. +class DISABLED_WebRtcDataChannelTest : public WebRtcContentBrowserTestBase { public: - MAYBE_WebRtcDataChannelTest() {} - ~MAYBE_WebRtcDataChannelTest() override {} + DISABLED_WebRtcDataChannelTest() {} + ~DISABLED_WebRtcDataChannelTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { WebRtcContentBrowserTestBase::SetUpCommandLine(command_line); @@ -38,10 +30,10 @@ } private: - DISALLOW_COPY_AND_ASSIGN(MAYBE_WebRtcDataChannelTest); + DISALLOW_COPY_AND_ASSIGN(DISABLED_WebRtcDataChannelTest); }; -IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcDataChannelTest, DataChannelGC) { +IN_PROC_BROWSER_TEST_F(DISABLED_WebRtcDataChannelTest, DataChannelGC) { MakeTypicalCall("testDataChannelGC();", kDataChannelHtmlFile); }
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h index 626229b8..81512cd 100644 --- a/content/public/renderer/render_frame.h +++ b/content/public/renderer/render_frame.h
@@ -200,8 +200,8 @@ // Used by plugins that load data in this RenderFrame to update the loading // notifications. - virtual void DidStartLoading() = 0; - virtual void DidStopLoading() = 0; + virtual void PluginDidStartLoading() = 0; + virtual void PluginDidStopLoading() = 0; #endif // Returns true if this frame is a FTP directory listing.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b843dd8..abfad56 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2577,11 +2577,11 @@ return plugin_power_saver_helper_->WhitelistContentOrigin(content_origin); } -void RenderFrameImpl::DidStartLoading() { +void RenderFrameImpl::PluginDidStartLoading() { didStartLoading(true); } -void RenderFrameImpl::DidStopLoading() { +void RenderFrameImpl::PluginDidStopLoading() { didStopLoading(); } #endif // BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 415f386f..f607fe0e 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -428,8 +428,8 @@ const gfx::Size& unobscured_size, RecordPeripheralDecision record_decision) const override; void WhitelistContentOrigin(const url::Origin& content_origin) override; - void DidStartLoading() override; - void DidStopLoading() override; + void PluginDidStartLoading() override; + void PluginDidStopLoading() override; #endif bool IsFTPDirectoryListing() override; void AttachGuest(int element_instance_id) override;
diff --git a/crypto/ec_private_key.cc b/crypto/ec_private_key.cc index 0a2344c2..9914c5dd 100644 --- a/crypto/ec_private_key.cc +++ b/crypto/ec_private_key.cc
@@ -95,7 +95,6 @@ // static std::unique_ptr<ECPrivateKey> ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - const std::string& password, const std::vector<uint8_t>& encrypted_private_key_info, const std::vector<uint8_t>& subject_public_key_info) { // NOTE: The |subject_public_key_info| can be ignored here, it is only @@ -113,21 +112,15 @@ if (!p8_encrypted || ptr != data + encrypted_private_key_info.size()) return nullptr; - bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> p8_decrypted; - if (password.empty()) { - // Hack for reading keys generated by an older version of the OpenSSL - // code. OpenSSL used to use "\0\0" rather than the empty string because it - // would treat the password as an ASCII string to be converted to UCS-2 - // while NSS used a byte string. - p8_decrypted.reset(PKCS8_decrypt_pbe( - p8_encrypted.get(), reinterpret_cast<const uint8_t*>("\0\0"), 2)); - } - if (!p8_decrypted) { - p8_decrypted.reset(PKCS8_decrypt_pbe( - p8_encrypted.get(), - reinterpret_cast<const uint8_t*>(password.data()), - password.size())); - } + // Hack for reading keys generated by an older version of the OpenSSL code. + // Some implementations encode the empty password as "\0\0" (passwords are + // normally encoded in big-endian UCS-2 with a NUL terminator) and some + // encode as the empty string. PKCS8_decrypt distinguishes the two by whether + // the password is nullptr. + bssl::UniquePtr<PKCS8_PRIV_KEY_INFO> p8_decrypted( + PKCS8_decrypt(p8_encrypted.get(), "", 0)); + if (!p8_decrypted) + p8_decrypted.reset(PKCS8_decrypt(p8_encrypted.get(), nullptr, 0)); if (!p8_decrypted) return nullptr; @@ -166,8 +159,6 @@ } bool ECPrivateKey::ExportEncryptedPrivateKey( - const std::string& password, - int iterations, std::vector<uint8_t>* output) const { OpenSSLErrStackTracer err_tracer(FROM_HERE); // Convert into a PKCS#8 object. @@ -180,9 +171,8 @@ // so use NID_pbe_WithSHA1And3_Key_TripleDES_CBC which should be the OpenSSL // equivalent. bssl::UniquePtr<X509_SIG> encrypted( - PKCS8_encrypt_pbe(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, - reinterpret_cast<const uint8_t*>(password.data()), - password.size(), nullptr, 0, iterations, pkcs8.get())); + PKCS8_encrypt(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, nullptr, nullptr, 0, + nullptr, 0, 1, pkcs8.get())); if (!encrypted) return false;
diff --git a/crypto/ec_private_key.h b/crypto/ec_private_key.h index 8e5fe5e..432019b 100644 --- a/crypto/ec_private_key.h +++ b/crypto/ec_private_key.h
@@ -41,13 +41,12 @@ // Creates a new instance by importing an existing key pair. // The key pair is given as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo - // block and an X.509 SubjectPublicKeyInfo block. + // block with empty password and an X.509 SubjectPublicKeyInfo block. // Returns nullptr if initialization fails. // // This function is deprecated. Use CreateFromPrivateKeyInfo for new code. // See https://crbug.com/603319. static std::unique_ptr<ECPrivateKey> CreateFromEncryptedPrivateKeyInfo( - const std::string& password, const std::vector<uint8_t>& encrypted_private_key_info, const std::vector<uint8_t>& subject_public_key_info); @@ -60,16 +59,12 @@ bool ExportPrivateKey(std::vector<uint8_t>* output) const; // Exports the private key as an ASN.1-encoded PKCS #8 EncryptedPrivateKeyInfo - // block and the public key as an X.509 SubjectPublicKeyInfo block. - // The |password| and |iterations| are used as inputs to the key derivation - // function for generating the encryption key. PKCS #5 recommends a minimum - // of 1000 iterations, on modern systems a larger value may be preferrable. + // block wth empty password. This was historically used as a workaround for + // NSS API deficiencies and does not provide security. // // This function is deprecated. Use ExportPrivateKey for new code. See // https://crbug.com/603319. - bool ExportEncryptedPrivateKey(const std::string& password, - int iterations, - std::vector<uint8_t>* output) const; + bool ExportEncryptedPrivateKey(std::vector<uint8_t>* output) const; // Exports the public key to an X.509 SubjectPublicKeyInfo block. bool ExportPublicKey(std::vector<uint8_t>* output) const;
diff --git a/crypto/ec_private_key_unittest.cc b/crypto/ec_private_key_unittest.cc index 386844c..5345647 100644 --- a/crypto/ec_private_key_unittest.cc +++ b/crypto/ec_private_key_unittest.cc
@@ -41,9 +41,6 @@ // should get back the same exact public key, and the private key should have // the same value and elliptic curve params. TEST(ECPrivateKeyUnitTest, InitRandomTest) { - static const char kPassword1[] = ""; - static const char kPassword2[] = "test"; - std::unique_ptr<crypto::ECPrivateKey> keypair(crypto::ECPrivateKey::Create()); ASSERT_TRUE(keypair); @@ -58,19 +55,10 @@ // Re-import as an EncryptedPrivateKeyInfo with kPassword1. std::vector<uint8_t> encrypted_privkey; std::vector<uint8_t> pubkey; - EXPECT_TRUE( - keypair->ExportEncryptedPrivateKey(kPassword1, 1, &encrypted_privkey)); + EXPECT_TRUE(keypair->ExportEncryptedPrivateKey(&encrypted_privkey)); EXPECT_TRUE(keypair->ExportPublicKey(&pubkey)); keypair_copy = crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - kPassword1, encrypted_privkey, pubkey); - ASSERT_TRUE(keypair_copy); - ExpectKeysEqual(keypair.get(), keypair_copy.get()); - - // Re-import as an EncryptedPrivateKeyInfo with kPassword2. - EXPECT_TRUE( - keypair->ExportEncryptedPrivateKey(kPassword2, 1, &encrypted_privkey)); - keypair_copy = crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - kPassword2, encrypted_privkey, pubkey); + encrypted_privkey, pubkey); ASSERT_TRUE(keypair_copy); ExpectKeysEqual(keypair.get(), keypair_copy.get()); } @@ -200,26 +188,6 @@ EXPECT_FALSE(key); } -TEST(ECPrivateKeyUnitTest, BadPasswordTest) { - const std::string password1; - const std::string password2 = "test"; - - std::unique_ptr<crypto::ECPrivateKey> keypair1( - crypto::ECPrivateKey::Create()); - ASSERT_TRUE(keypair1); - - std::vector<uint8_t> privkey1; - std::vector<uint8_t> pubkey1; - ASSERT_TRUE(keypair1->ExportEncryptedPrivateKey( - password1, 1, &privkey1)); - ASSERT_TRUE(keypair1->ExportPublicKey(&pubkey1)); - - std::unique_ptr<crypto::ECPrivateKey> keypair2( - crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - password2, privkey1, pubkey1)); - ASSERT_FALSE(keypair2); -} - TEST(ECPrivateKeyUnitTest, LoadNSSKeyTest) { static const uint8_t kNSSKey[] = { 0x30, 0x81, 0xb8, 0x30, 0x23, 0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, @@ -252,7 +220,7 @@ std::unique_ptr<crypto::ECPrivateKey> keypair_nss( crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - "", std::vector<uint8_t>(std::begin(kNSSKey), std::end(kNSSKey)), + std::vector<uint8_t>(std::begin(kNSSKey), std::end(kNSSKey)), std::vector<uint8_t>(std::begin(kNSSPublicKey), std::end(kNSSPublicKey)))); @@ -298,7 +266,6 @@ std::unique_ptr<crypto::ECPrivateKey> keypair_openssl( crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - "", std::vector<uint8_t>(std::begin(kOpenSSLKey), std::end(kOpenSSLKey)), std::vector<uint8_t>(std::begin(kOpenSSLPublicKey), std::end(kOpenSSLPublicKey)))); @@ -393,7 +360,6 @@ std::unique_ptr<crypto::ECPrivateKey> keypair_openssl( crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - "", std::vector<uint8_t>(std::begin(kOpenSSLKey), std::end(kOpenSSLKey)), std::vector<uint8_t>(std::begin(kOpenSSLPublicKey), std::end(kOpenSSLPublicKey))));
diff --git a/crypto/ec_signature_creator_unittest.cc b/crypto/ec_signature_creator_unittest.cc index 018ba54a..1bfd89d 100644 --- a/crypto/ec_signature_creator_unittest.cc +++ b/crypto/ec_signature_creator_unittest.cc
@@ -21,23 +21,19 @@ // Do a verify round trip. std::unique_ptr<crypto::ECPrivateKey> key_original( crypto::ECPrivateKey::Create()); - ASSERT_TRUE(key_original.get()); + ASSERT_TRUE(key_original); std::vector<uint8_t> key_info; - ASSERT_TRUE( - key_original->ExportEncryptedPrivateKey(std::string(), 1000, &key_info)); - std::vector<uint8_t> pubkey_info; - ASSERT_TRUE(key_original->ExportPublicKey(&pubkey_info)); + ASSERT_TRUE(key_original->ExportPrivateKey(&key_info)); std::unique_ptr<crypto::ECPrivateKey> key( - crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - std::string(), key_info, pubkey_info)); - ASSERT_TRUE(key.get()); - ASSERT_TRUE(key->key() != NULL); + crypto::ECPrivateKey::CreateFromPrivateKeyInfo(key_info)); + ASSERT_TRUE(key); + ASSERT_TRUE(key->key()); std::unique_ptr<crypto::ECSignatureCreator> signer( crypto::ECSignatureCreator::Create(key.get())); - ASSERT_TRUE(signer.get()); + ASSERT_TRUE(signer); std::string data("Hello, World!"); std::vector<uint8_t> signature;
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 0c788e0..e48990b 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -276,7 +276,6 @@ "//ios/chrome/browser/tabs", "//ios/chrome/browser/tabs:tabs_internal", "//ios/chrome/browser/ui", - "//ios/chrome/browser/ui:browser_list", "//ios/chrome/browser/ui/webui:webui_internal", ] }
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.h b/ios/chrome/browser/downstream_chromium_browser_provider.h index 9f8e139e6..2e1e189 100644 --- a/ios/chrome/browser/downstream_chromium_browser_provider.h +++ b/ios/chrome/browser/downstream_chromium_browser_provider.h
@@ -19,7 +19,6 @@ // ChromeBrowserProvider implementations. All of these will move upstream // into ChromiumBrowserProvider eventually, and from there callers will be // converted to not go through the provider API at all. - bool IsOffTheRecordSessionActive() override; void GetFaviconForURL( ios::ChromeBrowserState* browser_state, const GURL& page_url,
diff --git a/ios/chrome/browser/downstream_chromium_browser_provider.mm b/ios/chrome/browser/downstream_chromium_browser_provider.mm index f4104d6..20a3056a 100644 --- a/ios/chrome/browser/downstream_chromium_browser_provider.mm +++ b/ios/chrome/browser/downstream_chromium_browser_provider.mm
@@ -11,17 +11,12 @@ #include "base/memory/ptr_util.h" #include "ios/chrome/browser/tabs/tab_model_synced_window_delegate_getter.h" -#import "ios/chrome/browser/ui/browser_list_ios.h" #include "ios/chrome/browser/ui/webui/chrome_web_ui_ios_controller_factory.h" DownstreamChromiumBrowserProvider::DownstreamChromiumBrowserProvider() {} DownstreamChromiumBrowserProvider::~DownstreamChromiumBrowserProvider() {} -bool DownstreamChromiumBrowserProvider::IsOffTheRecordSessionActive() { - return BrowserListIOS::IsOffTheRecordSessionActive(); -} - void DownstreamChromiumBrowserProvider::GetFaviconForURL( ios::ChromeBrowserState* browser_state, const GURL& page_url,
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn index a103be6..3232e1f 100644 --- a/ios/chrome/browser/metrics/BUILD.gn +++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -9,8 +9,8 @@ "field_trial_synchronizer.h", "ios_chrome_metrics_service_accessor.cc", "ios_chrome_metrics_service_accessor.h", - "ios_chrome_metrics_service_client.cc", "ios_chrome_metrics_service_client.h", + "ios_chrome_metrics_service_client.mm", "ios_chrome_metrics_services_manager_client.h", "ios_chrome_metrics_services_manager_client.mm", "ios_chrome_origins_seen_service_factory.cc", @@ -48,7 +48,7 @@ "//ios/chrome/browser/google", "//ios/chrome/browser/signin", "//ios/chrome/browser/sync", - "//ios/chrome/browser/ui", + "//ios/chrome/browser/ui:browser_list", "//ios/chrome/browser/variations", "//ios/chrome/browser/variations:ios_chrome_ui_string_overrider_factory", "//ios/chrome/common",
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm similarity index 81% rename from ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc rename to ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm index e0b8216..eebf255 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
@@ -51,7 +51,7 @@ #include "ios/chrome/browser/signin/ios_chrome_signin_status_metrics_provider_delegate.h" #include "ios/chrome/browser/sync/ios_chrome_sync_client.h" #include "ios/chrome/browser/tab_parenting_global_observer.h" -#include "ios/chrome/browser/ui/browser_otr_state.h" +#include "ios/chrome/browser/ui/browser_list_ios.h" #include "ios/chrome/common/channel_info.h" #include "ios/web/public/web_thread.h" @@ -152,11 +152,10 @@ std::unique_ptr<metrics::MetricsLogUploader> IOSChromeMetricsServiceClient::CreateUploader( const base::Callback<void(int)>& on_upload_complete) { - return std::unique_ptr<metrics::MetricsLogUploader>( - new metrics::NetMetricsLogUploader( - GetApplicationContext()->GetSystemURLRequestContext(), - metrics::kDefaultMetricsServerUrl, metrics::kDefaultMetricsMimeType, - on_upload_complete)); + return base::MakeUnique<metrics::NetMetricsLogUploader>( + GetApplicationContext()->GetSystemURLRequestContext(), + metrics::kDefaultMetricsServerUrl, metrics::kDefaultMetricsMimeType, + on_upload_complete); } base::TimeDelta IOSChromeMetricsServiceClient::GetStandardUploadInterval() { @@ -182,63 +181,69 @@ } void IOSChromeMetricsServiceClient::Initialize() { - metrics_service_.reset(new metrics::MetricsService( - metrics_state_manager_, this, GetApplicationContext()->GetLocalState())); + metrics_service_ = base::MakeUnique<metrics::MetricsService>( + metrics_state_manager_, this, GetApplicationContext()->GetLocalState()); // Register metrics providers. metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new metrics::NetworkMetricsProvider( - web::WebThread::GetBlockingPool()))); + base::MakeUnique<metrics::NetworkMetricsProvider>( + web::WebThread::GetBlockingPool())); // Currently, we configure OmniboxMetricsProvider to not log events to UMA // if there is a single incognito session visible. In the future, it may // be worth revisiting this to still log events from non-incognito sessions. metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>(new OmniboxMetricsProvider( - base::Bind(&::IsOffTheRecordSessionActive)))); + base::MakeUnique<OmniboxMetricsProvider>( + base::Bind(&BrowserListIOS::IsOffTheRecordSessionActive))); - stability_metrics_provider_ = new IOSChromeStabilityMetricsProvider( - GetApplicationContext()->GetLocalState()); - metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>(stability_metrics_provider_)); + { + auto stability_metrics_provider = + base::MakeUnique<IOSChromeStabilityMetricsProvider>( + GetApplicationContext()->GetLocalState()); + stability_metrics_provider_ = stability_metrics_provider.get(); + metrics_service_->RegisterMetricsProvider( + std::move(stability_metrics_provider)); + } metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new metrics::ScreenInfoMetricsProvider)); + base::MakeUnique<metrics::ScreenInfoMetricsProvider>()); - drive_metrics_provider_ = new metrics::DriveMetricsProvider( - web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE), - ios::FILE_LOCAL_STATE); - metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>(drive_metrics_provider_)); + { + auto drive_metrics_provider = + base::MakeUnique<metrics::DriveMetricsProvider>( + web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE), + ios::FILE_LOCAL_STATE); + drive_metrics_provider_ = drive_metrics_provider.get(); + metrics_service_->RegisterMetricsProvider( + std::move(drive_metrics_provider)); + } - profiler_metrics_provider_ = new metrics::ProfilerMetricsProvider( - base::Bind(&metrics::IsCellularLogicEnabled)); - metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>(profiler_metrics_provider_)); + { + auto profiler_metrics_provider = + base::MakeUnique<metrics::ProfilerMetricsProvider>( + base::Bind(&metrics::IsCellularLogicEnabled)); + profiler_metrics_provider_ = profiler_metrics_provider.get(); + metrics_service_->RegisterMetricsProvider( + std::move(profiler_metrics_provider)); + } metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new metrics::CallStackProfileMetricsProvider)); + base::MakeUnique<metrics::CallStackProfileMetricsProvider>()); metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - SigninStatusMetricsProvider::CreateInstance(base::WrapUnique( - new IOSChromeSigninStatusMetricsProviderDelegate)))); + SigninStatusMetricsProvider::CreateInstance( + base::MakeUnique<IOSChromeSigninStatusMetricsProviderDelegate>())); metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new MobileSessionShutdownMetricsProvider(metrics_service_.get()))); + base::MakeUnique<MobileSessionShutdownMetricsProvider>( + metrics_service_.get())); metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new syncer::DeviceCountMetricsProvider( - base::Bind(&IOSChromeSyncClient::GetDeviceInfoTrackers)))); + base::MakeUnique<syncer::DeviceCountMetricsProvider>( + base::Bind(&IOSChromeSyncClient::GetDeviceInfoTrackers))); metrics_service_->RegisterMetricsProvider( - std::unique_ptr<metrics::MetricsProvider>( - new translate::TranslateRankerMetricsProvider())); + base::MakeUnique<translate::TranslateRankerMetricsProvider>()); } void IOSChromeMetricsServiceClient::OnInitTaskGotDriveMetrics() {
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm index 1afc1478..d528c47 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
@@ -16,7 +16,7 @@ #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_accessor.h" #include "ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h" -#include "ios/chrome/browser/ui/browser_otr_state.h" +#include "ios/chrome/browser/ui/browser_list_ios.h" #include "ios/chrome/browser/variations/ios_chrome_variations_service_client.h" #include "ios/chrome/browser/variations/ios_ui_string_overrider_factory.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" @@ -50,7 +50,8 @@ IOSChromeMetricsServicesManagerClient::IOSChromeMetricsServicesManagerClient( PrefService* local_state) - : enabled_state_provider_(new IOSChromeEnabledStateProvider()), + : enabled_state_provider_( + base::MakeUnique<IOSChromeEnabledStateProvider>()), local_state_(local_state) { DCHECK(local_state); } @@ -62,7 +63,7 @@ IOSChromeMetricsServicesManagerClient::CreateRapporServiceImpl() { DCHECK(thread_checker_.CalledOnValidThread()); return base::MakeUnique<rappor::RapporServiceImpl>( - local_state_, base::Bind(&::IsOffTheRecordSessionActive)); + local_state_, base::Bind(&BrowserListIOS::IsOffTheRecordSessionActive)); } std::unique_ptr<variations::VariationsService> @@ -73,7 +74,7 @@ // a dummy value for the name of the switch that disables background // networking. return variations::VariationsService::Create( - base::WrapUnique(new IOSChromeVariationsServiceClient), local_state_, + base::MakeUnique<IOSChromeVariationsServiceClient>(), local_state_, GetMetricsStateManager(), "dummy-disable-background-switch", ::CreateUIStringOverrider()); }
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index 5c68334..90523244 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -24,8 +24,6 @@ "animation_util.mm", "background_generator.h", "background_generator.mm", - "browser_otr_state.h", - "browser_otr_state.mm", "favicon_view.h", "favicon_view.mm", "file_locations.h", @@ -59,7 +57,6 @@ "//ios/chrome/browser", "//ios/chrome/browser/favicon", "//ios/chrome/browser/ui/commands", - "//ios/public/provider/chrome/browser", "//ios/web", "//ui/base", "//ui/gfx",
diff --git a/ios/chrome/browser/ui/browser_otr_state.h b/ios/chrome/browser/ui/browser_otr_state.h deleted file mode 100644 index 7a53f0f..0000000 --- a/ios/chrome/browser/ui/browser_otr_state.h +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2015 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. - -#ifndef IOS_CHROME_BROWSER_UI_BROWSER_OTR_STATE_H_ -#define IOS_CHROME_BROWSER_UI_BROWSER_OTR_STATE_H_ - -// Returns whether there is any Off-The-Record session in progress. -bool IsOffTheRecordSessionActive(); - -#endif // IOS_CHROME_BROWSER_UI_BROWSER_OTR_STATE_H_
diff --git a/ios/chrome/browser/ui/browser_otr_state.mm b/ios/chrome/browser/ui/browser_otr_state.mm deleted file mode 100644 index 9431105..0000000 --- a/ios/chrome/browser/ui/browser_otr_state.mm +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2015 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. - -#include "ios/chrome/browser/ui/browser_otr_state.h" - -#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -bool IsOffTheRecordSessionActive() { - ios::ChromeBrowserProvider* chrome_browser_provider = - ios::GetChromeBrowserProvider(); - return chrome_browser_provider && - chrome_browser_provider->IsOffTheRecordSessionActive(); -}
diff --git a/ios/chrome/browser/ui/history/BUILD.gn b/ios/chrome/browser/ui/history/BUILD.gn index 31702128..9a842bc 100644 --- a/ios/chrome/browser/ui/history/BUILD.gn +++ b/ios/chrome/browser/ui/history/BUILD.gn
@@ -66,6 +66,7 @@ "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/context_menu", "//ios/chrome/browser/ui/icons", + "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/ntp/recent_tabs/views", "//ios/chrome/browser/ui/popup_menu",
diff --git a/ios/chrome/browser/ui/history/history_panel_view_controller.mm b/ios/chrome/browser/ui/history/history_panel_view_controller.mm index 41be2fa..158840f 100644 --- a/ios/chrome/browser/ui/history/history_panel_view_controller.mm +++ b/ios/chrome/browser/ui/history/history_panel_view_controller.mm
@@ -6,12 +6,14 @@ #include "base/ios/block_types.h" #include "base/ios/ios_util.h" +#include "base/ios/weak_nsobject.h" #include "base/mac/scoped_nsobject.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ui/history/clear_browsing_bar.h" #import "ios/chrome/browser/ui/history/history_collection_view_controller.h" #import "ios/chrome/browser/ui/history/history_search_view_controller.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" +#import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/ui/material_components/utils.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/views/panel_bar_view.h" #import "ios/chrome/browser/ui/show_privacy_settings_util.h" @@ -378,4 +380,16 @@ [_historyCollectionController hasHistoryEntries]; } +#pragma mark - UIResponder + +- (NSArray*)keyCommands { + base::WeakNSObject<HistoryPanelViewController> weakSelf(self); + return @[ [UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape + modifierFlags:Cr_UIKeyModifierNone + title:nil + action:^{ + [weakSelf closeHistory]; + }] ]; +} + @end
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm b/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm index 73ee56c7..8aee9c9 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm
@@ -106,7 +106,7 @@ DCHECK(browserState); [_label setText:text]; self.accessibilityLabel = [_label accessibilityLabel]; - ios_internal::GetFavicon(url, browserState, ^(UIImage* newIcon) { + TabSwitcherGetFavicon(url, browserState, ^(UIImage* newIcon) { [_favicon setImage:newIcon]; }); }
diff --git a/ios/chrome/browser/ui/reading_list/BUILD.gn b/ios/chrome/browser/ui/reading_list/BUILD.gn index c7e7c071..abf601f 100644 --- a/ios/chrome/browser/ui/reading_list/BUILD.gn +++ b/ios/chrome/browser/ui/reading_list/BUILD.gn
@@ -61,6 +61,7 @@ "//ios/chrome/browser/ui/alert_coordinator", "//ios/chrome/browser/ui/collection_view/cells", "//ios/chrome/browser/ui/colors", + "//ios/chrome/browser/ui/keyboard", "//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/reading_list:resources", "//ios/chrome/browser/ui/side_swipe",
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h index 4b11dd46..262f185 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h +++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.h
@@ -20,12 +20,15 @@ @class TabModel; // Audience for the ReadingListViewController, managing the visibility of the -// toolbar. +// toolbar and dismissing the Reading List View. @protocol ReadingListViewControllerAudience<NSObject> // Whether the collection has items. - (void)setCollectionHasItems:(BOOL)hasItems; +// Dismisses the Reading List View. +- (void)dismiss; + @end @interface ReadingListViewController @@ -51,11 +54,4 @@ @end -@interface ReadingListViewController (Testing) - -// Dismisses this view controller. -- (void)dismiss; - -@end - #endif // IOS_CHROME_BROWSER_UI_READING_LIST_READING_LIST_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm index 607efd35..8887f81 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller.mm
@@ -447,8 +447,7 @@ // Reset observer to prevent further model update notifications. _modelBridge.reset(); [_actionSheet stop]; - [self.presentingViewController dismissViewControllerAnimated:YES - completion:nil]; + [self.audience dismiss]; } - (void)loadModel {
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_view_controller_container.mm b/ios/chrome/browser/ui/reading_list/reading_list_view_controller_container.mm index e2155397..52ffd42 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_view_controller_container.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_view_controller_container.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/ui/reading_list/reading_list_view_controller_container.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" +#import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/ui/reading_list/reading_list_toolbar.h" #import "ios/chrome/browser/ui/reading_list/reading_list_view_controller.h" @@ -83,7 +84,7 @@ constraint.active = YES; } -#pragma mark - ReadingListViewControllerDelegate +#pragma mark - ReadingListViewControllerAudience - (void)setCollectionHasItems:(BOOL)hasItems { if (hasItems) { @@ -110,6 +111,11 @@ } } +- (void)dismiss { + [self.presentingViewController dismissViewControllerAnimated:YES + completion:nil]; +} + #pragma mark - ReadingListToolbarActionTarget - (void)markPressed { @@ -144,4 +150,16 @@ }); } +#pragma mark - UIResponder + +- (NSArray*)keyCommands { + __weak ReadingListViewControllerContainer* weakSelf = self; + return @[ [UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape + modifierFlags:Cr_UIKeyModifierNone + title:nil + action:^{ + [weakSelf dismiss]; + }] ]; +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/BUILD.gn index ded140ce..e5cfbf46 100644 --- a/ios/chrome/browser/ui/tab_switcher/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/BUILD.gn
@@ -51,8 +51,6 @@ source_set("tab_switcher") { sources = [ - "session_changes.h", - "session_changes.mm", "tab_model_snapshot.h", "tab_model_snapshot.mm", "tab_switcher.h", @@ -81,6 +79,8 @@ "tab_switcher_panel_view.mm", "tab_switcher_session_cell_data.h", "tab_switcher_session_cell_data.mm", + "tab_switcher_session_changes.h", + "tab_switcher_session_changes.mm", "tab_switcher_tab_strip_placeholder_view.h", "tab_switcher_tab_strip_placeholder_view.mm", "tab_switcher_transition_context.h",
diff --git a/ios/chrome/browser/ui/tab_switcher/session_changes.h b/ios/chrome/browser/ui/tab_switcher/session_changes.h deleted file mode 100644 index a765f4f..0000000 --- a/ios/chrome/browser/ui/tab_switcher/session_changes.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2016 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. - -#ifndef IOS_CHROME_BROWSER_UI_TAB_SWITCHER_SESSION_CHANGES_H_ -#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_SESSION_CHANGES_H_ - -#include <vector> - -namespace ios_internal { - -// This structure represents the changes a session undergoes. -// It is used to update the UICollectionView showing a set of tabs. -class SessionChanges { - public: - SessionChanges(std::vector<size_t> const& tabHashesInInitialState, - std::vector<size_t> const& tabHashesInFinalState); - ~SessionChanges(); - SessionChanges(const SessionChanges& sessionChanges) = delete; - SessionChanges& operator=(const SessionChanges& sessionChanges) = delete; - - std::vector<size_t> const& deletions() const; - std::vector<size_t> const& insertions() const; - std::vector<size_t> const& updates() const; - - bool hasChanges() const; - - private: - // Those vectors contain indexes of tabs. - // The indexes are relative to a tab model snapshot, or a distant session. - // To be in accordance with the UICollectionView's |performBatchUpdates| - // method: - // -the indexes in |updates| are relative to the previous state of the - // session. - // -the indexes in |deletions| are relative to the previous state of the - // session. - // -the indexes in |insertions| are relative to the final state of the - // session. - std::vector<size_t> deletions_; - std::vector<size_t> insertions_; - std::vector<size_t> updates_; -}; - -} // namespace ios_internal - -#endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_SESSION_CHANGES_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/session_changes.mm b/ios/chrome/browser/ui/tab_switcher/session_changes.mm deleted file mode 100644 index 3e06b52..0000000 --- a/ios/chrome/browser/ui/tab_switcher/session_changes.mm +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 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. - -#import "ios/chrome/browser/ui/tab_switcher/session_changes.h" - -#import "ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h" - -namespace ios_internal { - -SessionChanges::SessionChanges( - std::vector<size_t> const& tabHashesInInitialState, - std::vector<size_t> const& tabHashesInFinalState) { - ios_internal::MinimalReplacementOperations(tabHashesInInitialState, - tabHashesInFinalState, &updates_, - &deletions_, &insertions_); -} - -SessionChanges::~SessionChanges() {} - -std::vector<size_t> const& SessionChanges::deletions() const { - return deletions_; -} -std::vector<size_t> const& SessionChanges::insertions() const { - return insertions_; -} -std::vector<size_t> const& SessionChanges::updates() const { - return updates_; -} - -bool SessionChanges::hasChanges() const { - return updates_.size() || deletions_.size() || insertions_.size(); -} - -} // namespace ios_internal
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm index 16060190..6fb47212 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
@@ -31,7 +31,6 @@ #import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_off_view.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_on_no_sessions_view.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_out_view.h" -#import "ios/chrome/browser/ui/tab_switcher/session_changes.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_model.h" @@ -136,12 +135,12 @@ - (NSInteger)currentPanelIndex; // Returns the session type of the panel and the given index. -- (ios_internal::SessionType)sessionTypeForPanelIndex:(NSInteger)panelIndex; +- (TabSwitcherSessionType)sessionTypeForPanelIndex:(NSInteger)panelIndex; // Returns the tab model corresponding to the given session type. // There is no tab model for distant sessions so it returns nil for distant // sessions type. -- (TabModel*)tabModelForSessionType:(ios_internal::SessionType)sessionType; +- (TabModel*)tabModelForSessionType:(TabSwitcherSessionType)sessionType; // Returns the tab model of the currently selected tab. - (TabModel*)currentSelectedModel; @@ -207,13 +206,13 @@ [self loadTabSwitcherView]; _onTheRecordSession.reset([[TabSwitcherPanelController alloc] initWithModel:_tabSwitcherModel - forLocalSessionOfType:ios_internal::SessionType::REGULAR_SESSION + forLocalSessionOfType:TabSwitcherSessionType::REGULAR_SESSION withCache:_cache browserState:_browserState]); [_onTheRecordSession setDelegate:self]; _offTheRecordSession.reset([[TabSwitcherPanelController alloc] initWithModel:_tabSwitcherModel - forLocalSessionOfType:ios_internal::SessionType::OFF_THE_RECORD_SESSION + forLocalSessionOfType:TabSwitcherSessionType::OFF_THE_RECORD_SESSION withCache:_cache browserState:_browserState]); [_offTheRecordSession setDelegate:self]; @@ -392,10 +391,10 @@ : kLocalTabsOffTheRecordPanelIndex; [_tabSwitcherView selectPanelAtIndex:panelIndex]; - const ios_internal::SessionType panelSessionType = + const TabSwitcherSessionType panelSessionType = (command == IDC_NEW_TAB) - ? ios_internal::SessionType::REGULAR_SESSION - : ios_internal::SessionType::OFF_THE_RECORD_SESSION; + ? TabSwitcherSessionType::REGULAR_SESSION + : TabSwitcherSessionType::OFF_THE_RECORD_SESSION; TabModel* model = [self tabModelForSessionType:panelSessionType]; [self dismissWithNewTabAnimation:GURL(kChromeUINewTabURL) @@ -737,23 +736,23 @@ return kSignInPromoPanelIndex + 1; } -- (ios_internal::SessionType)sessionTypeForPanelIndex:(NSInteger)panelIndex { +- (TabSwitcherSessionType)sessionTypeForPanelIndex:(NSInteger)panelIndex { if (panelIndex == kLocalTabsOffTheRecordPanelIndex) - return ios_internal::SessionType::OFF_THE_RECORD_SESSION; + return TabSwitcherSessionType::OFF_THE_RECORD_SESSION; if (panelIndex == kLocalTabsOnTheRecordPanelIndex) - return ios_internal::SessionType::REGULAR_SESSION; - return ios_internal::SessionType::DISTANT_SESSION; + return TabSwitcherSessionType::REGULAR_SESSION; + return TabSwitcherSessionType::DISTANT_SESSION; } -- (TabModel*)tabModelForSessionType:(ios_internal::SessionType)sessionType { +- (TabModel*)tabModelForSessionType:(TabSwitcherSessionType)sessionType { switch (sessionType) { - case ios_internal::SessionType::REGULAR_SESSION: + case TabSwitcherSessionType::REGULAR_SESSION: return [_tabSwitcherModel mainTabModel]; break; - case ios_internal::SessionType::OFF_THE_RECORD_SESSION: + case TabSwitcherSessionType::OFF_THE_RECORD_SESSION: return [_tabSwitcherModel otrTabModel]; break; - case ios_internal::SessionType::DISTANT_SESSION: + case TabSwitcherSessionType::DISTANT_SESSION: return nil; break; } @@ -761,7 +760,7 @@ - (TabModel*)currentSelectedModel { const NSInteger currentPanelIndex = [self currentPanelIndex]; - const ios_internal::SessionType sessionType = + const TabSwitcherSessionType sessionType = [self sessionTypeForPanelIndex:currentPanelIndex]; TabModel* model = [self tabModelForSessionType:sessionType]; if (!model) @@ -1003,11 +1002,11 @@ } } -- (void)localSessionMayNeedUpdate:(ios_internal::SessionType)type { - if (type == ios_internal::SessionType::REGULAR_SESSION) { +- (void)localSessionMayNeedUpdate:(TabSwitcherSessionType)type { + if (type == TabSwitcherSessionType::REGULAR_SESSION) { [_onTheRecordSession updateCollectionViewIfNeeded]; } else { - DCHECK(type == ios_internal::SessionType::OFF_THE_RECORD_SESSION); + DCHECK(type == TabSwitcherSessionType::OFF_THE_RECORD_SESSION); [_offTheRecordSession updateCollectionViewIfNeeded]; } } @@ -1042,13 +1041,13 @@ } - (CGSize)sizeForItemAtIndex:(NSUInteger)index - inSession:(ios_internal::SessionType)session { + inSession:(TabSwitcherSessionType)session { switch (session) { - case ios_internal::SessionType::OFF_THE_RECORD_SESSION: + case TabSwitcherSessionType::OFF_THE_RECORD_SESSION: return [[_offTheRecordSession view] cellSize]; - case ios_internal::SessionType::REGULAR_SESSION: + case TabSwitcherSessionType::REGULAR_SESSION: return [[_onTheRecordSession view] cellSize]; - case ios_internal::SessionType::DISTANT_SESSION: + case TabSwitcherSessionType::DISTANT_SESSION: NOTREACHED(); return {}; } @@ -1085,16 +1084,16 @@ return [_tabSwitcherModel sessionCount] + promoPanel; } -- (SessionCellData*)sessionCellDataAtIndex:(NSUInteger)index { +- (TabSwitcherSessionCellData*)sessionCellDataAtIndex:(NSUInteger)index { if (index == kLocalTabsOffTheRecordPanelIndex) { // If has incognito tabs return incognito cell data. - return [SessionCellData incognitoSessionCellData]; + return [TabSwitcherSessionCellData incognitoSessionCellData]; } else if (index == kLocalTabsOnTheRecordPanelIndex) { - return [SessionCellData openTabSessionCellData]; + return [TabSwitcherSessionCellData openTabSessionCellData]; } else { if (![_tabSwitcherModel distantSessionCount]) { // Display promo panel cell if there is no distant sessions. - return [SessionCellData otherDevicesSessionCellData]; + return [TabSwitcherSessionCellData otherDevicesSessionCellData]; } else { index -= kHeaderDistantSessionIndexOffset; @@ -1110,20 +1109,21 @@ deviceType = distantSession->device_type; cellTitle = base::SysUTF8ToNSString(distantSession->name); } - ios_internal::SessionCellType cellType; + TabSwitcherSessionCellType cellType; switch (deviceType) { case sync_sessions::SyncedSession::TYPE_PHONE: - cellType = ios_internal::kPhoneRemoteSessionCell; + cellType = kPhoneRemoteSessionCell; break; case sync_sessions::SyncedSession::TYPE_TABLET: - cellType = ios_internal::kTabletRemoteSessionCell; + cellType = kTabletRemoteSessionCell; break; default: - cellType = ios_internal::kLaptopRemoteSessionCell; + cellType = kLaptopRemoteSessionCell; break; } - SessionCellData* sessionData = [[[SessionCellData alloc] - initWithSessionCellType:cellType] autorelease]; + TabSwitcherSessionCellData* sessionData = + [[[TabSwitcherSessionCellData alloc] initWithSessionCellType:cellType] + autorelease]; sessionData.title = cellTitle; return sessionData; } @@ -1207,14 +1207,14 @@ (TabSwitcherPanelController*)tabSwitcherPanelController didSelectLocalTab:(Tab*)tab { DCHECK(tab); - const ios_internal::SessionType panelSessionType = + const TabSwitcherSessionType panelSessionType = tabSwitcherPanelController.sessionType; TabModel* tabModel = [self tabModelForSessionType:panelSessionType]; [tabModel setCurrentTab:tab]; [self.delegate tabSwitcher:self dismissTransitionWillStartWithActiveModel:tabModel]; [self tabSwitcherDismissWithModel:tabModel]; - if (panelSessionType == ios_internal::SessionType::OFF_THE_RECORD_SESSION) { + if (panelSessionType == TabSwitcherSessionType::OFF_THE_RECORD_SESSION) { base::RecordAction( base::UserMetricsAction("MobileTabSwitcherOpenIncognitoTab")); } else { @@ -1227,10 +1227,10 @@ (TabSwitcherPanelController*)tabSwitcherPanelController didCloseLocalTab:(Tab*)tab { DCHECK(tab); - const ios_internal::SessionType panelSessionType = + const TabSwitcherSessionType panelSessionType = tabSwitcherPanelController.sessionType; [tab close]; - if (panelSessionType == ios_internal::SessionType::OFF_THE_RECORD_SESSION) { + if (panelSessionType == TabSwitcherSessionType::OFF_THE_RECORD_SESSION) { base::RecordAction( base::UserMetricsAction("MobileTabSwitcherCloseIncognitoTab")); } else {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h index d16157db..7b30d0669 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.h
@@ -7,7 +7,7 @@ #import <UIKit/UIKit.h> -@class SessionCellData; +@class TabSwitcherSessionCellData; // This class is the cell class used in the table view of the tab switcher // header. @@ -16,8 +16,8 @@ // Default table view cell identifier. + (NSString*)identifier; -// Load the cell content using the given SessionCellData object. -- (void)loadSessionCellData:(SessionCellData*)sessionCellData; +// Load the cell content using the given TabSwitcherSessionCellData object. +- (void)loadSessionCellData:(TabSwitcherSessionCellData*)sessionCellData; @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.mm index a45bad0..2638016 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_cell.mm
@@ -43,7 +43,7 @@ return [[self class] identifier]; } -- (void)loadSessionCellData:(SessionCellData*)sessionCellData { +- (void)loadSessionCellData:(TabSwitcherSessionCellData*)sessionCellData { [_imageView setImage:sessionCellData.image]; [_label setText:sessionCellData.title]; [self setNeedsLayout];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h index c37ad7b..374794c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.h
@@ -9,7 +9,7 @@ #include "base/ios/block_types.h" -@class SessionCellData; +@class TabSwitcherSessionCellData; @class TabSwitcherHeaderView; @protocol TabSwitcherHeaderViewDelegate<NSObject> @@ -25,7 +25,7 @@ @protocol TabSwitcherHeaderViewDataSource<NSObject> - (NSInteger)tabSwitcherHeaderViewSessionCount; -- (SessionCellData*)sessionCellDataAtIndex:(NSUInteger)index; +- (TabSwitcherSessionCellData*)sessionCellDataAtIndex:(NSUInteger)index; @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.mm index bcaec65..140d6ead 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_header_view.mm
@@ -334,7 +334,7 @@ - (NSString*)panelTitleAtIndex:(NSInteger)index { NSIndexPath* indexPath = [NSIndexPath indexPathForItem:index inSection:0]; - SessionCellData* sessionCellData = + TabSwitcherSessionCellData* sessionCellData = [[self dataSource] sessionCellDataAtIndex:indexPath.row]; return sessionCellData.title; } @@ -373,7 +373,7 @@ TabSwitcherHeaderCell* headerCell = [collectionView dequeueReusableCellWithReuseIdentifier:[TabSwitcherHeaderCell identifier] forIndexPath:indexPath]; - SessionCellData* sessionCellData = + TabSwitcherSessionCellData* sessionCellData = [[self dataSource] sessionCellDataAtIndex:indexPath.row]; [headerCell loadSessionCellData:sessionCellData]; return headerCell;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.h index a684735..d065e92 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.h
@@ -15,6 +15,7 @@ #import "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions_bridge.h" #import "ios/chrome/browser/ui/tab_switcher/tab_model_snapshot.h" +class ChromeBrowserState; @class TabModel; @class TabSwitcherCache; @@ -26,21 +27,15 @@ NO_PANEL, }; -namespace ios_internal { - -enum class SessionType { +enum class TabSwitcherSessionType { OFF_THE_RECORD_SESSION, REGULAR_SESSION, DISTANT_SESSION }; -class ChromeBrowserState; - // Returns true if the session type is a local session. A local session is a // "regular session" or an "off the record" session. -bool IsLocalSession(SessionType sessionType); - -} // namespace ios_internal +bool TabSwitcherSessionTypeIsLocalSession(TabSwitcherSessionType sessionType); // Protocol to observe changes to the TabSwitcherModel. @protocol TabSwitcherModelDelegate<NSObject> @@ -51,12 +46,12 @@ // Called when the distant session with the tag |tag| may need to be updated. - (void)distantSessionMayNeedUpdate:(std::string const&)tag; // Called when a local session of type |type| needs to be updated. -- (void)localSessionMayNeedUpdate:(ios_internal::SessionType)type; +- (void)localSessionMayNeedUpdate:(TabSwitcherSessionType)type; // Called when the signed-in panel (if any) must change. - (void)signInPanelChangedTo:(TabSwitcherSignInPanelsType)panelType; // Called to retrieve the size of the item at the |index| in |session|. - (CGSize)sizeForItemAtIndex:(NSUInteger)index - inSession:(ios_internal::SessionType)session; + inSession:(TabSwitcherSessionType)session; @end // This class serves as a bridge between Chrome-level data (CLD), and what is @@ -90,7 +85,7 @@ - (ios::ChromeBrowserState*)browserState; // Returns the latest data for the local session of type |type|. - (std::unique_ptr<TabModelSnapshot>)tabModelSnapshotForLocalSession: - (ios_internal::SessionType)type; + (TabSwitcherSessionType)type; // Returns the latest data for the distant session of tag |tag|. - (std::unique_ptr<const synced_sessions::DistantSession>)distantSessionForTag: (std::string const&)tag;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.mm index 6f1a4e5d..3024a2f 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model.mm
@@ -18,21 +18,16 @@ #import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab_model.h" #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" -#import "ios/chrome/browser/ui/tab_switcher/session_changes.h" #import "ios/chrome/browser/ui/tab_switcher/tab_model_snapshot.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_model_private.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h" -namespace ios_internal { - -bool IsLocalSession(SessionType sessionType) { - return sessionType == SessionType::OFF_THE_RECORD_SESSION || - sessionType == SessionType::REGULAR_SESSION; +bool TabSwitcherSessionTypeIsLocalSession(TabSwitcherSessionType sessionType) { + return sessionType == TabSwitcherSessionType::OFF_THE_RECORD_SESSION || + sessionType == TabSwitcherSessionType::REGULAR_SESSION; } -} // namespace ios_internal - namespace { class TagAndIndex { @@ -77,7 +72,7 @@ // Returns the type of the local session corresponding to the given |tabModel|. // |tabModel| MUST be equal to either |_mainTabModel|, or |_otrTabModel|. -- (ios_internal::SessionType)typeOfLocalSessionForTabModel:(TabModel*)tabModel; +- (TabSwitcherSessionType)typeOfLocalSessionForTabModel:(TabModel*)tabModel; @end @implementation TabSwitcherModel @@ -153,33 +148,32 @@ return _browserState; } -- (TabModel*)tabModelForSessionOfType:(ios_internal::SessionType)type { - DCHECK(type == ios_internal::SessionType::OFF_THE_RECORD_SESSION || - type == ios_internal::SessionType::REGULAR_SESSION); - return type == ios_internal::SessionType::OFF_THE_RECORD_SESSION - ? _otrTabModel - : _mainTabModel; +- (TabModel*)tabModelForSessionOfType:(TabSwitcherSessionType)type { + DCHECK(type == TabSwitcherSessionType::OFF_THE_RECORD_SESSION || + type == TabSwitcherSessionType::REGULAR_SESSION); + return type == TabSwitcherSessionType::OFF_THE_RECORD_SESSION ? _otrTabModel + : _mainTabModel; } -- (NSInteger)numberOfTabsInLocalSessionOfType:(ios_internal::SessionType)type { +- (NSInteger)numberOfTabsInLocalSessionOfType:(TabSwitcherSessionType)type { TabModelSnapshot* tabModelSnapshot = [self tabModelSnapshotForSession:type]; return tabModelSnapshot->tabs().size(); } - (Tab*)tabAtIndex:(NSUInteger)index - inLocalSessionOfType:(ios_internal::SessionType)type { + inLocalSessionOfType:(TabSwitcherSessionType)type { TabModelSnapshot* tabModelSnapshot = [self tabModelSnapshotForSession:type]; return tabModelSnapshot->tabs()[index]; } - (std::unique_ptr<TabModelSnapshot>)tabModelSnapshotForLocalSession: - (ios_internal::SessionType)type { + (TabSwitcherSessionType)type { TabModel* tm = nullptr; switch (type) { - case ios_internal::SessionType::OFF_THE_RECORD_SESSION: + case TabSwitcherSessionType::OFF_THE_RECORD_SESSION: tm = _otrTabModel; break; - case ios_internal::SessionType::REGULAR_SESSION: + case TabSwitcherSessionType::REGULAR_SESSION: tm = _mainTabModel; break; default: @@ -316,19 +310,18 @@ } } -- (ios_internal::SessionType)typeOfLocalSessionForTabModel:(TabModel*)tabModel { +- (TabSwitcherSessionType)typeOfLocalSessionForTabModel:(TabModel*)tabModel { DCHECK(tabModel == _mainTabModel || tabModel == _otrTabModel); if (tabModel == _otrTabModel) - return ios_internal::SessionType::OFF_THE_RECORD_SESSION; - return ios_internal::SessionType::REGULAR_SESSION; + return TabSwitcherSessionType::OFF_THE_RECORD_SESSION; + return TabSwitcherSessionType::REGULAR_SESSION; } -- (TabModelSnapshot*)tabModelSnapshotForSession: - (ios_internal::SessionType)type { +- (TabModelSnapshot*)tabModelSnapshotForSession:(TabSwitcherSessionType)type { switch (type) { - case ios_internal::SessionType::OFF_THE_RECORD_SESSION: + case TabSwitcherSessionType::OFF_THE_RECORD_SESSION: return _otrTabModelSnapshot.get(); - case ios_internal::SessionType::REGULAR_SESSION: + case TabSwitcherSessionType::REGULAR_SESSION: return _mainTabModelSnapshot.get(); default: NOTREACHED(); @@ -338,12 +331,12 @@ } - (void)setTabModelSnapshot:(std::unique_ptr<TabModelSnapshot>)tabModelSnapshot - forSession:(ios_internal::SessionType)type { + forSession:(TabSwitcherSessionType)type { switch (type) { - case ios_internal::SessionType::OFF_THE_RECORD_SESSION: + case TabSwitcherSessionType::OFF_THE_RECORD_SESSION: _otrTabModelSnapshot = std::move(tabModelSnapshot); break; - case ios_internal::SessionType::REGULAR_SESSION: + case TabSwitcherSessionType::REGULAR_SESSION: _mainTabModelSnapshot = std::move(tabModelSnapshot); break; default: @@ -353,7 +346,7 @@ } - (void)tabModelChanged:(TabModel*)tabModel { - ios_internal::SessionType sessionType = + TabSwitcherSessionType sessionType = [self typeOfLocalSessionForTabModel:tabModel]; [_delegate localSessionMayNeedUpdate:sessionType]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model_unittest.mm index 08e5726..7eccd8e 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_model_unittest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_model_unittest.mm
@@ -9,7 +9,6 @@ #include "base/strings/utf_string_conversions.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" -#include "ios/chrome/browser/ui/tab_switcher/session_changes.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_model_private.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h" #include "testing/platform_test.h" @@ -17,13 +16,6 @@ namespace { -// A lightweight SessionChanges. -struct LightSessionChanges { - std::vector<int> updates; - std::vector<int> deletions; - std::vector<int> insertions; -}; - // A lightweight DistantTab. class LightDT { public: @@ -88,7 +80,7 @@ EXPECT_EQ(1UL, _expectedTagsOfTheSessionsNeedingUpdates.erase(tag)); } -- (void)localSessionMayNeedUpdate:(ios_internal::SessionType)type { +- (void)localSessionMayNeedUpdate:(TabSwitcherSessionType)type { NOTREACHED(); } @@ -96,7 +88,7 @@ NOTREACHED(); } - (CGSize)sizeForItemAtIndex:(NSUInteger)index - inSession:(ios_internal::SessionType)session { + inSession:(TabSwitcherSessionType)session { return CGSizeZero; } @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h index 79be1ad2..42d3249 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h
@@ -43,7 +43,7 @@ // Sets the cell's appearance using information in |tab|. - (void)setAppearanceForTab:(Tab*)tab cellSize:(CGSize)cellSize; // Sets the cell's appearance depending on |type|. -- (void)setSessionType:(ios_internal::SessionType)type; +- (void)setSessionType:(TabSwitcherSessionType)type; // Sets the cell's delegate. - (void)setDelegate:(id<SessionCellDelegate>)delegate;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm index d38f3245..d0361e39 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm
@@ -239,12 +239,12 @@ }]; } -- (void)setSessionType:(ios_internal::SessionType)type { +- (void)setSessionType:(TabSwitcherSessionType)type { UIColor* topBarBackgroundColor; UIColor* closeButtonTintColor; UIColor* textColor; UIColor* snapshotBackgroundColor; - if (type == ios_internal::SessionType::OFF_THE_RECORD_SESSION) { + if (type == TabSwitcherSessionType::OFF_THE_RECORD_SESSION) { topBarBackgroundColor = [[MDCPalette greyPalette] tint700]; closeButtonTintColor = [[MDCPalette greyPalette] tint100]; textColor = [[MDCPalette greyPalette] tint100]; @@ -398,7 +398,7 @@ - (void)setSessionGURL:(GURL const&)gurl withBrowserState:(ios::ChromeBrowserState*)browserState { - ios_internal::FaviconGetterCompletionBlock block = ^(UIImage* favicon) { + TabSwitcherFaviconGetterCompletionBlock block = ^(UIImage* favicon) { UIColor* imageDominantColor = DominantColorForImage(gfx::Image(favicon), 1.0); MDCPalette* dominantPalette = @@ -424,7 +424,7 @@ }; GURL gurlCopy = gurl; _faviconObtainer.reset([[NSBlockOperation blockOperationWithBlock:^{ - ios_internal::GetFavicon(gurlCopy, browserState, block); + TabSwitcherGetFavicon(gurlCopy, browserState, block); }] retain]); NSOperationQueue* operationQueue = [NSOperationQueue mainQueue]; [operationQueue addOperation:_faviconObtainer];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h index 402f74c..59f87c58 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h
@@ -52,13 +52,13 @@ @property(nonatomic, readonly) TabSwitcherPanelView* view; @property(nonatomic, assign) id<TabSwitcherPanelControllerDelegate> delegate; -@property(nonatomic, readonly) ios_internal::SessionType sessionType; +@property(nonatomic, readonly) TabSwitcherSessionType sessionType; // Initializes a controller for a view showing local tabs. |offTheRecord| // determines whether the tabs will be shown for the incognito browser state or // not. |model| is used to populate the view and must not be nil. - (instancetype)initWithModel:(TabSwitcherModel*)model - forLocalSessionOfType:(ios_internal::SessionType)type + forLocalSessionOfType:(TabSwitcherSessionType)type withCache:(TabSwitcherCache*)cache browserState:(ios::ChromeBrowserState*)browserState;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.mm index 07f5ea19..112f0fd 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.mm
@@ -9,11 +9,11 @@ #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/tabs/tab.h" #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" -#import "ios/chrome/browser/ui/tab_switcher/session_changes.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h" +#include "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h" namespace { @@ -35,7 +35,7 @@ base::scoped_nsobject<TabSwitcherPanelView> _panelView; base::scoped_nsobject<TabSwitcherModel> _model; std::string _sessionTag; - ios_internal::SessionType _sessionType; + TabSwitcherSessionType _sessionType; base::scoped_nsobject<TabSwitcherCache> _cache; base::scoped_nsobject<TabSwitcherPanelOverlayView> _overlayView; std::unique_ptr<const synced_sessions::DistantSession> _distantSession; @@ -58,7 +58,7 @@ self = [super init]; if (self) { DCHECK(model); - _sessionType = ios_internal::SessionType::DISTANT_SESSION; + _sessionType = TabSwitcherSessionType::DISTANT_SESSION; _model.reset([model retain]); _distantSession = [model distantSessionForTag:sessionTag]; _sessionTag = sessionTag; @@ -69,7 +69,7 @@ } - (instancetype)initWithModel:(TabSwitcherModel*)model - forLocalSessionOfType:(ios_internal::SessionType)sessionType + forLocalSessionOfType:(TabSwitcherSessionType)sessionType withCache:(TabSwitcherCache*)cache browserState:(ios::ChromeBrowserState*)browserState { self = [super init]; @@ -99,7 +99,7 @@ } - (BOOL)shouldShowNewTabButton { - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { return NO; } else { return ![self isOverlayVisible]; @@ -107,9 +107,9 @@ } - (void)updateCollectionViewIfNeeded { - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { UICollectionView* collectionView = [_panelView collectionView]; - // TODO(crbug.com/633928) Compute SessionChanges outside of the + // TODO(crbug.com/633928) Compute TabSwitcherSessionChanges outside of the // updateBlock. auto updateBlock = ^{ std::unique_ptr<const synced_sessions::DistantSession> newDistantSession = @@ -120,8 +120,8 @@ &oldTabsHashes); FillVectorWithHashesUsingDistantSession(*newDistantSession.get(), &newTabsHashes); - ios_internal::SessionChanges changes(oldTabsHashes, newTabsHashes); - if (changes.hasChanges()) { + TabSwitcherSessionChanges changes(oldTabsHashes, newTabsHashes); + if (changes.HasChanges()) { _distantSession = std::move(newDistantSession); [self applyChanges:changes toCollectionView:collectionView]; } @@ -132,9 +132,9 @@ auto updateBlock = ^{ std::unique_ptr<const TabModelSnapshot> newLocalSession = [_model tabModelSnapshotForLocalSession:_sessionType]; - ios_internal::SessionChanges changes(_localSession->hashes(), - newLocalSession->hashes()); - if (changes.hasChanges()) { + TabSwitcherSessionChanges changes(_localSession->hashes(), + newLocalSession->hashes()); + if (changes.HasChanges()) { _localSession = std::move(newLocalSession); [self applyChanges:changes toCollectionView:collectionView]; } @@ -143,7 +143,7 @@ } } -- (void)applyChanges:(ios_internal::SessionChanges&)changes +- (void)applyChanges:(TabSwitcherSessionChanges&)changes toCollectionView:(UICollectionView*)collectionView { NSMutableArray* deletedIndexes = [NSMutableArray array]; NSMutableArray* insertedIndexes = [NSMutableArray array]; @@ -202,7 +202,7 @@ - (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section { DCHECK_EQ(section, 0); - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { CHECK(_distantSession); return _distantSession->tabs.size(); } else { @@ -217,7 +217,7 @@ cellForItemAtIndexPath:(NSIndexPath*)indexPath { UICollectionViewCell* cell = nil; NSUInteger tabIndex = indexPath.item; - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { cell = [collectionView dequeueReusableCellWithReuseIdentifier:[TabSwitcherDistantSessionCell identifier] @@ -262,7 +262,7 @@ const NSInteger tabIndex = [[_panelView collectionView] indexPathForCell:cell].item; - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { synced_sessions::DistantTab* tab = _distantSession->tabs[tabIndex].get(); if (tab) [self.delegate tabSwitcherPanelController:self didSelectDistantTab:tab]; @@ -274,7 +274,7 @@ } - (void)deleteButtonPressedForCell:(UICollectionViewCell*)cell { - DCHECK(_sessionType != ios_internal::SessionType::DISTANT_SESSION); + DCHECK(_sessionType != TabSwitcherSessionType::DISTANT_SESSION); const NSInteger tabIndex = [[_panelView collectionView] indexPathForCell:cell].item; Tab* tab = _localSession->tabs()[tabIndex]; @@ -292,7 +292,7 @@ if (show == [self isOverlayVisible]) return; - DCHECK(ios_internal::IsLocalSession(_sessionType)); + DCHECK(TabSwitcherSessionTypeIsLocalSession(_sessionType)); if (!_overlayView) { _overlayView.reset([[TabSwitcherPanelOverlayView alloc] @@ -300,7 +300,7 @@ browserState:_browserState]); [_overlayView setOverlayType: - (_sessionType == ios_internal::SessionType::OFF_THE_RECORD_SESSION) + (_sessionType == TabSwitcherSessionType::OFF_THE_RECORD_SESSION) ? TabSwitcherPanelOverlayType:: OVERLAY_PANEL_USER_NO_INCOGNITO_TABS : TabSwitcherPanelOverlayType::OVERLAY_PANEL_USER_NO_OPEN_TABS];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h index 16be52cd..3c11453 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.h
@@ -15,7 +15,7 @@ @property(nonatomic, readonly) UICollectionView* collectionView; -- (instancetype)initWithSessionType:(ios_internal::SessionType)sessionType +- (instancetype)initWithSessionType:(TabSwitcherSessionType)sessionType NS_DESIGNATED_INITIALIZER; - (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.mm index e53c52c..65245fd 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_view.mm
@@ -12,14 +12,14 @@ base::scoped_nsobject<UICollectionView> _collectionView; base::scoped_nsobject<TabSwitcherPanelCollectionViewLayout> _collectionViewLayout; - ios_internal::SessionType _sessionType; + TabSwitcherSessionType _sessionType; } @end @implementation TabSwitcherPanelView -- (instancetype)initWithSessionType:(ios_internal::SessionType)sessionType { +- (instancetype)initWithSessionType:(TabSwitcherSessionType)sessionType { self = [super initWithFrame:CGRectZero]; if (self) { _sessionType = sessionType; @@ -62,7 +62,7 @@ _collectionView.reset([[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:_collectionViewLayout.get()]); - if (_sessionType == ios_internal::SessionType::DISTANT_SESSION) { + if (_sessionType == TabSwitcherSessionType::DISTANT_SESSION) { [_collectionView registerClass:[TabSwitcherDistantSessionCell class] forCellWithReuseIdentifier:[TabSwitcherDistantSessionCell identifier]]; } else {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h index 2f8e4e80..d61b101 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.h
@@ -9,8 +9,7 @@ @class TabSwitcherHeaderView; -namespace ios_internal { -enum SessionCellType { +enum TabSwitcherSessionCellType { kIncognitoSessionCell, kOpenTabSessionCell, kGenericRemoteSessionCell, @@ -18,11 +17,10 @@ kTabletRemoteSessionCell, kLaptopRemoteSessionCell, }; -} // This class hold the data used to configure the content of a // TabSwitcherHeaderCell. -@interface SessionCellData : NSObject +@interface TabSwitcherSessionCellData : NSObject // Those two methods are used to create incognito and open tab cell data. // Each method create a SessionCellData object on the first call and returns @@ -31,9 +29,9 @@ + (instancetype)openTabSessionCellData; + (instancetype)otherDevicesSessionCellData; -- (instancetype)initWithSessionCellType:(ios_internal::SessionCellType)type; +- (instancetype)initWithSessionCellType:(TabSwitcherSessionCellType)type; -@property(nonatomic, readonly) ios_internal::SessionCellType type; +@property(nonatomic, readonly) TabSwitcherSessionCellType type; @property(nonatomic, copy) NSString* title; @property(nonatomic, retain) UIImage* image;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.mm index cbb8af2e..a304a26 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_cell_data.mm
@@ -6,43 +6,43 @@ #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" -@implementation SessionCellData +@implementation TabSwitcherSessionCellData @synthesize type = _type; @synthesize title = _title; @synthesize image = _image; + (instancetype)incognitoSessionCellData { - static SessionCellData* incognitoSessionCellData = nil; + static TabSwitcherSessionCellData* incognitoSessionCellData = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - incognitoSessionCellData = [[self alloc] - initWithSessionCellType:ios_internal::kIncognitoSessionCell]; + incognitoSessionCellData = + [[self alloc] initWithSessionCellType:kIncognitoSessionCell]; }); return incognitoSessionCellData; } + (instancetype)openTabSessionCellData { - static SessionCellData* openTabSessionCellData = nil; + static TabSwitcherSessionCellData* openTabSessionCellData = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - openTabSessionCellData = [[self alloc] - initWithSessionCellType:ios_internal::kOpenTabSessionCell]; + openTabSessionCellData = + [[self alloc] initWithSessionCellType:kOpenTabSessionCell]; }); return openTabSessionCellData; } + (instancetype)otherDevicesSessionCellData { - static SessionCellData* otherDevicesSessionCellData = nil; + static TabSwitcherSessionCellData* otherDevicesSessionCellData = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - otherDevicesSessionCellData = [[self alloc] - initWithSessionCellType:ios_internal::kGenericRemoteSessionCell]; + otherDevicesSessionCellData = + [[self alloc] initWithSessionCellType:kGenericRemoteSessionCell]; }); return otherDevicesSessionCellData; } -- (instancetype)initWithSessionCellType:(ios_internal::SessionCellType)type { +- (instancetype)initWithSessionCellType:(TabSwitcherSessionCellType)type { self = [super init]; if (self) { _type = type; @@ -57,27 +57,27 @@ NSString* imageName = nil; int messageId = 0; switch (self.type) { - case ios_internal::kIncognitoSessionCell: + case kIncognitoSessionCell: imageName = @"tabswitcher_incognito"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_INCOGNITO_TABS; break; - case ios_internal::kOpenTabSessionCell: + case kOpenTabSessionCell: imageName = @"tabswitcher_open_tabs"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_NON_INCOGNITO_TABS; break; - case ios_internal::kGenericRemoteSessionCell: + case kGenericRemoteSessionCell: imageName = @"tabswitcher_other_devices"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_OTHER_DEVICES_TABS; break; - case ios_internal::kPhoneRemoteSessionCell: + case kPhoneRemoteSessionCell: imageName = @"ntp_opentabs_phone"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_OTHER_DEVICES_TABS; break; - case ios_internal::kTabletRemoteSessionCell: + case kTabletRemoteSessionCell: imageName = @"ntp_opentabs_tablet"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_OTHER_DEVICES_TABS; break; - case ios_internal::kLaptopRemoteSessionCell: + case kLaptopRemoteSessionCell: imageName = @"ntp_opentabs_laptop"; messageId = IDS_IOS_TAB_SWITCHER_HEADER_OTHER_DEVICES_TABS; break;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h new file mode 100644 index 0000000..44389529 --- /dev/null +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h
@@ -0,0 +1,46 @@ +// Copyright 2016 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. + +#ifndef IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_SWITCHER_SESSION_CHANGES_H_ +#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_SWITCHER_SESSION_CHANGES_H_ + +#include <vector> + +// This structure represents the changes a session undergoes. +// It is used to update the UICollectionView showing a set of tabs. +class TabSwitcherSessionChanges { + public: + TabSwitcherSessionChanges(std::vector<size_t> const& tabHashesInInitialState, + std::vector<size_t> const& tabHashesInFinalState); + ~TabSwitcherSessionChanges(); + TabSwitcherSessionChanges(const TabSwitcherSessionChanges& sessionChanges) = + delete; + TabSwitcherSessionChanges& operator=( + const TabSwitcherSessionChanges& sessionChanges) = delete; + + std::vector<size_t> const& deletions() const { return deletions_; } + + std::vector<size_t> const& insertions() const { return insertions_; } + + std::vector<size_t> const& updates() const { return updates_; } + + bool HasChanges() const; + + private: + // Those vectors contain indexes of tabs. + // The indexes are relative to a tab model snapshot, or a distant session. + // To be in accordance with the UICollectionView's |performBatchUpdates| + // method: + // -the indexes in |updates| are relative to the previous state of the + // session. + // -the indexes in |deletions| are relative to the previous state of the + // session. + // -the indexes in |insertions| are relative to the final state of the + // session. + std::vector<size_t> deletions_; + std::vector<size_t> insertions_; + std::vector<size_t> updates_; +}; + +#endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_SWITCHER_SESSION_CHANGES_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.mm new file mode 100644 index 0000000..5d94e05 --- /dev/null +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.mm
@@ -0,0 +1,21 @@ +// Copyright 2016 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. + +#include "ios/chrome/browser/ui/tab_switcher/tab_switcher_session_changes.h" + +#import "ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h" + +TabSwitcherSessionChanges::TabSwitcherSessionChanges( + std::vector<size_t> const& tabHashesInInitialState, + std::vector<size_t> const& tabHashesInFinalState) { + TabSwitcherMinimalReplacementOperations(tabHashesInInitialState, + tabHashesInFinalState, &updates_, + &deletions_, &insertions_); +} + +TabSwitcherSessionChanges::~TabSwitcherSessionChanges() {} + +bool TabSwitcherSessionChanges::HasChanges() const { + return updates_.size() || deletions_.size() || insertions_.size(); +}
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h index cdae3c9..a183686f 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h
@@ -9,18 +9,17 @@ class GURL; @class UIImage; + namespace ios { class ChromeBrowserState; } // namespace ios -namespace ios_internal { - -typedef void (^FaviconGetterCompletionBlock)(UIImage*); +typedef void (^TabSwitcherFaviconGetterCompletionBlock)(UIImage*); // Favicon for |url|, calls |block| when loaded. -void GetFavicon(GURL const& url, - ios::ChromeBrowserState* browserState, - FaviconGetterCompletionBlock block); +void TabSwitcherGetFavicon(GURL const& url, + ios::ChromeBrowserState* browserState, + TabSwitcherFaviconGetterCompletionBlock block); // Returns the substitutions/deletions/insertions needed to go from |initial| to // |final|. @@ -34,12 +33,10 @@ // For example, AB => BC could be done with 2 substitutions, but doing // 1 insertion and 1 deletion is preferable because it better communicates the // changes to the user in the UICollectionViews. -void MinimalReplacementOperations(std::vector<size_t> const& initial, - std::vector<size_t> const& final, - std::vector<size_t>* substitutions, - std::vector<size_t>* deletions, - std::vector<size_t>* insertions); - -} // namespace ios_internal +void TabSwitcherMinimalReplacementOperations(std::vector<size_t> const& initial, + std::vector<size_t> const& final, + std::vector<size_t>* substitutions, + std::vector<size_t>* deletions, + std::vector<size_t>* insertions); #endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_SWITCHER_UTILS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm index c6a3afd..af2c65d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm
@@ -18,15 +18,49 @@ #import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_theme_resources.h" -namespace ios_internal { +namespace { UIImage* DefaultFaviconImage() { return NativeImage(IDR_IOS_OMNIBOX_HTTP); } -void GetFavicon(GURL const& url, - ios::ChromeBrowserState* browser_state, - ios_internal::FaviconGetterCompletionBlock block) { +enum BacktrackOperation { NOTHING, SUBSTITUTION, DELETION, INSERTION }; + +BacktrackOperation BacktrackOperationInCostMatrix( + std::vector<std::vector<int>> const& costMatrix, + size_t finalIndex, + size_t initialIndex) { + DCHECK(finalIndex || initialIndex); + DCHECK(initialIndex < costMatrix.size()); + DCHECK(finalIndex < costMatrix[initialIndex].size()); + + if (finalIndex == 0) + return DELETION; + if (initialIndex == 0) + return INSERTION; + + int currentCost = costMatrix[initialIndex][finalIndex]; + + int costBeforeInsertion = costMatrix[initialIndex][finalIndex - 1]; + if (costBeforeInsertion + 1 == currentCost) + return INSERTION; + + int costBeforeDeletion = costMatrix[initialIndex - 1][finalIndex]; + if (costBeforeDeletion + 1 == currentCost) + return DELETION; + + int costBeforeSubstitution = costMatrix[initialIndex - 1][finalIndex - 1]; + if (costBeforeSubstitution == currentCost) + return NOTHING; + + return SUBSTITUTION; +} + +} // namespace + +void TabSwitcherGetFavicon(GURL const& url, + ios::ChromeBrowserState* browser_state, + TabSwitcherFaviconGetterCompletionBlock block) { DCHECK(browser_state); syncer::SyncService* sync_service = IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state); @@ -70,43 +104,11 @@ block(DefaultFaviconImage()); } -enum BacktrackOperation { NOTHING, SUBSTITUTION, DELETION, INSERTION }; - -BacktrackOperation BacktrackOperationInCostMatrix( - std::vector<std::vector<int>> const& costMatrix, - size_t finalIndex, - size_t initialIndex) { - DCHECK(finalIndex || initialIndex); - DCHECK(initialIndex < costMatrix.size()); - DCHECK(finalIndex < costMatrix[initialIndex].size()); - - if (finalIndex == 0) - return DELETION; - if (initialIndex == 0) - return INSERTION; - - int currentCost = costMatrix[initialIndex][finalIndex]; - - int costBeforeInsertion = costMatrix[initialIndex][finalIndex - 1]; - if (costBeforeInsertion + 1 == currentCost) - return INSERTION; - - int costBeforeDeletion = costMatrix[initialIndex - 1][finalIndex]; - if (costBeforeDeletion + 1 == currentCost) - return DELETION; - - int costBeforeSubstitution = costMatrix[initialIndex - 1][finalIndex - 1]; - if (costBeforeSubstitution == currentCost) - return NOTHING; - - return SUBSTITUTION; -} - -void MinimalReplacementOperations(std::vector<size_t> const& initial, - std::vector<size_t> const& final, - std::vector<size_t>* substitutions, - std::vector<size_t>* deletions, - std::vector<size_t>* insertions) { +void TabSwitcherMinimalReplacementOperations(std::vector<size_t> const& initial, + std::vector<size_t> const& final, + std::vector<size_t>* substitutions, + std::vector<size_t>* deletions, + std::vector<size_t>* insertions) { DCHECK(substitutions); DCHECK(deletions); DCHECK(insertions); @@ -185,5 +187,3 @@ std::reverse(std::begin(*deletions), std::end(*deletions)); std::reverse(std::begin(*insertions), std::end(*insertions)); } - -} // namespace ios_internal
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils_unittest.mm index 37d4537..1ccdee3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils_unittest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils_unittest.mm
@@ -18,8 +18,8 @@ std::vector<size_t> substitutions; std::vector<size_t> deletions; std::vector<size_t> insertions; - ios_internal::MinimalReplacementOperations(initial, final, &substitutions, - &deletions, &insertions); + TabSwitcherMinimalReplacementOperations(initial, final, &substitutions, + &deletions, &insertions); EXPECT_EQ(substitutions, expectedSubstitutions); EXPECT_EQ(deletions, expectedDeletions); EXPECT_EQ(insertions, expectedInsertions);
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h index 58eec55..73ea0ab7 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.h +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -91,8 +91,6 @@ virtual std::string GetDistributionBrandCode(); // Returns risk data used in Wallet requests. virtual std::string GetRiskData(); - // Returns whether there is an Off-The-Record session active. - virtual bool IsOffTheRecordSessionActive(); // Get the favicon for |page_url| and run |callback| with result when loaded. // Note. |callback| is always run asynchronously. virtual void GetFaviconForURL(
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.mm b/ios/public/provider/chrome/browser/chrome_browser_provider.mm index 211c80a..dab8adf 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.mm +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
@@ -66,10 +66,6 @@ return std::string(); } -bool ChromeBrowserProvider::IsOffTheRecordSessionActive() { - return false; -} - void ChromeBrowserProvider::GetFaviconForURL( ios::ChromeBrowserState* browser_state, const GURL& page_url,
diff --git a/jingle/BUILD.gn b/jingle/BUILD.gn index 0fc2541..10345a4 100644 --- a/jingle/BUILD.gn +++ b/jingle/BUILD.gn
@@ -100,8 +100,7 @@ public_deps = [ "//third_party/libjingle", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] deps = [ ":jingle_glue", @@ -173,8 +172,7 @@ public_deps = [ "//third_party/libjingle", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] deps = [ ":jingle_glue",
diff --git a/jingle/DEPS b/jingle/DEPS index 948e91d..5a5a3f9 100644 --- a/jingle/DEPS +++ b/jingle/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+net", "+third_party/libjingle", - "+third_party/webrtc/libjingle", + "+third_party/libjingle_xmpp/xmllite", + "+third_party/libjingle_xmpp/xmpp", ]
diff --git a/jingle/glue/chrome_async_socket.h b/jingle/glue/chrome_async_socket.h index a00069a..7d6c9aa9 100644 --- a/jingle/glue/chrome_async_socket.h +++ b/jingle/glue/chrome_async_socket.h
@@ -23,7 +23,7 @@ #include "base/memory/weak_ptr.h" #include "net/base/completion_callback.h" #include "net/base/net_errors.h" -#include "third_party/webrtc/libjingle/xmpp/asyncsocket.h" +#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h" namespace net { class IOBufferWithSize;
diff --git a/jingle/notifier/DEPS b/jingle/notifier/DEPS index 56600f5da..80bd8ce 100644 --- a/jingle/notifier/DEPS +++ b/jingle/notifier/DEPS
@@ -1,8 +1,5 @@ include_rules = [ - # notifier depends on libjingle. - "+talk/base", - "+talk/xmpp", - "+talk/xmllite", - "+webrtc/libjingle", "+webrtc/base", + "+third_party/libjingle_xmpp/xmpp", + "+third_party/libjingle_xmpp/xmllite", ]
diff --git a/jingle/notifier/base/fake_base_task.cc b/jingle/notifier/base/fake_base_task.cc index 89f5bf8..21b8c530 100644 --- a/jingle/notifier/base/fake_base_task.cc +++ b/jingle/notifier/base/fake_base_task.cc
@@ -8,7 +8,7 @@ #include "jingle/notifier/base/fake_base_task.h" #include "jingle/notifier/base/weak_xmpp_client.h" #include "testing/gmock/include/gmock/gmock.h" -#include "webrtc/libjingle/xmpp/asyncsocket.h" +#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h" namespace notifier {
diff --git a/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc b/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc index 657fd3ff..26fbfc43 100644 --- a/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc +++ b/jingle/notifier/base/gaia_token_pre_xmpp_auth.cc
@@ -8,9 +8,9 @@ #include "base/logging.h" #include "base/macros.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h" #include "webrtc/base/socketaddress.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/saslcookiemechanism.h" namespace notifier {
diff --git a/jingle/notifier/base/gaia_token_pre_xmpp_auth.h b/jingle/notifier/base/gaia_token_pre_xmpp_auth.h index 7b86bd5..86da7a04 100644 --- a/jingle/notifier/base/gaia_token_pre_xmpp_auth.h +++ b/jingle/notifier/base/gaia_token_pre_xmpp_auth.h
@@ -9,7 +9,7 @@ #include <vector> #include "base/compiler_specific.h" -#include "webrtc/libjingle/xmpp/prexmppauth.h" +#include "third_party/libjingle_xmpp/xmpp/prexmppauth.h" namespace notifier {
diff --git a/jingle/notifier/base/notifier_options_util.cc b/jingle/notifier/base/notifier_options_util.cc index a8615b1..9754b2c7 100644 --- a/jingle/notifier/base/notifier_options_util.cc +++ b/jingle/notifier/base/notifier_options_util.cc
@@ -7,8 +7,8 @@ #include "base/logging.h" #include "jingle/notifier/base/const_communicator.h" #include "jingle/notifier/base/notifier_options.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" namespace notifier {
diff --git a/jingle/notifier/base/notifier_options_util.h b/jingle/notifier/base/notifier_options_util.h index 2d14429..9ecb3cf 100644 --- a/jingle/notifier/base/notifier_options_util.h +++ b/jingle/notifier/base/notifier_options_util.h
@@ -11,7 +11,7 @@ #include <vector> #include "jingle/notifier/base/server_information.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace notifier {
diff --git a/jingle/notifier/base/weak_xmpp_client.h b/jingle/notifier/base/weak_xmpp_client.h index ab0137a3..16a68dd 100644 --- a/jingle/notifier/base/weak_xmpp_client.h +++ b/jingle/notifier/base/weak_xmpp_client.h
@@ -13,7 +13,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" namespace rtc { class TaskParent;
diff --git a/jingle/notifier/base/xmpp_connection.cc b/jingle/notifier/base/xmpp_connection.cc index efa62bc..8d71e5d9 100644 --- a/jingle/notifier/base/xmpp_connection.cc +++ b/jingle/notifier/base/xmpp_connection.cc
@@ -17,7 +17,7 @@ #include "net/socket/client_socket_factory.h" #include "net/ssl/ssl_config_service.h" #include "net/url_request/url_request_context.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace notifier {
diff --git a/jingle/notifier/base/xmpp_connection.h b/jingle/notifier/base/xmpp_connection.h index e41d914..1e1c2db 100644 --- a/jingle/notifier/base/xmpp_connection.h +++ b/jingle/notifier/base/xmpp_connection.h
@@ -15,8 +15,8 @@ #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" #include "net/url_request/url_request_context_getter.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" #include "webrtc/base/sigslot.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" namespace buzz { class PreXmppAuth;
diff --git a/jingle/notifier/base/xmpp_connection_unittest.cc b/jingle/notifier/base/xmpp_connection_unittest.cc index ee1b44d..4e07fcf7 100644 --- a/jingle/notifier/base/xmpp_connection_unittest.cc +++ b/jingle/notifier/base/xmpp_connection_unittest.cc
@@ -21,8 +21,8 @@ #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/libjingle/xmpp/prexmppauth.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/prexmppauth.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace buzz { class CaptchaChallenge;
diff --git a/jingle/notifier/communicator/connection_settings.cc b/jingle/notifier/communicator/connection_settings.cc index 3e8bc420..0e848d7f 100644 --- a/jingle/notifier/communicator/connection_settings.cc +++ b/jingle/notifier/communicator/connection_settings.cc
@@ -8,10 +8,10 @@ #include "base/logging.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" // Ideally we shouldn't include anything from talk/p2p, but we need // the definition of ProtocolType. Don't use any functions from // port.h, since it won't link. +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" #include "webrtc/p2p/base/port.h" namespace notifier {
diff --git a/jingle/notifier/communicator/login.cc b/jingle/notifier/communicator/login.cc index aacfa41031..ce7f85a 100644 --- a/jingle/notifier/communicator/login.cc +++ b/jingle/notifier/communicator/login.cc
@@ -10,17 +10,17 @@ #include "base/rand_util.h" #include "base/time/time.h" #include "net/base/host_port_pair.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h" +#include "third_party/libjingle_xmpp/xmpp/prexmppauth.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" #include "webrtc/base/common.h" #include "webrtc/base/firewallsocketserver.h" #include "webrtc/base/logging.h" #include "webrtc/base/physicalsocketserver.h" #include "webrtc/base/taskrunner.h" -#include "webrtc/libjingle/xmpp/asyncsocket.h" -#include "webrtc/libjingle/xmpp/prexmppauth.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" namespace notifier {
diff --git a/jingle/notifier/communicator/login.h b/jingle/notifier/communicator/login.h index 8f115f4..06c06ac0 100644 --- a/jingle/notifier/communicator/login.h +++ b/jingle/notifier/communicator/login.h
@@ -18,7 +18,7 @@ #include "jingle/notifier/communicator/login_settings.h" #include "jingle/notifier/communicator/single_login_attempt.h" #include "net/base/network_change_notifier.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" namespace buzz { class XmppClientSettings;
diff --git a/jingle/notifier/communicator/login_settings.h b/jingle/notifier/communicator/login_settings.h index c797bdd..ae81e7f5 100644 --- a/jingle/notifier/communicator/login_settings.h +++ b/jingle/notifier/communicator/login_settings.h
@@ -10,7 +10,7 @@ #include "base/time/time.h" #include "jingle/notifier/base/server_information.h" #include "net/url_request/url_request_context_getter.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace notifier {
diff --git a/jingle/notifier/communicator/login_settings_unittest.cc b/jingle/notifier/communicator/login_settings_unittest.cc index 72e769a..fb0034f 100644 --- a/jingle/notifier/communicator/login_settings_unittest.cc +++ b/jingle/notifier/communicator/login_settings_unittest.cc
@@ -7,7 +7,7 @@ #include <cstddef> #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace notifier {
diff --git a/jingle/notifier/communicator/single_login_attempt.cc b/jingle/notifier/communicator/single_login_attempt.cc index 5b24b5d..a8d0732 100644 --- a/jingle/notifier/communicator/single_login_attempt.cc +++ b/jingle/notifier/communicator/single_login_attempt.cc
@@ -16,9 +16,9 @@ #include "jingle/notifier/base/gaia_token_pre_xmpp_auth.h" #include "jingle/notifier/listener/xml_element_util.h" #include "net/base/host_port_pair.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace notifier {
diff --git a/jingle/notifier/communicator/single_login_attempt.h b/jingle/notifier/communicator/single_login_attempt.h index b31280b5..f5b05e6 100644 --- a/jingle/notifier/communicator/single_login_attempt.h +++ b/jingle/notifier/communicator/single_login_attempt.h
@@ -12,7 +12,7 @@ #include "jingle/notifier/base/xmpp_connection.h" #include "jingle/notifier/communicator/connection_settings.h" #include "jingle/notifier/communicator/login_settings.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" namespace buzz { class XmppTaskParentInterface;
diff --git a/jingle/notifier/communicator/single_login_attempt_unittest.cc b/jingle/notifier/communicator/single_login_attempt_unittest.cc index 298907c..f200d88 100644 --- a/jingle/notifier/communicator/single_login_attempt_unittest.cc +++ b/jingle/notifier/communicator/single_login_attempt_unittest.cc
@@ -17,9 +17,9 @@ #include "net/dns/mock_host_resolver.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" namespace buzz { class XmppTaskParentInterface;
diff --git a/jingle/notifier/listener/push_notifications_listen_task.cc b/jingle/notifier/listener/push_notifications_listen_task.cc index 4e6a276d..7aff7a2e 100644 --- a/jingle/notifier/listener/push_notifications_listen_task.cc +++ b/jingle/notifier/listener/push_notifications_listen_task.cc
@@ -9,12 +9,12 @@ #include "jingle/notifier/listener/notification_constants.h" #include "jingle/notifier/listener/notification_defines.h" #include "jingle/notifier/listener/xml_element_util.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" #include "webrtc/base/task.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" namespace notifier {
diff --git a/jingle/notifier/listener/push_notifications_listen_task.h b/jingle/notifier/listener/push_notifications_listen_task.h index 033827a..3f7028f 100644 --- a/jingle/notifier/listener/push_notifications_listen_task.h +++ b/jingle/notifier/listener/push_notifications_listen_task.h
@@ -15,7 +15,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "webrtc/libjingle/xmpp/xmpptask.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/push_notifications_send_update_task.cc b/jingle/notifier/listener/push_notifications_send_update_task.cc index 68d632a..87108d97 100644 --- a/jingle/notifier/listener/push_notifications_send_update_task.cc +++ b/jingle/notifier/listener/push_notifications_send_update_task.cc
@@ -13,11 +13,11 @@ #include "base/logging.h" #include "jingle/notifier/listener/notification_constants.h" #include "jingle/notifier/listener/xml_element_util.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/jid.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" namespace notifier {
diff --git a/jingle/notifier/listener/push_notifications_send_update_task.h b/jingle/notifier/listener/push_notifications_send_update_task.h index d8fc7d0f..b0d111a 100644 --- a/jingle/notifier/listener/push_notifications_send_update_task.h +++ b/jingle/notifier/listener/push_notifications_send_update_task.h
@@ -11,7 +11,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "jingle/notifier/listener/notification_defines.h" -#include "webrtc/libjingle/xmpp/xmpptask.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" namespace buzz { class Jid;
diff --git a/jingle/notifier/listener/push_notifications_send_update_task_unittest.cc b/jingle/notifier/listener/push_notifications_send_update_task_unittest.cc index edd80a2e..bf2b83b 100644 --- a/jingle/notifier/listener/push_notifications_send_update_task_unittest.cc +++ b/jingle/notifier/listener/push_notifications_send_update_task_unittest.cc
@@ -11,7 +11,7 @@ #include "base/strings/stringprintf.h" #include "jingle/notifier/listener/xml_element_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/libjingle/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/push_notifications_subscribe_task.cc b/jingle/notifier/listener/push_notifications_subscribe_task.cc index ec7ec06..c7a324b5 100644 --- a/jingle/notifier/listener/push_notifications_subscribe_task.cc +++ b/jingle/notifier/listener/push_notifications_subscribe_task.cc
@@ -10,12 +10,12 @@ #include "base/logging.h" #include "jingle/notifier/listener/notification_constants.h" #include "jingle/notifier/listener/xml_element_util.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" #include "webrtc/base/task.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" -#include "webrtc/libjingle/xmpp/xmppengine.h" namespace notifier {
diff --git a/jingle/notifier/listener/push_notifications_subscribe_task.h b/jingle/notifier/listener/push_notifications_subscribe_task.h index 3a90f70..4dad3c4 100644 --- a/jingle/notifier/listener/push_notifications_subscribe_task.h +++ b/jingle/notifier/listener/push_notifications_subscribe_task.h
@@ -14,8 +14,8 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "jingle/notifier/listener/notification_defines.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "webrtc/libjingle/xmpp/xmpptask.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" namespace notifier { class PushNotificationsSubscribeTask : public buzz::XmppTask {
diff --git a/jingle/notifier/listener/push_notifications_subscribe_task_unittest.cc b/jingle/notifier/listener/push_notifications_subscribe_task_unittest.cc index 11530b17..af638667 100644 --- a/jingle/notifier/listener/push_notifications_subscribe_task_unittest.cc +++ b/jingle/notifier/listener/push_notifications_subscribe_task_unittest.cc
@@ -10,7 +10,7 @@ #include "base/strings/stringprintf.h" #include "jingle/notifier/listener/xml_element_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/libjingle/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/send_ping_task.cc b/jingle/notifier/listener/send_ping_task.cc index 2260adfb..0bf205e 100644 --- a/jingle/notifier/listener/send_ping_task.cc +++ b/jingle/notifier/listener/send_ping_task.cc
@@ -9,11 +9,11 @@ #include "base/logging.h" #include "jingle/notifier/listener/xml_element_util.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "webrtc/libjingle/xmpp/constants.h" -#include "webrtc/libjingle/xmpp/jid.h" -#include "webrtc/libjingle/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" namespace notifier {
diff --git a/jingle/notifier/listener/send_ping_task.h b/jingle/notifier/listener/send_ping_task.h index 75f9fb70..8f8ea78 100644 --- a/jingle/notifier/listener/send_ping_task.h +++ b/jingle/notifier/listener/send_ping_task.h
@@ -10,7 +10,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "webrtc/libjingle/xmpp/xmpptask.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/send_ping_task_unittest.cc b/jingle/notifier/listener/send_ping_task_unittest.cc index 4f7f61d..e1b4296 100644 --- a/jingle/notifier/listener/send_ping_task_unittest.cc +++ b/jingle/notifier/listener/send_ping_task_unittest.cc
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "jingle/notifier/listener/xml_element_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/libjingle/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/xml_element_util.cc b/jingle/notifier/listener/xml_element_util.cc index 280485e..2224cccf5 100644 --- a/jingle/notifier/listener/xml_element_util.cc +++ b/jingle/notifier/listener/xml_element_util.cc
@@ -8,10 +8,10 @@ #include <string> #include "base/strings/string_number_conversions.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlconstants.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmllite/xmlprinter.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" namespace notifier {
diff --git a/jingle/notifier/listener/xml_element_util_unittest.cc b/jingle/notifier/listener/xml_element_util_unittest.cc index 3c4c0ad..e5212da 100644 --- a/jingle/notifier/listener/xml_element_util_unittest.cc +++ b/jingle/notifier/listener/xml_element_util_unittest.cc
@@ -9,9 +9,9 @@ #include <string> #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmllite/xmlprinter.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" namespace buzz { class XmlElement;
diff --git a/jingle/notifier/listener/xmpp_push_client.h b/jingle/notifier/listener/xmpp_push_client.h index 5cd826f..6472a08 100644 --- a/jingle/notifier/listener/xmpp_push_client.h +++ b/jingle/notifier/listener/xmpp_push_client.h
@@ -22,7 +22,7 @@ #include "jingle/notifier/listener/push_notifications_listen_task.h" #include "jingle/notifier/listener/push_notifications_subscribe_task.h" #include "jingle/notifier/listener/send_ping_task.h" -#include "webrtc/libjingle/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" namespace buzz { class XmppTaskParentInterface;
diff --git a/media/filters/decoder_stream_traits.cc b/media/filters/decoder_stream_traits.cc index 645a1de4..fcbc19e 100644 --- a/media/filters/decoder_stream_traits.cc +++ b/media/filters/decoder_stream_traits.cc
@@ -144,6 +144,7 @@ UMA_HISTOGRAM_MEDIUM_TIMES( "Media.Video.KeyFrameDistance", current_frame_timestamp - last_keyframe_timestamp_); + last_keyframe_timestamp_ = current_frame_timestamp; } } // namespace media
diff --git a/net/extras/sqlite/sqlite_channel_id_store.cc b/net/extras/sqlite/sqlite_channel_id_store.cc index 238577fd..ebcf7ec7 100644 --- a/net/extras/sqlite/sqlite_channel_id_store.cc +++ b/net/extras/sqlite/sqlite_channel_id_store.cc
@@ -227,8 +227,7 @@ smt.ColumnBlobAsVector(2, &public_key_from_db); std::unique_ptr<crypto::ECPrivateKey> key( crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - ChannelIDService::kEPKIPassword, private_key_from_db, - public_key_from_db)); + private_key_from_db, public_key_from_db)); if (!key) continue; std::unique_ptr<DefaultChannelIDStore::ChannelID> channel_id( @@ -498,8 +497,7 @@ add_statement.Reset(true); add_statement.BindString(0, po->channel_id().server_identifier()); std::vector<uint8_t> private_key, public_key; - if (!po->channel_id().key()->ExportEncryptedPrivateKey( - ChannelIDService::kEPKIPassword, 1, &private_key)) + if (!po->channel_id().key()->ExportEncryptedPrivateKey(&private_key)) continue; if (!po->channel_id().key()->ExportPublicKey(&public_key)) continue;
diff --git a/net/extras/sqlite/sqlite_channel_id_store_unittest.cc b/net/extras/sqlite/sqlite_channel_id_store_unittest.cc index 8cb2bb12..7c9b223 100644 --- a/net/extras/sqlite/sqlite_channel_id_store_unittest.cc +++ b/net/extras/sqlite/sqlite_channel_id_store_unittest.cc
@@ -65,8 +65,8 @@ ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(*cert_data, &spki)); std::vector<uint8_t> public_key(spki.size()); memcpy(public_key.data(), spki.data(), spki.size()); - *key = crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( - ChannelIDService::kEPKIPassword, private_key, public_key); + *key = crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(private_key, + public_key); } static base::Time GetTestCertExpirationTime() {
diff --git a/net/ssl/channel_id_service.cc b/net/ssl/channel_id_service.cc index 53c3c636..74ab3816 100644 --- a/net/ssl/channel_id_service.cc +++ b/net/ssl/channel_id_service.cc
@@ -201,9 +201,6 @@ bool create_if_missing_; }; -// static -const char ChannelIDService::kEPKIPassword[] = ""; - ChannelIDService::Request::Request() : service_(NULL) { }
diff --git a/net/ssl/channel_id_service.h b/net/ssl/channel_id_service.h index d9de879..617a297 100644 --- a/net/ssl/channel_id_service.h +++ b/net/ssl/channel_id_service.h
@@ -69,11 +69,6 @@ ChannelIDServiceJob* job_; }; - // Password used on EncryptedPrivateKeyInfo data stored in EC private_key - // values. (This is not used to provide any security, but to workaround NSS - // being unable to import unencrypted PrivateKeyInfo for EC keys.) - static const char kEPKIPassword[]; - // This object owns |channel_id_store|. |task_runner| will // be used to post channel ID generation worker tasks. The tasks are // safe for use with WorkerPool and SequencedWorkerPool::CONTINUE_ON_SHUTDOWN.
diff --git a/net/ssl/ssl_platform_key_nss_unittest.cc b/net/ssl/ssl_platform_key_nss_unittest.cc index 85799cae..350c462 100644 --- a/net/ssl/ssl_platform_key_nss_unittest.cc +++ b/net/ssl/ssl_platform_key_nss_unittest.cc
@@ -74,7 +74,7 @@ crypto::ECPrivateKey::CreateFromPrivateKeyInfo(pkcs8_vector); ASSERT_TRUE(ec_private_key); std::vector<uint8_t> encrypted; - ASSERT_TRUE(ec_private_key->ExportEncryptedPrivateKey("", 1, &encrypted)); + ASSERT_TRUE(ec_private_key->ExportEncryptedPrivateKey(&encrypted)); SECItem encrypted_item = {siBuffer, encrypted.data(), static_cast<unsigned>(encrypted.size())};
diff --git a/remoting/DEPS b/remoting/DEPS index 08af137..9dab5fcb 100644 --- a/remoting/DEPS +++ b/remoting/DEPS
@@ -11,10 +11,10 @@ "+third_party/libvpx", "+third_party/libyuv", "+third_party/webrtc/base", - "+third_party/webrtc/libjingle", "+third_party/webrtc/media", "+third_party/webrtc/p2p", "+third_party/webrtc/modules/desktop_capture", + "+third_party/libjingle_xmpp/xmllite", "+ui/base/keycodes", "+ui/base/l10n", "+ui/base/resource",
diff --git a/remoting/client/client_status_logger_unittest.cc b/remoting/client/client_status_logger_unittest.cc index f63871e2..e308bf9 100644 --- a/remoting/client/client_status_logger_unittest.cc +++ b/remoting/client/client_status_logger_unittest.cc
@@ -11,7 +11,7 @@ #include "remoting/signaling/server_log_entry_unittest.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::XmlElement; using buzz::QName;
diff --git a/remoting/client/server_log_entry_client_unittest.cc b/remoting/client/server_log_entry_client_unittest.cc index 294a97f..b9b1bfa 100644 --- a/remoting/client/server_log_entry_client_unittest.cc +++ b/remoting/client/server_log_entry_client_unittest.cc
@@ -12,7 +12,7 @@ #include "remoting/signaling/server_log_entry.h" #include "remoting/signaling/server_log_entry_unittest.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using base::SysInfo; using buzz::XmlAttr;
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index 6a09a0c..4798ee17 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -471,8 +471,7 @@ if (enable_webrtc) { public_deps += [ "//third_party/libjingle/webrtc:libjingle_webrtc", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", "//third_party/webrtc/modules/desktop_capture", ] } @@ -625,8 +624,7 @@ if (enable_webrtc) { deps += [ "//third_party/libjingle/webrtc:libjingle_webrtc", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] } } @@ -742,8 +740,7 @@ if (enable_webrtc) { deps += [ "//third_party/libjingle/webrtc:libjingle_webrtc", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] }
diff --git a/remoting/host/DEPS b/remoting/host/DEPS index a9a7eb0..5ee2145 100644 --- a/remoting/host/DEPS +++ b/remoting/host/DEPS
@@ -16,6 +16,7 @@ "+third_party/jsoncpp", "+third_party/skia", "+third_party/webrtc", + "+third_party/libjingle_xmpp/xmpp", "+ui", ]
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index 5f641f6..e452b5e 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc
@@ -22,8 +22,8 @@ #include "remoting/signaling/jid_util.h" #include "remoting/signaling/server_log_entry.h" #include "remoting/signaling/signal_strategy.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 9253ac6e..e537288 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -17,8 +17,8 @@ #include "remoting/signaling/mock_signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/host_change_notification_listener.cc b/remoting/host/host_change_notification_listener.cc index 421822bd..3c079f1 100644 --- a/remoting/host/host_change_notification_listener.cc +++ b/remoting/host/host_change_notification_listener.cc
@@ -11,8 +11,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "remoting/base/constants.h" #include "remoting/protocol/jingle_messages.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/host_change_notification_listener_unittest.cc b/remoting/host/host_change_notification_listener_unittest.cc index 1a1d466..7bbf290b 100644 --- a/remoting/host/host_change_notification_listener_unittest.cc +++ b/remoting/host/host_change_notification_listener_unittest.cc
@@ -16,8 +16,8 @@ #include "remoting/signaling/mock_signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/host_status_logger_unittest.cc b/remoting/host/host_status_logger_unittest.cc index 6b24ccf7..fee9ae4 100644 --- a/remoting/host/host_status_logger_unittest.cc +++ b/remoting/host/host_status_logger_unittest.cc
@@ -11,7 +11,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::XmlElement; using buzz::QName;
diff --git a/remoting/host/pam_authorization_factory_posix.cc b/remoting/host/pam_authorization_factory_posix.cc index 35da4cd3..1e7c2c5 100644 --- a/remoting/host/pam_authorization_factory_posix.cc +++ b/remoting/host/pam_authorization_factory_posix.cc
@@ -15,7 +15,7 @@ #include "remoting/base/logging.h" #include "remoting/host/username.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/remoting/host/register_support_host_request.cc b/remoting/host/register_support_host_request.cc index 48d42279..ef25c4a 100644 --- a/remoting/host/register_support_host_request.cc +++ b/remoting/host/register_support_host_request.cc
@@ -17,8 +17,8 @@ #include "remoting/signaling/iq_sender.h" #include "remoting/signaling/jid_util.h" #include "remoting/signaling/signal_strategy.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/register_support_host_request_unittest.cc b/remoting/host/register_support_host_request_unittest.cc index a467476..aed7da0 100644 --- a/remoting/host/register_support_host_request_unittest.cc +++ b/remoting/host/register_support_host_request_unittest.cc
@@ -19,8 +19,8 @@ #include "remoting/signaling/mock_signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/host/server_log_entry_host_unittest.cc b/remoting/host/server_log_entry_host_unittest.cc index f70d4311..b6376e266 100644 --- a/remoting/host/server_log_entry_host_unittest.cc +++ b/remoting/host/server_log_entry_host_unittest.cc
@@ -11,7 +11,7 @@ #include "remoting/signaling/server_log_entry.h" #include "remoting/signaling/server_log_entry_unittest.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::XmlAttr; using buzz::XmlElement;
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index 25742c8..9656bb8 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -243,8 +243,7 @@ if (enable_webrtc) { deps += [ "//third_party/libjingle/webrtc:libjingle_webrtc", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] } else { sources -= [
diff --git a/remoting/protocol/DEPS b/remoting/protocol/DEPS index 20afa9ee..b5d7cb4 100644 --- a/remoting/protocol/DEPS +++ b/remoting/protocol/DEPS
@@ -8,8 +8,8 @@ "+remoting/codec", "+remoting/signaling", "+third_party/boringssl", - "+third_party/libjingle", - "+third_party/webrtc", + "+third_party/libjingle_xmpp/xmpp", "+third_party/protobuf/src", + "+third_party/webrtc", "+ui/events/keycodes/dom", ]
diff --git a/remoting/protocol/authenticator.cc b/remoting/protocol/authenticator.cc index 1b029c67..f8c1285 100644 --- a/remoting/protocol/authenticator.cc +++ b/remoting/protocol/authenticator.cc
@@ -6,7 +6,7 @@ #include "base/memory/ptr_util.h" #include "remoting/base/constants.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/authenticator_test_base.cc b/remoting/protocol/authenticator_test_base.cc index 879afc2..7b26f0a 100644 --- a/remoting/protocol/authenticator_test_base.cc +++ b/remoting/protocol/authenticator_test_base.cc
@@ -20,7 +20,7 @@ #include "remoting/protocol/fake_stream_socket.h" #include "remoting/protocol/p2p_stream_socket.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::SaveArg;
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc index 6ac678d..96baafe 100644 --- a/remoting/protocol/content_description.cc +++ b/remoting/protocol/content_description.cc
@@ -13,7 +13,7 @@ #include "remoting/base/constants.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/name_value_map.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/protocol/content_description_unittest.cc b/remoting/protocol/content_description_unittest.cc index ca0eb56..8a88f22 100644 --- a/remoting/protocol/content_description_unittest.cc +++ b/remoting/protocol/content_description_unittest.cc
@@ -11,7 +11,7 @@ #include "remoting/protocol/authenticator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/fake_authenticator.cc b/remoting/protocol/fake_authenticator.cc index 14bb06ae..a57845c 100644 --- a/remoting/protocol/fake_authenticator.cc +++ b/remoting/protocol/fake_authenticator.cc
@@ -17,7 +17,7 @@ #include "remoting/base/constants.h" #include "remoting/protocol/p2p_stream_socket.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/fake_session.cc b/remoting/protocol/fake_session.cc index 18c16ca..56cbd51 100644 --- a/remoting/protocol/fake_session.cc +++ b/remoting/protocol/fake_session.cc
@@ -9,7 +9,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "remoting/protocol/fake_authenticator.h" #include "remoting/protocol/session_plugin.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/ice_transport_unittest.cc b/remoting/protocol/ice_transport_unittest.cc index eea7878..ccb3d8d 100644 --- a/remoting/protocol/ice_transport_unittest.cc +++ b/remoting/protocol/ice_transport_unittest.cc
@@ -25,7 +25,7 @@ #include "remoting/protocol/transport_context.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_;
diff --git a/remoting/protocol/jingle_info_request.cc b/remoting/protocol/jingle_info_request.cc index 7569dcc..b61b8c17 100644 --- a/remoting/protocol/jingle_info_request.cc +++ b/remoting/protocol/jingle_info_request.cc
@@ -13,9 +13,9 @@ #include "base/time/time.h" #include "remoting/protocol/ice_config.h" #include "remoting/signaling/iq_sender.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" #include "third_party/webrtc/base/socketaddress.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/jingle_messages.cc b/remoting/protocol/jingle_messages.cc index 8c28fdf..e444a44 100644 --- a/remoting/protocol/jingle_messages.cc +++ b/remoting/protocol/jingle_messages.cc
@@ -12,7 +12,7 @@ #include "remoting/protocol/session_plugin.h" #include "remoting/signaling/jid_util.h" #include "remoting/signaling/remoting_bot.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/protocol/jingle_messages.h b/remoting/protocol/jingle_messages.h index 019f35b..589a31e 100644 --- a/remoting/protocol/jingle_messages.h +++ b/remoting/protocol/jingle_messages.h
@@ -10,7 +10,7 @@ #include <string> #include "remoting/protocol/errors.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/webrtc/p2p/base/candidate.h" namespace remoting {
diff --git a/remoting/protocol/jingle_messages_unittest.cc b/remoting/protocol/jingle_messages_unittest.cc index 38d4844..680900c 100644 --- a/remoting/protocol/jingle_messages_unittest.cc +++ b/remoting/protocol/jingle_messages_unittest.cc
@@ -12,8 +12,8 @@ #include "remoting/protocol/content_description.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlAttr;
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc index bf86991..bb3eb73f 100644 --- a/remoting/protocol/jingle_session.cc +++ b/remoting/protocol/jingle_session.cc
@@ -26,8 +26,8 @@ #include "remoting/protocol/session_plugin.h" #include "remoting/protocol/transport.h" #include "remoting/signaling/iq_sender.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" #include "third_party/webrtc/p2p/base/candidate.h" using buzz::XmlElement;
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc index a477cf4..5d564f7 100644 --- a/remoting/protocol/jingle_session_manager.cc +++ b/remoting/protocol/jingle_session_manager.cc
@@ -14,9 +14,9 @@ #include "remoting/protocol/transport.h" #include "remoting/signaling/iq_sender.h" #include "remoting/signaling/signal_strategy.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" #include "third_party/webrtc/base/socketaddress.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" using buzz::QName;
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc index f97801c..4575e6e1 100644 --- a/remoting/protocol/jingle_session_unittest.cc +++ b/remoting/protocol/jingle_session_unittest.cc
@@ -32,7 +32,7 @@ #include "remoting/signaling/fake_signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using testing::_; using testing::AtLeast;
diff --git a/remoting/protocol/me2me_host_authenticator_factory.cc b/remoting/protocol/me2me_host_authenticator_factory.cc index d80462f..6e63fbe 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.cc +++ b/remoting/protocol/me2me_host_authenticator_factory.cc
@@ -15,7 +15,7 @@ #include "remoting/protocol/rejecting_authenticator.h" #include "remoting/protocol/token_validator.h" #include "remoting/signaling/jid_util.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/negotiating_authenticator_base.cc b/remoting/protocol/negotiating_authenticator_base.cc index 296d5ac..0c5a8018c 100644 --- a/remoting/protocol/negotiating_authenticator_base.cc +++ b/remoting/protocol/negotiating_authenticator_base.cc
@@ -15,7 +15,7 @@ #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/name_value_map.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/negotiating_authenticator_unittest.cc b/remoting/protocol/negotiating_authenticator_unittest.cc index cf3e96a..ae76795 100644 --- a/remoting/protocol/negotiating_authenticator_unittest.cc +++ b/remoting/protocol/negotiating_authenticator_unittest.cc
@@ -19,7 +19,7 @@ #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::DeleteArg;
diff --git a/remoting/protocol/negotiating_client_authenticator.cc b/remoting/protocol/negotiating_client_authenticator.cc index 9906b941..cc91e7e3 100644 --- a/remoting/protocol/negotiating_client_authenticator.cc +++ b/remoting/protocol/negotiating_client_authenticator.cc
@@ -18,7 +18,7 @@ #include "remoting/protocol/pairing_client_authenticator.h" #include "remoting/protocol/spake2_authenticator.h" #include "remoting/protocol/v2_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/negotiating_host_authenticator.cc b/remoting/protocol/negotiating_host_authenticator.cc index bd896f0..c7b098e 100644 --- a/remoting/protocol/negotiating_host_authenticator.cc +++ b/remoting/protocol/negotiating_host_authenticator.cc
@@ -19,7 +19,7 @@ #include "remoting/protocol/spake2_authenticator.h" #include "remoting/protocol/token_validator.h" #include "remoting/protocol/v2_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/pairing_authenticator_base.h b/remoting/protocol/pairing_authenticator_base.h index f1ccb3b2..81a8deaa 100644 --- a/remoting/protocol/pairing_authenticator_base.h +++ b/remoting/protocol/pairing_authenticator_base.h
@@ -8,7 +8,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "remoting/protocol/authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/pairing_client_authenticator.cc b/remoting/protocol/pairing_client_authenticator.cc index b35e7fbf..9961035 100644 --- a/remoting/protocol/pairing_client_authenticator.cc +++ b/remoting/protocol/pairing_client_authenticator.cc
@@ -9,7 +9,7 @@ #include "remoting/base/constants.h" #include "remoting/protocol/auth_util.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/pairing_host_authenticator.cc b/remoting/protocol/pairing_host_authenticator.cc index 7218530..173b263 100644 --- a/remoting/protocol/pairing_host_authenticator.cc +++ b/remoting/protocol/pairing_host_authenticator.cc
@@ -8,7 +8,7 @@ #include "base/logging.h" #include "remoting/base/constants.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/protocol_mock_objects.h b/remoting/protocol/protocol_mock_objects.h index 0dc09e0..bb5a4572 100644 --- a/remoting/protocol/protocol_mock_objects.h +++ b/remoting/protocol/protocol_mock_objects.h
@@ -31,7 +31,7 @@ #include "remoting/protocol/transport.h" #include "remoting/protocol/video_stub.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/remoting/protocol/rejecting_authenticator.cc b/remoting/protocol/rejecting_authenticator.cc index b23f298..b332b1e 100644 --- a/remoting/protocol/rejecting_authenticator.cc +++ b/remoting/protocol/rejecting_authenticator.cc
@@ -7,7 +7,7 @@ #include "base/callback.h" #include "base/logging.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/spake2_authenticator.cc b/remoting/protocol/spake2_authenticator.cc index 55bbea32..7577f2e 100644 --- a/remoting/protocol/spake2_authenticator.cc +++ b/remoting/protocol/spake2_authenticator.cc
@@ -16,7 +16,7 @@ #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/ssl_hmac_channel_authenticator.h" #include "third_party/boringssl/src/include/openssl/curve25519.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/spake2_authenticator_unittest.cc b/remoting/protocol/spake2_authenticator_unittest.cc index d203f00..9c8a40d 100644 --- a/remoting/protocol/spake2_authenticator_unittest.cc +++ b/remoting/protocol/spake2_authenticator_unittest.cc
@@ -13,7 +13,7 @@ #include "remoting/protocol/connection_tester.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::DeleteArg;
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc index cc93201..6b9aa21 100644 --- a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc +++ b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc
@@ -25,7 +25,7 @@ #include "remoting/protocol/p2p_stream_socket.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::NotNull;
diff --git a/remoting/protocol/third_party_authenticator_base.cc b/remoting/protocol/third_party_authenticator_base.cc index ba03712..96b9796 100644 --- a/remoting/protocol/third_party_authenticator_base.cc +++ b/remoting/protocol/third_party_authenticator_base.cc
@@ -11,7 +11,7 @@ #include "remoting/base/constants.h" #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/third_party_authenticator_base.h b/remoting/protocol/third_party_authenticator_base.h index 6e2fe574..34905fb 100644 --- a/remoting/protocol/third_party_authenticator_base.h +++ b/remoting/protocol/third_party_authenticator_base.h
@@ -11,7 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "remoting/protocol/authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/qname.h" namespace buzz {
diff --git a/remoting/protocol/third_party_authenticator_unittest.cc b/remoting/protocol/third_party_authenticator_unittest.cc index 953bf45e..519f115a 100644 --- a/remoting/protocol/third_party_authenticator_unittest.cc +++ b/remoting/protocol/third_party_authenticator_unittest.cc
@@ -22,7 +22,7 @@ #include "remoting/protocol/v2_authenticator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::DeleteArg;
diff --git a/remoting/protocol/third_party_client_authenticator.cc b/remoting/protocol/third_party_client_authenticator.cc index dd21135..304865f 100644 --- a/remoting/protocol/third_party_client_authenticator.cc +++ b/remoting/protocol/third_party_client_authenticator.cc
@@ -13,7 +13,7 @@ #include "remoting/base/constants.h" #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/third_party_host_authenticator.cc b/remoting/protocol/third_party_host_authenticator.cc index 0024480..0d3972d 100644 --- a/remoting/protocol/third_party_host_authenticator.cc +++ b/remoting/protocol/third_party_host_authenticator.cc
@@ -12,7 +12,7 @@ #include "base/logging.h" #include "remoting/base/constants.h" #include "remoting/protocol/token_validator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/v2_authenticator.cc b/remoting/protocol/v2_authenticator.cc index 9db2fef..42127bf3e 100644 --- a/remoting/protocol/v2_authenticator.cc +++ b/remoting/protocol/v2_authenticator.cc
@@ -12,7 +12,7 @@ #include "remoting/base/constants.h" #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/ssl_hmac_channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using crypto::P224EncryptedKeyExchange;
diff --git a/remoting/protocol/v2_authenticator_unittest.cc b/remoting/protocol/v2_authenticator_unittest.cc index 1315ad3..689ea50 100644 --- a/remoting/protocol/v2_authenticator_unittest.cc +++ b/remoting/protocol/v2_authenticator_unittest.cc
@@ -14,7 +14,7 @@ #include "remoting/protocol/connection_tester.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using testing::_; using testing::DeleteArg;
diff --git a/remoting/protocol/validating_authenticator.cc b/remoting/protocol/validating_authenticator.cc index 0595cb25..ee622be 100644 --- a/remoting/protocol/validating_authenticator.cc +++ b/remoting/protocol/validating_authenticator.cc
@@ -16,7 +16,7 @@ #include "base/memory/weak_ptr.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/channel_authenticator.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/validating_authenticator_unittest.cc b/remoting/protocol/validating_authenticator_unittest.cc index 32bed4c..dd23b72 100644 --- a/remoting/protocol/validating_authenticator_unittest.cc +++ b/remoting/protocol/validating_authenticator_unittest.cc
@@ -17,7 +17,7 @@ #include "remoting/protocol/validating_authenticator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc index 5477e718b..e4ce98ae 100644 --- a/remoting/protocol/webrtc_transport.cc +++ b/remoting/protocol/webrtc_transport.cc
@@ -28,8 +28,8 @@ #include "remoting/protocol/transport_context.h" #include "remoting/protocol/webrtc_audio_module.h" #include "remoting/protocol/webrtc_dummy_video_encoder.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #include "third_party/webrtc/api/test/fakeconstraints.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/protocol/webrtc_transport_unittest.cc b/remoting/protocol/webrtc_transport_unittest.cc index 59c644b..a2200c03 100644 --- a/remoting/protocol/webrtc_transport_unittest.cc +++ b/remoting/protocol/webrtc_transport_unittest.cc
@@ -23,7 +23,7 @@ #include "remoting/protocol/transport_context.h" #include "remoting/signaling/fake_signal_strategy.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting { namespace protocol {
diff --git a/remoting/signaling/BUILD.gn b/remoting/signaling/BUILD.gn index 7490c7ec..324f39d 100644 --- a/remoting/signaling/BUILD.gn +++ b/remoting/signaling/BUILD.gn
@@ -35,8 +35,7 @@ public_deps = [ "//remoting/proto", "//third_party/libjingle", - "//third_party/webrtc/libjingle/xmllite", - "//third_party/webrtc/libjingle/xmpp", + "//third_party/libjingle_xmpp", ] deps = [
diff --git a/remoting/signaling/DEPS b/remoting/signaling/DEPS index d6dad0c..735bee7 100644 --- a/remoting/signaling/DEPS +++ b/remoting/signaling/DEPS
@@ -1,7 +1,7 @@ include_rules = [ "+net", "+jingle", - "+third_party/libjingle", "+third_party/webrtc/base", - "+third_party/webrtc/libjingle", + "+third_party/libjingle_xmpp/xmllite", + "+third_party/libjingle_xmpp/xmpp", ]
diff --git a/remoting/signaling/delegating_signal_strategy.cc b/remoting/signaling/delegating_signal_strategy.cc index d0c10c05..83f23907 100644 --- a/remoting/signaling/delegating_signal_strategy.cc +++ b/remoting/signaling/delegating_signal_strategy.cc
@@ -8,8 +8,8 @@ #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" namespace remoting {
diff --git a/remoting/signaling/fake_signal_strategy.cc b/remoting/signaling/fake_signal_strategy.cc index b0ecd38b..fed04e5 100644 --- a/remoting/signaling/fake_signal_strategy.cc +++ b/remoting/signaling/fake_signal_strategy.cc
@@ -14,8 +14,8 @@ #include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "remoting/signaling/jid_util.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" namespace remoting {
diff --git a/remoting/signaling/iq_sender.cc b/remoting/signaling/iq_sender.cc index 725cc08..efa2528 100644 --- a/remoting/signaling/iq_sender.cc +++ b/remoting/signaling/iq_sender.cc
@@ -17,8 +17,8 @@ #include "base/time/time.h" #include "remoting/signaling/jid_util.h" #include "remoting/signaling/signal_strategy.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" namespace remoting {
diff --git a/remoting/signaling/iq_sender_unittest.cc b/remoting/signaling/iq_sender_unittest.cc index 810d5df..c03abd6 100644 --- a/remoting/signaling/iq_sender_unittest.cc +++ b/remoting/signaling/iq_sender_unittest.cc
@@ -14,8 +14,8 @@ #include "remoting/signaling/mock_signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using ::testing::_; using ::testing::DeleteArg;
diff --git a/remoting/signaling/log_to_server.cc b/remoting/signaling/log_to_server.cc index 0116cce6..5e05ace 100644 --- a/remoting/signaling/log_to_server.cc +++ b/remoting/signaling/log_to_server.cc
@@ -9,8 +9,8 @@ #include "remoting/base/constants.h" #include "remoting/signaling/iq_sender.h" #include "remoting/signaling/signal_strategy.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" using buzz::QName; using buzz::XmlElement;
diff --git a/remoting/signaling/mock_signal_strategy.h b/remoting/signaling/mock_signal_strategy.h index 79c3ea5..e4455f4 100644 --- a/remoting/signaling/mock_signal_strategy.h +++ b/remoting/signaling/mock_signal_strategy.h
@@ -7,7 +7,7 @@ #include "remoting/signaling/iq_sender.h" #include "remoting/signaling/signal_strategy.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/remoting/signaling/push_notification_subscriber.cc b/remoting/signaling/push_notification_subscriber.cc index 0984df66..bbeb02b 100644 --- a/remoting/signaling/push_notification_subscriber.cc +++ b/remoting/signaling/push_notification_subscriber.cc
@@ -10,7 +10,7 @@ #include "remoting/base/logging.h" #include "remoting/signaling/iq_sender.h" #include "remoting/signaling/jid_util.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/remoting/signaling/server_log_entry.cc b/remoting/signaling/server_log_entry.cc index aa8651f9..0b7b54dd 100644 --- a/remoting/signaling/server_log_entry.cc +++ b/remoting/signaling/server_log_entry.cc
@@ -8,7 +8,7 @@ #include "base/memory/ptr_util.h" #include "base/sys_info.h" #include "remoting/base/constants.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using base::SysInfo; using buzz::QName;
diff --git a/remoting/signaling/server_log_entry_unittest.cc b/remoting/signaling/server_log_entry_unittest.cc index ac3506d..80b5b22 100644 --- a/remoting/signaling/server_log_entry_unittest.cc +++ b/remoting/signaling/server_log_entry_unittest.cc
@@ -7,7 +7,7 @@ #include <sstream> #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" using buzz::QName; using buzz::XmlAttr;
diff --git a/remoting/signaling/xmpp_login_handler.cc b/remoting/signaling/xmpp_login_handler.cc index 1e83af8..d47da51 100644 --- a/remoting/signaling/xmpp_login_handler.cc +++ b/remoting/signaling/xmpp_login_handler.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/logging.h" #include "remoting/signaling/xmpp_stream_parser.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" // Undefine SendMessage and ERROR defined in Windows headers. #ifdef SendMessage
diff --git a/remoting/signaling/xmpp_login_handler_unittest.cc b/remoting/signaling/xmpp_login_handler_unittest.cc index 885c4ce7..c25206a2 100644 --- a/remoting/signaling/xmpp_login_handler_unittest.cc +++ b/remoting/signaling/xmpp_login_handler_unittest.cc
@@ -11,7 +11,7 @@ #include "base/run_loop.h" #include "remoting/signaling/xmpp_stream_parser.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" #ifdef SendMessage #undef SendMessage
diff --git a/remoting/signaling/xmpp_signal_strategy.cc b/remoting/signaling/xmpp_signal_strategy.cc index 8a019e4..32ab100 100644 --- a/remoting/signaling/xmpp_signal_strategy.cc +++ b/remoting/signaling/xmpp_signal_strategy.cc
@@ -32,7 +32,7 @@ #include "remoting/base/logging.h" #include "remoting/signaling/xmpp_login_handler.h" #include "remoting/signaling/xmpp_stream_parser.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" // Use 50 seconds keep-alive interval, in case routers terminate // connections that are idle for more than a minute.
diff --git a/remoting/signaling/xmpp_signal_strategy_unittest.cc b/remoting/signaling/xmpp_signal_strategy_unittest.cc index e991ec0..53147bc 100644 --- a/remoting/signaling/xmpp_signal_strategy_unittest.cc +++ b/remoting/signaling/xmpp_signal_strategy_unittest.cc
@@ -13,7 +13,7 @@ #include "net/socket/socket_test_util.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/remoting/signaling/xmpp_stream_parser.cc b/remoting/signaling/xmpp_stream_parser.cc index ee029de..d43ed02 100644 --- a/remoting/signaling/xmpp_stream_parser.cc +++ b/remoting/signaling/xmpp_stream_parser.cc
@@ -10,9 +10,9 @@ #include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "third_party/webrtc/libjingle/xmllite/xmlbuilder.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" -#include "third_party/webrtc/libjingle/xmllite/xmlparser.h" +#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" namespace remoting {
diff --git a/remoting/signaling/xmpp_stream_parser_unittest.cc b/remoting/signaling/xmpp_stream_parser_unittest.cc index 0b6dc1b4..299d9f7 100644 --- a/remoting/signaling/xmpp_stream_parser_unittest.cc +++ b/remoting/signaling/xmpp_stream_parser_unittest.cc
@@ -11,7 +11,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" namespace remoting {
diff --git a/skia/ext/bitmap_platform_device_cairo.h b/skia/ext/bitmap_platform_device_cairo.h index d1c9c350..5e6a6f3 100644 --- a/skia/ext/bitmap_platform_device_cairo.h +++ b/skia/ext/bitmap_platform_device_cairo.h
@@ -46,8 +46,6 @@ namespace skia { -class ScopedPlatformPaint; - // ----------------------------------------------------------------------------- // This is the Linux bitmap backing for Skia. We create a Cairo image surface // to store the backing buffer. This buffer is BGRA in memory (on little-endian @@ -98,14 +96,7 @@ // Graphics context used to draw into the surface. cairo_t* cairo_; - // True when there is a transform or clip that has not been set to the - // context. The context is retrieved for every text operation, and the - // transform and clip do not change as much. We can save time by not loading - // the clip and transform for every one. - bool config_dirty_; - DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice); - friend class ScopedPlatformPaint; }; } // namespace skia
diff --git a/skia/ext/bitmap_platform_device_mac_unittest.cc b/skia/ext/bitmap_platform_device_mac_unittest.cc index 9d8020b0..05d5089 100644 --- a/skia/ext/bitmap_platform_device_mac_unittest.cc +++ b/skia/ext/bitmap_platform_device_mac_unittest.cc
@@ -36,8 +36,7 @@ skia::CreateCanvas(bitmap_, CRASH_ON_FAILURE); canvas->setMatrix(transform); - ScopedPlatformPaint p(canvas.get()); - CGContextRef context = p.GetNativeDrawingContext(); + CGContextRef context = skia::GetNativeDrawingContext(canvas.get()); SkRect clip_rect = skia::CGRectToSkRect(CGContextGetClipBoundingBox(context)); transform.mapRect(&clip_rect); @@ -55,8 +54,7 @@ skia::CreateCanvas(bitmap_, CRASH_ON_FAILURE); canvas->setMatrix(transform); - ScopedPlatformPaint p(canvas.get()); - CGContextRef context = p.GetNativeDrawingContext(); + CGContextRef context = skia::GetNativeDrawingContext(canvas.get()); SkRect clip_rect = skia::CGRectToSkRect(CGContextGetClipBoundingBox(context)); transform.mapRect(&clip_rect);
diff --git a/skia/ext/bitmap_platform_device_skia.h b/skia/ext/bitmap_platform_device_skia.h index 854de47..024064f 100644 --- a/skia/ext/bitmap_platform_device_skia.h +++ b/skia/ext/bitmap_platform_device_skia.h
@@ -14,8 +14,6 @@ namespace skia { -class ScopedPlatformPaint; - // ----------------------------------------------------------------------------- // For now we just use SkBitmap for SkBitmapDevice // @@ -50,8 +48,6 @@ const SkIRect& clip_bounds) override; DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice); - - friend class ScopedPlatformPaint; }; } // namespace skia
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc index b792c0fd..8270be32 100644 --- a/skia/ext/bitmap_platform_device_win.cc +++ b/skia/ext/bitmap_platform_device_win.cc
@@ -35,7 +35,6 @@ void DrawToNativeContext(SkCanvas* canvas, HDC destination_hdc, int x, int y, const RECT* src_rect) { - ScopedPlatformPaint p(canvas); RECT temp_rect; if (!src_rect) { temp_rect.left = 0; @@ -44,7 +43,7 @@ temp_rect.bottom = canvas->imageInfo().height(); src_rect = &temp_rect; } - skia::CopyHDC(p.GetNativeDrawingContext(), destination_hdc, x, y, + skia::CopyHDC(skia::GetNativeDrawingContext(canvas), destination_hdc, x, y, canvas->imageInfo().isOpaque(), *src_rect, canvas->getTotalMatrix()); }
diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h index b750e166..82f17ff3 100644 --- a/skia/ext/bitmap_platform_device_win.h +++ b/skia/ext/bitmap_platform_device_win.h
@@ -11,8 +11,6 @@ namespace skia { -class ScopedPlatformPaint; - // A device is basically a wrapper around SkBitmap that provides a surface for // SkCanvas to draw into. Our device provides a surface Windows can also write // to. BitmapPlatformDevice creates a bitmap using CreateDIBSection() in a @@ -75,7 +73,6 @@ void LoadConfig(const SkMatrix& transform, const SkIRect& clip_bounds); DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice); - friend class ScopedPlatformPaint; }; } // namespace skia
diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc index 52a11c7b..81093801 100644 --- a/skia/ext/platform_canvas.cc +++ b/skia/ext/platform_canvas.cc
@@ -90,18 +90,17 @@ } #endif -ScopedPlatformPaint::ScopedPlatformPaint(SkCanvas* canvas) : - canvas_(canvas), - native_drawing_context_(nullptr) { - // TODO(tomhudson) we're assuming non-null canvas? +NativeDrawingContext GetNativeDrawingContext(SkCanvas* canvas) { PlatformDevice* platform_device = GetPlatformDevice(canvas->getTopDevice(true)); - if (platform_device) { - // Compensate for drawing to a layer rather than the entire canvas - SkMatrix ctm; - SkIRect clip_bounds; - canvas->temporary_internal_describeTopLayer(&ctm, &clip_bounds); - native_drawing_context_ = platform_device->BeginPlatformPaint(ctm, clip_bounds); - } + if (!platform_device) + return nullptr; + + // Compensate for drawing to a layer rather than the entire canvas + SkMatrix ctm; + SkIRect clip_bounds; + canvas->temporary_internal_describeTopLayer(&ctm, &clip_bounds); + + return platform_device->BeginPlatformPaint(ctm, clip_bounds); } } // namespace skia
diff --git a/skia/ext/platform_canvas.h b/skia/ext/platform_canvas.h index 4a9692f1..ef657837 100644 --- a/skia/ext/platform_canvas.h +++ b/skia/ext/platform_canvas.h
@@ -123,29 +123,11 @@ // Returns true if native platform routines can be used to draw on the // given canvas. If this function returns false, -// ScopedPlatformPaint::GetNativeDrawingContext() should return NULL. +// GetNativeDrawingContext() should return NULL. SK_API bool SupportsPlatformPaint(const SkCanvas* canvas); -// This object guards calls to platform drawing routines. The surface -// returned from GetNativeDrawingContext() can be used with the native platform -// routines. -class SK_API ScopedPlatformPaint { - public: - explicit ScopedPlatformPaint(SkCanvas* canvas); - - // Returns the NativeDrawingContext to use for native platform drawing calls. - NativeDrawingContext GetNativeDrawingContext() { - return native_drawing_context_; - } - - private: - SkCanvas* canvas_; - NativeDrawingContext native_drawing_context_; - - // Disallow copy and assign - ScopedPlatformPaint(const ScopedPlatformPaint&); - ScopedPlatformPaint& operator=(const ScopedPlatformPaint&); -}; +// Returns the NativeDrawingContext to use for native platform drawing calls. +SK_API NativeDrawingContext GetNativeDrawingContext(SkCanvas* canvas); // Following routines are used in print preview workflow to mark the // preview metafile.
diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc index 38d574f..2282a8f 100644 --- a/skia/ext/platform_canvas_unittest.cc +++ b/skia/ext/platform_canvas_unittest.cc
@@ -136,8 +136,7 @@ #if defined(OS_WIN) void DrawNativeRect(SkCanvas& canvas, int x, int y, int w, int h) { - skia::ScopedPlatformPaint scoped_platform_paint(&canvas); - HDC dc = scoped_platform_paint.GetNativeDrawingContext(); + HDC dc = skia::GetNativeDrawingContext(&canvas); RECT inner_rc; inner_rc.left = x; @@ -148,8 +147,7 @@ } #elif defined(OS_MACOSX) void DrawNativeRect(SkCanvas& canvas, int x, int y, int w, int h) { - skia::ScopedPlatformPaint scoped_platform_paint(&canvas); - CGContextRef context = scoped_platform_paint.GetNativeDrawingContext(); + CGContextRef context = skia::GetNativeDrawingContext(&canvas); CGRect inner_rc = CGRectMake(x, y, w, h); // RGBA opaque black @@ -160,8 +158,7 @@ } #elif defined(USE_CAIRO) void DrawNativeRect(SkCanvas& canvas, int x, int y, int w, int h) { - skia::ScopedPlatformPaint scoped_platform_paint(&canvas); - cairo_t* context = scoped_platform_paint.GetNativeDrawingContext(); + cairo_t* context = skia::GetNativeDrawingContext(&canvas); cairo_rectangle(context, x, y, w, h); cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
diff --git a/skia/ext/platform_device.h b/skia/ext/platform_device.h index 721893a..b756aa6 100644 --- a/skia/ext/platform_device.h +++ b/skia/ext/platform_device.h
@@ -16,7 +16,6 @@ namespace skia { class PlatformDevice; -class ScopedPlatformPaint; // The following routines provide accessor points for the functionality // exported by the various PlatformDevice ports. @@ -47,14 +46,11 @@ public: virtual ~PlatformDevice(); - private: // The DC that corresponds to the bitmap, used for GDI operations drawing // into the bitmap. This is possibly heavyweight, so it should be existant // only during one pass of rendering. virtual NativeDrawingContext BeginPlatformPaint(const SkMatrix& transform, const SkIRect& clip_bounds) = 0; - - friend class ScopedPlatformPaint; }; } // namespace skia
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h index 0937d1dc..eb96228 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
@@ -24,7 +24,6 @@ class WrapperMarkingData { public: - friend class ScriptWrappableVisitor; WrapperMarkingData(void (*traceWrappersCallback)(const WrapperVisitor*, const void*), @@ -50,9 +49,7 @@ return !m_rawObjectPointer || heapObjectHeader()->isWrapperHeaderMarked(); } - // Returns raw object pointer. Beware it doesn't necessarily point to the - // beginning of the object. - const void* rawObjectPointer() { return m_rawObjectPointer; } + inline const void* rawObjectPointer() { return m_rawObjectPointer; } private: inline bool shouldBeInvalidated() { @@ -69,6 +66,8 @@ void (*m_traceWrappersCallback)(const WrapperVisitor*, const void*); HeapObjectHeader* (*m_heapObjectHeaderCallback)(const void*); const void* m_rawObjectPointer; + + friend class ScriptWrappableVisitor; }; // ScriptWrappableVisitor is able to trace through the objects to get all @@ -107,6 +106,8 @@ template <typename T> static void writeBarrier(const void* srcObject, const T* dstObject) { + static_assert(!NeedsAdjustAndMark<T>::value, + "wrapper tracing is not supported within mixins"); if (!RuntimeEnabledFeatures::traceWrappablesEnabled()) { return; } @@ -122,30 +123,13 @@ const ThreadState* threadState = ThreadState::current(); DCHECK(threadState); - // We can only safely check the marking state of |dstObject| for non-mixin - // objects or if we are outside of object construction. - if (!IsGarbageCollectedMixin<T>::value || - !threadState->isMixinInConstruction()) { - // If the wrapper is already marked we can bail out here. - if (TraceTrait<T>::heapObjectHeader(dstObject)->isWrapperHeaderMarked()) - return; - // Otherwise, eagerly mark the wrapper header and put the object on the - // marking deque for further processing. - WrapperVisitor* const visitor = currentVisitor(threadState->isolate()); - if (visitor->pushToMarkingDeque(TraceTrait<T>::traceMarkedWrapper, - TraceTrait<T>::heapObjectHeader, - dstObject)) { - TraceTrait<T>::markWrapperNoTracing(visitor, dstObject); - } + // If the wrapper is already marked we can bail out here. + if (TraceTrait<T>::heapObjectHeader(dstObject)->isWrapperHeaderMarked()) return; - } - - // We cannot eagerly mark the wrapper header because of mixin - // construction. Delay further processing until AdvanceMarking, which has to - // be in a non-construction state. This path may result in duplicates. - currentVisitor(threadState->isolate()) - ->pushToMarkingDeque(TraceTrait<T>::markAndTraceWrapper, - TraceTrait<T>::heapObjectHeader, dstObject); + // Otherwise, eagerly mark the wrapper header and put the object on the + // marking deque for further processing. + WrapperVisitor* const visitor = currentVisitor(threadState->isolate()); + visitor->markAndPushToMarkingDeque(dstObject); } void RegisterV8References(const std::vector<std::pair<void*, void*>>& @@ -171,6 +155,21 @@ void invalidateDeadObjectsInMarkingDeque(); + bool markWrapperHeader(HeapObjectHeader*) const; + + // Mark wrappers in all worlds for the given script wrappable as alive in + // V8. + void markWrappersInAllWorlds(const ScriptWrappable*) const override; + + WTF::Deque<WrapperMarkingData>* getMarkingDeque() { return &m_markingDeque; } + WTF::Deque<WrapperMarkingData>* getVerifierDeque() { + return &m_verifierDeque; + } + WTF::Vector<HeapObjectHeader*>* getHeadersToUnmark() { + return &m_headersToUnmark; + } + + protected: bool pushToMarkingDeque( void (*traceWrappersCallback)(const WrapperVisitor*, const void*), HeapObjectHeader* (*heapObjectHeaderCallback)(const void*), @@ -189,20 +188,6 @@ return true; } - bool markWrapperHeader(HeapObjectHeader*) const; - - // Mark wrappers in all worlds for the given script wrappable as alive in - // V8. - void markWrappersInAllWorlds(const ScriptWrappable*) const override; - - WTF::Deque<WrapperMarkingData>* getMarkingDeque() { return &m_markingDeque; } - WTF::Deque<WrapperMarkingData>* getVerifierDeque() { - return &m_verifierDeque; - } - WTF::Vector<HeapObjectHeader*>* getHeadersToUnmark() { - return &m_headersToUnmark; - } - private: // Returns true if wrapper tracing is currently in progress, i.e., // TracePrologue has been called, and TraceEpilogue has not yet been called.
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp index a3e2680..0cfb99f 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
@@ -189,9 +189,8 @@ ScriptWrappableVisitor* visitor = V8PerIsolateData::from(scope.isolate())->scriptWrappableVisitor(); visitor->TracePrologue(); - visitor->pushToMarkingDeque( - TraceTrait<DeathAwareScriptWrappable>::markAndTraceWrapper, - TraceTrait<DeathAwareScriptWrappable>::heapObjectHeader, object); + + visitor->markAndPushToMarkingDeque(object); EXPECT_EQ(visitor->getMarkingDeque()->first().rawObjectPointer(), object);
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp index 8f5f5808..4455c27 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -91,13 +91,15 @@ // Event listeners would keep DOMWrapperWorld objects alive for too long. // Also, they have references to JS objects, which become dangling once Heap // is destroyed. - for (auto it = m_eventListeners.begin(); it != m_eventListeners.end();) { - V8AbstractEventListener* listener = *it; - // clearListenerObject() will unregister the listener from - // m_eventListeners, and invalidate the iterator, so we have to advance - // it first. - ++it; - listener->clearListenerObject(); + m_closing = true; + HeapHashSet<Member<V8AbstractEventListener>> listeners; + listeners.swap(m_eventListeners); + while (!listeners.isEmpty()) { + for (const auto& listener : listeners) + listener->clearListenerObject(); + listeners.clear(); + // Pick up any additions made while iterating. + listeners.swap(m_eventListeners); } removeAllEventListeners(); @@ -139,7 +141,7 @@ void WorkerGlobalScope::deregisterEventListener( V8AbstractEventListener* eventListener) { auto it = m_eventListeners.find(eventListener); - CHECK(it != m_eventListeners.end()); + CHECK(it != m_eventListeners.end() || m_closing); m_eventListeners.remove(it); }
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h index 6b19d232..24101502 100644 --- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h +++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -208,7 +208,7 @@ const double m_timeOrigin; - HeapListHashSet<Member<V8AbstractEventListener>> m_eventListeners; + HeapHashSet<Member<V8AbstractEventListener>> m_eventListeners; HeapHashMap<int, Member<ErrorEvent>> m_pendingErrorEvents; int m_lastPendingErrorEventId;
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h index 15e97551..e2e3146 100644 --- a/third_party/WebKit/Source/platform/heap/TraceTraits.h +++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -188,7 +188,6 @@ static void trace(Visitor*, void* self); static void trace(InlinedGlobalMarkingVisitor, void* self); - static void markAndTraceWrapper(const WrapperVisitor*, const void*); static void markWrapperNoTracing(const WrapperVisitor*, const void*); static void traceMarkedWrapper(const WrapperVisitor*, const void*); static HeapObjectHeader* heapObjectHeader(const void*); @@ -234,16 +233,6 @@ } template <typename T> -void TraceTrait<T>::markAndTraceWrapper(const WrapperVisitor* visitor, - const void* t) { - const T* traceable = ToWrapperTracingType(t); - if (visitor->markWrapperHeader(heapObjectHeader(traceable))) { - visitor->markWrappersInAllWorlds(traceable); - visitor->dispatchTraceWrappers(traceable); - } -} - -template <typename T> void TraceTrait<T>::markWrapperNoTracing(const WrapperVisitor* visitor, const void* t) { const T* traceable = ToWrapperTracingType(t);
diff --git a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h index bd63dc07..d93767a 100644 --- a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h +++ b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
@@ -105,10 +105,7 @@ return; } - if (pushToMarkingDeque(TraceTrait<T>::traceMarkedWrapper, - TraceTrait<T>::heapObjectHeader, traceable)) { - TraceTrait<T>::markWrapperNoTracing(this, traceable); - } + markAndPushToMarkingDeque(traceable); } /** @@ -164,6 +161,15 @@ // don't require marking wrappers in all worlds, so just nop on those. } + template <typename T> + void markAndPushToMarkingDeque(const T* traceable) const { + if (pushToMarkingDeque(TraceTrait<T>::traceMarkedWrapper, + TraceTrait<T>::heapObjectHeader, traceable)) { + TraceTrait<T>::markWrapperNoTracing(this, traceable); + } + } + + protected: // Returns true if pushing to the marking deque was successful. virtual bool pushToMarkingDeque( void (*traceWrappersCallback)(const WrapperVisitor*, const void*),
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn new file mode 100644 index 0000000..6b01b4f --- /dev/null +++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -0,0 +1,153 @@ +# Copyright 2016 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. + +# TODO(kjellander): Remove remaining dependencies on the WebRTC codebase. +import("../webrtc/build/webrtc.gni") + +group("libjingle_xmpp") { + public_deps = [ + ":rtc_xmllite", + ":rtc_xmpp", + ] +} + +rtc_static_library("rtc_xmllite") { + sources = [ + "xmllite/qname.cc", + "xmllite/qname.h", + "xmllite/xmlbuilder.cc", + "xmllite/xmlbuilder.h", + "xmllite/xmlconstants.cc", + "xmllite/xmlconstants.h", + "xmllite/xmlelement.cc", + "xmllite/xmlelement.h", + "xmllite/xmlnsstack.cc", + "xmllite/xmlnsstack.h", + "xmllite/xmlparser.cc", + "xmllite/xmlparser.h", + "xmllite/xmlprinter.cc", + "xmllite/xmlprinter.h", + ] + + deps = [ + "//third_party/webrtc/base:rtc_base", + ] + public_deps = [ + "//third_party/expat", + ] +} + +config("rtc_xmpp_warnings_config") { + # GN orders flags on a target before flags from configs. The default config + # adds these flags so to cancel them out they need to come from a config and + # cannot be on the target directly. + if (is_android) { + cflags = [ "-Wno-error" ] + } +} + +config("rtc_xmpp_inherited_config") { + defines = [ + "FEATURE_ENABLE_SSL", + "FEATURE_ENABLE_VOICEMAIL", + ] +} + +rtc_static_library("rtc_xmpp") { + cflags = [] + sources = [ + "xmpp/asyncsocket.h", + "xmpp/constants.cc", + "xmpp/constants.h", + "xmpp/jid.cc", + "xmpp/jid.h", + "xmpp/plainsaslhandler.h", + "xmpp/prexmppauth.h", + "xmpp/saslcookiemechanism.h", + "xmpp/saslhandler.h", + "xmpp/saslmechanism.cc", + "xmpp/saslmechanism.h", + "xmpp/saslplainmechanism.h", + "xmpp/xmppclient.cc", + "xmpp/xmppclient.h", + "xmpp/xmppclientsettings.h", + "xmpp/xmppengine.h", + "xmpp/xmppengineimpl.cc", + "xmpp/xmppengineimpl.h", + "xmpp/xmppengineimpl_iq.cc", + "xmpp/xmpplogintask.cc", + "xmpp/xmpplogintask.h", + "xmpp/xmppstanzaparser.cc", + "xmpp/xmppstanzaparser.h", + "xmpp/xmpptask.cc", + "xmpp/xmpptask.h", + ] + + defines = [ "FEATURE_ENABLE_SSL" ] + + deps = [ + ":rtc_xmllite", + "//third_party/webrtc/base:rtc_base", + ] + public_deps = [ + "//third_party/expat", + ] + configs += [ ":rtc_xmpp_warnings_config" ] + + public_configs = [ ":rtc_xmpp_inherited_config" ] + + if (is_nacl) { + deps += [ "//native_client_sdk/src/libraries/nacl_io" ] + } + + if (is_posix && is_debug) { + # The Chromium configs defines this for all posix _except_ for ios & mac. + # We want it there as well, e.g. because ASSERT and friends trigger off of + # it. + defines += [ "_DEBUG" ] + } +} + +config("libjingle_xmpp_unittests_config") { + # GN orders flags on a target before flags from configs. The default config + # adds -Wall, and this flag have to be after -Wall -- so they need to + # come from a config and can"t be on the target directly. + if (is_clang) { + cflags = [ + "-Wno-missing-braces", + "-Wno-sign-compare", + "-Wno-unused-const-variable", + ] + } +} + +rtc_test("libjingle_xmpp_unittests") { + configs += [ ":libjingle_xmpp_unittests_config" ] + + deps = [ + ":libjingle_xmpp", + + # TODO(kjellander): Refactor/remove this dependency. It is needed by + # third_party/webrtc_overrides/webrtc/base/win32socketinit.cc. + "//net", + "//testing/gtest", + ] + + sources = [ + "run_all_unittests.cc", + "xmllite/qname_unittest.cc", + "xmllite/xmlbuilder_unittest.cc", + "xmllite/xmlelement_unittest.cc", + "xmllite/xmlnsstack_unittest.cc", + "xmllite/xmlparser_unittest.cc", + "xmllite/xmlprinter_unittest.cc", + "xmpp/fakexmppclient.h", + "xmpp/jid_unittest.cc", + "xmpp/util_unittest.cc", + "xmpp/util_unittest.h", + "xmpp/xmppengine_unittest.cc", + "xmpp/xmpplogintask_unittest.cc", + "xmpp/xmppstanzaparser_unittest.cc", + ] +}
diff --git a/third_party/libjingle_xmpp/DEPS b/third_party/libjingle_xmpp/DEPS new file mode 100644 index 0000000..4d25c08 --- /dev/null +++ b/third_party/libjingle_xmpp/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "run_all_unittests\.cc": [ + "+testing", + ] +}
diff --git a/third_party/libjingle_xmpp/LICENSE b/third_party/libjingle_xmpp/LICENSE new file mode 100644 index 0000000..4c41b7b2 --- /dev/null +++ b/third_party/libjingle_xmpp/LICENSE
@@ -0,0 +1,29 @@ +Copyright (c) 2011, The WebRTC project authors. 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 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 +HOLDER 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.
diff --git a/third_party/libjingle_xmpp/OWNERS b/third_party/libjingle_xmpp/OWNERS new file mode 100644 index 0000000..e5606c61a --- /dev/null +++ b/third_party/libjingle_xmpp/OWNERS
@@ -0,0 +1,6 @@ +henrika@chromium.org +henrikg@chromium.org +hta@chromium.org +perkj@chromium.org +sergeyu@chromium.org +tommi@chromium.org
diff --git a/third_party/libjingle_xmpp/README.chromium b/third_party/libjingle_xmpp/README.chromium new file mode 100644 index 0000000..2fa85aa --- /dev/null +++ b/third_party/libjingle_xmpp/README.chromium
@@ -0,0 +1,20 @@ +Name: libjingle XMPP and xmllite libraries +URL: https://chromium.googlesource.com/external/webrtc +Version: 5493b8a59deb16cf0481e24707a0ed72d19047dc +License: BSD +License File: LICENSE +Security Critical: Yes +License Android Compatible: Yes + +Description: +XMPP (Extensible Messaging and Presence Protocol) is a communications protocol +for messaging based on XML. xmllite is a minimalistic library for parsing and +generating XML. The source for these libraries originates from the libjingle +project, which was merged into the WebRTC codebase where it received minor +updates. As time passed, the code was no longer used in WebRTC but is still used +in Chromium. Only the parts that are used in Chromium are added here. + +Local Modifications: +* Include paths in third_party/libjingle_xmpp/xmllite and + third_party/libjingle_xmpp/xmpp are updated to reflect the new + absolute paths to their own headers.
diff --git a/third_party/libjingle_xmpp/run_all_unittests.cc b/third_party/libjingle_xmpp/run_all_unittests.cc new file mode 100644 index 0000000..49c887b --- /dev/null +++ b/third_party/libjingle_xmpp/run_all_unittests.cc
@@ -0,0 +1,10 @@ +// Copyright (c) 2016 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. + +#include "testing/gtest/include/gtest/gtest.h" + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}
diff --git a/third_party/libjingle_xmpp/xmllite/DEPS b/third_party/libjingle_xmpp/xmllite/DEPS new file mode 100644 index 0000000..063f1fe --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+third_party/expat", + "+third_party/webrtc/base", +]
diff --git a/third_party/libjingle_xmpp/xmllite/qname.cc b/third_party/libjingle_xmpp/xmllite/qname.cc new file mode 100644 index 0000000..dee94093 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/qname.cc
@@ -0,0 +1,78 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/qname.h" + +namespace buzz { + +QName::QName() { +} + +QName::QName(const QName& qname) + : namespace_(qname.namespace_), + local_part_(qname.local_part_) { +} + +QName::QName(const StaticQName& const_value) + : namespace_(const_value.ns), + local_part_(const_value.local) { +} + +QName::QName(const std::string& ns, const std::string& local) + : namespace_(ns), + local_part_(local) { +} + +QName::QName(const std::string& merged_or_local) { + size_t i = merged_or_local.rfind(':'); + if (i == std::string::npos) { + local_part_ = merged_or_local; + } else { + namespace_ = merged_or_local.substr(0, i); + local_part_ = merged_or_local.substr(i + 1); + } +} + +QName::~QName() { +} + +std::string QName::Merged() const { + if (namespace_[0] == '\0') + return local_part_; + + std::string result; + result.reserve(namespace_.length() + 1 + local_part_.length()); + result += namespace_; + result += ':'; + result += local_part_; + return result; +} + +bool QName::IsEmpty() const { + return namespace_.empty() && local_part_.empty(); +} + +int QName::Compare(const StaticQName& other) const { + int result = local_part_.compare(other.local); + if (result != 0) + return result; + + return namespace_.compare(other.ns); +} + +int QName::Compare(const QName& other) const { + int result = local_part_.compare(other.local_part_); + if (result != 0) + return result; + + return namespace_.compare(other.namespace_); +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/qname.h b/third_party/libjingle_xmpp/xmllite/qname.h new file mode 100644 index 0000000..1e772d3 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/qname.h
@@ -0,0 +1,83 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_QNAME_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_QNAME_H_ + +#include <string> + +namespace buzz { + +class QName; + +// StaticQName is used to represend constant quailified names. They +// can be initialized statically and don't need intializers code, e.g. +// const StaticQName QN_FOO = { "foo_namespace", "foo" }; +// +// Beside this use case, QName should be used everywhere +// else. StaticQName instances are implicitly converted to QName +// objects. +struct StaticQName { + const char* const ns; + const char* const local; + + bool operator==(const QName& other) const; + bool operator!=(const QName& other) const; +}; + +class QName { + public: + QName(); + QName(const QName& qname); + QName(const StaticQName& const_value); + QName(const std::string& ns, const std::string& local); + explicit QName(const std::string& merged_or_local); + ~QName(); + + const std::string& Namespace() const { return namespace_; } + const std::string& LocalPart() const { return local_part_; } + std::string Merged() const; + bool IsEmpty() const; + + int Compare(const StaticQName& other) const; + int Compare(const QName& other) const; + + bool operator==(const StaticQName& other) const { + return Compare(other) == 0; + } + bool operator==(const QName& other) const { + return Compare(other) == 0; + } + bool operator!=(const StaticQName& other) const { + return Compare(other) != 0; + } + bool operator!=(const QName& other) const { + return Compare(other) != 0; + } + bool operator<(const QName& other) const { + return Compare(other) < 0; + } + + private: + std::string namespace_; + std::string local_part_; +}; + +inline bool StaticQName::operator==(const QName& other) const { + return other.Compare(*this) == 0; +} + +inline bool StaticQName::operator!=(const QName& other) const { + return other.Compare(*this) != 0; +} + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMLLITE_QNAME_H_
diff --git a/third_party/libjingle_xmpp/xmllite/qname_unittest.cc b/third_party/libjingle_xmpp/xmllite/qname_unittest.cc new file mode 100644 index 0000000..e9009a1 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/qname_unittest.cc
@@ -0,0 +1,114 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <string> +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::StaticQName; +using buzz::QName; + +TEST(QNameTest, TestTrivial) { + QName name("test"); + EXPECT_EQ(name.LocalPart(), "test"); + EXPECT_EQ(name.Namespace(), ""); +} + +TEST(QNameTest, TestSplit) { + QName name("a:test"); + EXPECT_EQ(name.LocalPart(), "test"); + EXPECT_EQ(name.Namespace(), "a"); + QName name2("a-very:long:namespace:test-this"); + EXPECT_EQ(name2.LocalPart(), "test-this"); + EXPECT_EQ(name2.Namespace(), "a-very:long:namespace"); +} + +TEST(QNameTest, TestMerge) { + QName name("a", "test"); + EXPECT_EQ(name.LocalPart(), "test"); + EXPECT_EQ(name.Namespace(), "a"); + EXPECT_EQ(name.Merged(), "a:test"); + QName name2("a-very:long:namespace", "test-this"); + EXPECT_EQ(name2.LocalPart(), "test-this"); + EXPECT_EQ(name2.Namespace(), "a-very:long:namespace"); + EXPECT_EQ(name2.Merged(), "a-very:long:namespace:test-this"); +} + +TEST(QNameTest, TestAssignment) { + QName name("a", "test"); + // copy constructor + QName namecopy(name); + EXPECT_EQ(namecopy.LocalPart(), "test"); + EXPECT_EQ(namecopy.Namespace(), "a"); + QName nameassigned(""); + nameassigned = name; + EXPECT_EQ(nameassigned.LocalPart(), "test"); + EXPECT_EQ(nameassigned.Namespace(), "a"); +} + +TEST(QNameTest, TestConstAssignment) { + StaticQName name = { "a", "test" }; + QName namecopy(name); + EXPECT_EQ(namecopy.LocalPart(), "test"); + EXPECT_EQ(namecopy.Namespace(), "a"); + QName nameassigned(""); + nameassigned = name; + EXPECT_EQ(nameassigned.LocalPart(), "test"); + EXPECT_EQ(nameassigned.Namespace(), "a"); +} + +TEST(QNameTest, TestEquality) { + QName name("a-very:long:namespace:test-this"); + QName name2("a-very:long:namespace", "test-this"); + QName name3("a-very:long:namespaxe", "test-this"); + EXPECT_TRUE(name == name2); + EXPECT_FALSE(name == name3); +} + +TEST(QNameTest, TestCompare) { + QName name("a"); + QName name2("nsa", "a"); + QName name3("nsa", "b"); + QName name4("nsb", "b"); + + EXPECT_TRUE(name < name2); + EXPECT_FALSE(name2 < name); + + EXPECT_FALSE(name2 < name2); + + EXPECT_TRUE(name2 < name3); + EXPECT_FALSE(name3 < name2); + + EXPECT_TRUE(name3 < name4); + EXPECT_FALSE(name4 < name3); +} + +TEST(QNameTest, TestStaticQName) { + const StaticQName const_name1 = { "namespace", "local-name1" }; + const StaticQName const_name2 = { "namespace", "local-name2" }; + const QName name("namespace", "local-name1"); + const QName name1 = const_name1; + const QName name2 = const_name2; + + EXPECT_TRUE(name == const_name1); + EXPECT_TRUE(const_name1 == name); + EXPECT_FALSE(name != const_name1); + EXPECT_FALSE(const_name1 != name); + + EXPECT_TRUE(name == name1); + EXPECT_TRUE(name1 == name); + EXPECT_FALSE(name != name1); + EXPECT_FALSE(name1 != name); + + EXPECT_FALSE(name == name2); + EXPECT_FALSE(name2 == name); + EXPECT_TRUE(name != name2); + EXPECT_TRUE(name2 != name); +}
diff --git a/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc b/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc new file mode 100644 index 0000000..68ef3d5a --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlbuilder.cc
@@ -0,0 +1,130 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" + +#include <set> +#include <vector> +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/webrtc/base/common.h" + +namespace buzz { + +XmlBuilder::XmlBuilder() : + pelCurrent_(NULL), + pelRoot_(), + pvParents_(new std::vector<XmlElement *>()) { +} + +void +XmlBuilder::Reset() { + pelRoot_.reset(); + pelCurrent_ = NULL; + pvParents_->clear(); +} + +XmlElement * +XmlBuilder::BuildElement(XmlParseContext * pctx, + const char * name, const char ** atts) { + QName tagName(pctx->ResolveQName(name, false)); + if (tagName.IsEmpty()) + return NULL; + + XmlElement * pelNew = new XmlElement(tagName); + + if (!*atts) + return pelNew; + + std::set<QName> seenNonlocalAtts; + + while (*atts) { + QName attName(pctx->ResolveQName(*atts, true)); + if (attName.IsEmpty()) { + delete pelNew; + return NULL; + } + + // verify that namespaced names are unique + if (!attName.Namespace().empty()) { + if (seenNonlocalAtts.count(attName)) { + delete pelNew; + return NULL; + } + seenNonlocalAtts.insert(attName); + } + + pelNew->AddAttr(attName, std::string(*(atts + 1))); + atts += 2; + } + + return pelNew; +} + +void +XmlBuilder::StartElement(XmlParseContext * pctx, + const char * name, const char ** atts) { + XmlElement * pelNew = BuildElement(pctx, name, atts); + if (pelNew == NULL) { + pctx->RaiseError(XML_ERROR_SYNTAX); + return; + } + + if (!pelCurrent_) { + pelCurrent_ = pelNew; + pelRoot_.reset(pelNew); + pvParents_->push_back(NULL); + } else { + pelCurrent_->AddElement(pelNew); + pvParents_->push_back(pelCurrent_); + pelCurrent_ = pelNew; + } +} + +void +XmlBuilder::EndElement(XmlParseContext * pctx, const char * name) { + RTC_UNUSED(pctx); + RTC_UNUSED(name); + pelCurrent_ = pvParents_->back(); + pvParents_->pop_back(); +} + +void +XmlBuilder::CharacterData(XmlParseContext * pctx, + const char * text, int len) { + RTC_UNUSED(pctx); + if (pelCurrent_) { + pelCurrent_->AddParsedText(text, len); + } +} + +void +XmlBuilder::Error(XmlParseContext * pctx, XML_Error err) { + RTC_UNUSED(pctx); + RTC_UNUSED(err); + pelRoot_.reset(NULL); + pelCurrent_ = NULL; + pvParents_->clear(); +} + +XmlElement * +XmlBuilder::CreateElement() { + return pelRoot_.release(); +} + +XmlElement * +XmlBuilder::BuiltElement() { + return pelRoot_.get(); +} + +XmlBuilder::~XmlBuilder() { +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/xmlbuilder.h b/third_party/libjingle_xmpp/xmllite/xmlbuilder.h new file mode 100644 index 0000000..4acf3fe --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlbuilder.h
@@ -0,0 +1,61 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef _xmlbuilder_h_ +#define _xmlbuilder_h_ + +#include <memory> +#include <string> +#include <vector> +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" + +#ifdef EXPAT_RELATIVE_PATH +#include "expat.h" +#else +#include "third_party/expat/v2_0_1/Source/lib/expat.h" +#endif // EXPAT_RELATIVE_PATH + +namespace buzz { + +class XmlElement; +class XmlParseContext; + + +class XmlBuilder : public XmlParseHandler { +public: + XmlBuilder(); + + static XmlElement * BuildElement(XmlParseContext * pctx, + const char * name, const char ** atts); + virtual void StartElement(XmlParseContext * pctx, + const char * name, const char ** atts); + virtual void EndElement(XmlParseContext * pctx, const char * name); + virtual void CharacterData(XmlParseContext * pctx, + const char * text, int len); + virtual void Error(XmlParseContext * pctx, XML_Error); + virtual ~XmlBuilder(); + + void Reset(); + + // Take ownership of the built element; second call returns NULL + XmlElement * CreateElement(); + + // Peek at the built element without taking ownership + XmlElement * BuiltElement(); + +private: + XmlElement * pelCurrent_; + std::unique_ptr<XmlElement> pelRoot_; + std::unique_ptr<std::vector<XmlElement*> > pvParents_; +}; + +} + +#endif
diff --git a/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc b/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc new file mode 100644 index 0000000..0a6f606 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlbuilder_unittest.cc
@@ -0,0 +1,177 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::XmlBuilder; +using buzz::XmlElement; +using buzz::XmlParser; + +TEST(XmlBuilderTest, TestTrivial) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing/>"); + EXPECT_EQ("<testing/>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestAttributes1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='b'/>"); + EXPECT_EQ("<testing a=\"b\"/>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestAttributes2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing e='' long='some text'/>"); + EXPECT_EQ("<testing e=\"\" long=\"some text\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestNesting1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<top><first/><second><third></third></second></top>"); + EXPECT_EQ("<top><first/><second><third/></second></top>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestNesting2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<top><fifth><deeper><and><deeper/></and><sibling><leaf/>" + "</sibling></deeper></fifth><first/><second><third></third>" + "</second></top>"); + EXPECT_EQ("<top><fifth><deeper><and><deeper/></and><sibling><leaf/>" + "</sibling></deeper></fifth><first/><second><third/>" + "</second></top>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestQuoting1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='>'/>"); + EXPECT_EQ("<testing a=\">\"/>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestQuoting2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='<>&"'/>"); + EXPECT_EQ("<testing a=\"<>&"\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestQuoting3) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='so "important"'/>"); + EXPECT_EQ("<testing a=\"so "important"\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestQuoting4) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='"important", yes'/>"); + EXPECT_EQ("<testing a=\""important", yes\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestQuoting5) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<testing a='<what is "important">'/>"); + EXPECT_EQ("<testing a=\"<what is "important">\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestText1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing>></testing>"); + EXPECT_EQ("<testing>></testing>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestText2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing><>&"</testing>"); + EXPECT_EQ("<testing><>&\"</testing>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestText3) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing>so <important></testing>"); + EXPECT_EQ("<testing>so <important></testing>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestText4) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing><important>, yes</testing>"); + EXPECT_EQ("<testing><important>, yes</testing>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestText5) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<testing>importance &<important>&</testing>"); + EXPECT_EQ("<testing>importance &<important>&</testing>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestNamespace1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing xmlns='foo'/>"); + EXPECT_EQ("<testing xmlns=\"foo\"/>", builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestNamespace2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing xmlns:a='foo' a:b='c'/>"); + EXPECT_EQ("<testing xmlns:a=\"foo\" a:b=\"c\"/>", + builder.BuiltElement()->Str()); +} + +TEST(XmlBuilderTest, TestNamespace3) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing xmlns:a=''/>"); + EXPECT_TRUE(NULL == builder.BuiltElement()); +} + +TEST(XmlBuilderTest, TestNamespace4) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a:b='c'/>"); + EXPECT_TRUE(NULL == builder.BuiltElement()); +} + +TEST(XmlBuilderTest, TestAttrCollision1) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, "<testing a='first' a='second'/>"); + EXPECT_TRUE(NULL == builder.BuiltElement()); +} + +TEST(XmlBuilderTest, TestAttrCollision2) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<testing xmlns:a='foo' xmlns:b='foo' a:x='c' b:x='d'/>"); + EXPECT_TRUE(NULL == builder.BuiltElement()); +} + +TEST(XmlBuilderTest, TestAttrCollision3) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, + "<testing xmlns:a='foo'><nested xmlns:b='foo' a:x='c' b:x='d'/>" + "</testing>"); + EXPECT_TRUE(NULL == builder.BuiltElement()); +} +
diff --git a/third_party/libjingle_xmpp/xmllite/xmlconstants.cc b/third_party/libjingle_xmpp/xmllite/xmlconstants.cc new file mode 100644 index 0000000..c2e471c --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlconstants.cc
@@ -0,0 +1,25 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" + +namespace buzz { + +const char STR_EMPTY[] = ""; +const char NS_XML[] = "http://www.w3.org/XML/1998/namespace"; +const char NS_XMLNS[] = "http://www.w3.org/2000/xmlns/"; +const char STR_XMLNS[] = "xmlns"; +const char STR_XML[] = "xml"; +const char STR_VERSION[] = "version"; +const char STR_ENCODING[] = "encoding"; + +const StaticQName QN_XMLNS = { STR_EMPTY, STR_XMLNS }; + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/xmlconstants.h b/third_party/libjingle_xmpp/xmllite/xmlconstants.h new file mode 100644 index 0000000..1499a084 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlconstants.h
@@ -0,0 +1,30 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLCONSTANTS_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_XMLCONSTANTS_H_ + +#include "third_party/libjingle_xmpp/xmllite/qname.h" + +namespace buzz { + +extern const char STR_EMPTY[]; +extern const char NS_XML[]; +extern const char NS_XMLNS[]; +extern const char STR_XMLNS[]; +extern const char STR_XML[]; +extern const char STR_VERSION[]; +extern const char STR_ENCODING[]; + +extern const StaticQName QN_XMLNS; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMLLITE_XMLCONSTANTS_H_
diff --git a/third_party/libjingle_xmpp/xmllite/xmlelement.cc b/third_party/libjingle_xmpp/xmllite/xmlelement.cc new file mode 100644 index 0000000..0ef5841 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlelement.cc
@@ -0,0 +1,496 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" + +#include <ostream> +#include <sstream> +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" +#include "third_party/webrtc/base/common.h" + +namespace buzz { + +XmlChild::~XmlChild() { +} + +bool XmlText::IsTextImpl() const { + return true; +} + +XmlElement* XmlText::AsElementImpl() const { + return NULL; +} + +XmlText* XmlText::AsTextImpl() const { + return const_cast<XmlText *>(this); +} + +void XmlText::SetText(const std::string& text) { + text_ = text; +} + +void XmlText::AddParsedText(const char* buf, int len) { + text_.append(buf, len); +} + +void XmlText::AddText(const std::string& text) { + text_ += text; +} + +XmlText::~XmlText() { +} + +XmlElement::XmlElement(const QName& name) : + name_(name), + first_attr_(NULL), + last_attr_(NULL), + first_child_(NULL), + last_child_(NULL), + cdata_(false) { +} + +XmlElement::XmlElement(const XmlElement& elt) : + XmlChild(), + name_(elt.name_), + first_attr_(NULL), + last_attr_(NULL), + first_child_(NULL), + last_child_(NULL), + cdata_(false) { + + // copy attributes + XmlAttr* attr; + XmlAttr ** plast_attr = &first_attr_; + XmlAttr* newAttr = NULL; + for (attr = elt.first_attr_; attr; attr = attr->NextAttr()) { + newAttr = new XmlAttr(*attr); + *plast_attr = newAttr; + plast_attr = &(newAttr->next_attr_); + } + last_attr_ = newAttr; + + // copy children + XmlChild* pChild; + XmlChild ** ppLast = &first_child_; + XmlChild* newChild = NULL; + + for (pChild = elt.first_child_; pChild; pChild = pChild->NextChild()) { + if (pChild->IsText()) { + newChild = new XmlText(*(pChild->AsText())); + } else { + newChild = new XmlElement(*(pChild->AsElement())); + } + *ppLast = newChild; + ppLast = &(newChild->next_child_); + } + last_child_ = newChild; + + cdata_ = elt.cdata_; +} + +XmlElement::XmlElement(const QName& name, bool useDefaultNs) : + name_(name), + first_attr_(useDefaultNs ? new XmlAttr(QN_XMLNS, name.Namespace()) : NULL), + last_attr_(first_attr_), + first_child_(NULL), + last_child_(NULL), + cdata_(false) { +} + +bool XmlElement::IsTextImpl() const { + return false; +} + +XmlElement* XmlElement::AsElementImpl() const { + return const_cast<XmlElement *>(this); +} + +XmlText* XmlElement::AsTextImpl() const { + return NULL; +} + +const std::string XmlElement::BodyText() const { + if (first_child_ && first_child_->IsText() && last_child_ == first_child_) { + return first_child_->AsText()->Text(); + } + + return std::string(); +} + +void XmlElement::SetBodyText(const std::string& text) { + if (text.empty()) { + ClearChildren(); + } else if (first_child_ == NULL) { + AddText(text); + } else if (first_child_->IsText() && last_child_ == first_child_) { + first_child_->AsText()->SetText(text); + } else { + ClearChildren(); + AddText(text); + } +} + +const QName XmlElement::FirstElementName() const { + const XmlElement* element = FirstElement(); + if (element == NULL) + return QName(); + return element->Name(); +} + +XmlAttr* XmlElement::FirstAttr() { + return first_attr_; +} + +const std::string XmlElement::Attr(const StaticQName& name) const { + XmlAttr* attr; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + return attr->value_; + } + return std::string(); +} + +const std::string XmlElement::Attr(const QName& name) const { + XmlAttr* attr; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + return attr->value_; + } + return std::string(); +} + +bool XmlElement::HasAttr(const StaticQName& name) const { + XmlAttr* attr; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + return true; + } + return false; +} + +bool XmlElement::HasAttr(const QName& name) const { + XmlAttr* attr; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + return true; + } + return false; +} + +void XmlElement::SetAttr(const QName& name, const std::string& value) { + XmlAttr* attr; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + break; + } + if (!attr) { + attr = new XmlAttr(name, value); + if (last_attr_) + last_attr_->next_attr_ = attr; + else + first_attr_ = attr; + last_attr_ = attr; + return; + } + attr->value_ = value; +} + +void XmlElement::ClearAttr(const QName& name) { + XmlAttr* attr; + XmlAttr* last_attr = NULL; + for (attr = first_attr_; attr; attr = attr->next_attr_) { + if (attr->name_ == name) + break; + last_attr = attr; + } + if (!attr) + return; + if (!last_attr) + first_attr_ = attr->next_attr_; + else + last_attr->next_attr_ = attr->next_attr_; + if (last_attr_ == attr) + last_attr_ = last_attr; + delete attr; +} + +XmlChild* XmlElement::FirstChild() { + return first_child_; +} + +XmlElement* XmlElement::FirstElement() { + XmlChild* pChild; + for (pChild = first_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText()) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement* XmlElement::NextElement() { + XmlChild* pChild; + for (pChild = next_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText()) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement* XmlElement::FirstWithNamespace(const std::string& ns) { + XmlChild* pChild; + for (pChild = first_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement * +XmlElement::NextWithNamespace(const std::string& ns) { + XmlChild* pChild; + for (pChild = next_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name().Namespace() == ns) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement * +XmlElement::FirstNamed(const QName& name) { + XmlChild* pChild; + for (pChild = first_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name() == name) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement * +XmlElement::FirstNamed(const StaticQName& name) { + XmlChild* pChild; + for (pChild = first_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name() == name) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement * +XmlElement::NextNamed(const QName& name) { + XmlChild* pChild; + for (pChild = next_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name() == name) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement * +XmlElement::NextNamed(const StaticQName& name) { + XmlChild* pChild; + for (pChild = next_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name() == name) + return pChild->AsElement(); + } + return NULL; +} + +XmlElement* XmlElement::FindOrAddNamedChild(const QName& name) { + XmlElement* child = FirstNamed(name); + if (!child) { + child = new XmlElement(name); + AddElement(child); + } + + return child; +} + +const std::string XmlElement::TextNamed(const QName& name) const { + XmlChild* pChild; + for (pChild = first_child_; pChild; pChild = pChild->next_child_) { + if (!pChild->IsText() && pChild->AsElement()->Name() == name) + return pChild->AsElement()->BodyText(); + } + return std::string(); +} + +void XmlElement::InsertChildAfter(XmlChild* predecessor, XmlChild* next) { + if (predecessor == NULL) { + next->next_child_ = first_child_; + first_child_ = next; + } + else { + next->next_child_ = predecessor->next_child_; + predecessor->next_child_ = next; + } +} + +void XmlElement::RemoveChildAfter(XmlChild* predecessor) { + XmlChild* next; + + if (predecessor == NULL) { + next = first_child_; + first_child_ = next->next_child_; + } + else { + next = predecessor->next_child_; + predecessor->next_child_ = next->next_child_; + } + + if (last_child_ == next) + last_child_ = predecessor; + + delete next; +} + +void XmlElement::AddAttr(const QName& name, const std::string& value) { + ASSERT(!HasAttr(name)); + + XmlAttr ** pprev = last_attr_ ? &(last_attr_->next_attr_) : &first_attr_; + last_attr_ = (*pprev = new XmlAttr(name, value)); +} + +void XmlElement::AddAttr(const QName& name, const std::string& value, + int depth) { + XmlElement* element = this; + while (depth--) { + element = element->last_child_->AsElement(); + } + element->AddAttr(name, value); +} + +void XmlElement::AddParsedText(const char* cstr, int len) { + if (len == 0) + return; + + if (last_child_ && last_child_->IsText()) { + last_child_->AsText()->AddParsedText(cstr, len); + return; + } + XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_; + last_child_ = *pprev = new XmlText(cstr, len); +} + +void XmlElement::AddCDATAText(const char* buf, int len) { + cdata_ = true; + AddParsedText(buf, len); +} + +void XmlElement::AddText(const std::string& text) { + if (text == STR_EMPTY) + return; + + if (last_child_ && last_child_->IsText()) { + last_child_->AsText()->AddText(text); + return; + } + XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_; + last_child_ = *pprev = new XmlText(text); +} + +void XmlElement::AddText(const std::string& text, int depth) { + // note: the first syntax is ambigious for msvc 6 + // XmlElement* pel(this); + XmlElement* element = this; + while (depth--) { + element = element->last_child_->AsElement(); + } + element->AddText(text); +} + +void XmlElement::AddElement(XmlElement *child) { + if (child == NULL) + return; + + XmlChild ** pprev = last_child_ ? &(last_child_->next_child_) : &first_child_; + *pprev = child; + last_child_ = child; + child->next_child_ = NULL; +} + +void XmlElement::AddElement(XmlElement *child, int depth) { + XmlElement* element = this; + while (depth--) { + element = element->last_child_->AsElement(); + } + element->AddElement(child); +} + +void XmlElement::ClearNamedChildren(const QName& name) { + XmlChild* prev_child = NULL; + XmlChild* next_child; + XmlChild* child; + for (child = FirstChild(); child; child = next_child) { + next_child = child->NextChild(); + if (!child->IsText() && child->AsElement()->Name() == name) + { + RemoveChildAfter(prev_child); + continue; + } + prev_child = child; + } +} + +void XmlElement::ClearAttributes() { + XmlAttr* attr; + for (attr = first_attr_; attr; ) { + XmlAttr* to_delete = attr; + attr = attr->next_attr_; + delete to_delete; + } + first_attr_ = last_attr_ = NULL; +} + +void XmlElement::ClearChildren() { + XmlChild* pchild; + for (pchild = first_child_; pchild; ) { + XmlChild* to_delete = pchild; + pchild = pchild->next_child_; + delete to_delete; + } + first_child_ = last_child_ = NULL; +} + +std::string XmlElement::Str() const { + std::stringstream ss; + XmlPrinter::PrintXml(&ss, this); + return ss.str(); +} + +XmlElement* XmlElement::ForStr(const std::string& str) { + XmlBuilder builder; + XmlParser::ParseXml(&builder, str); + return builder.CreateElement(); +} + +XmlElement::~XmlElement() { + XmlAttr* attr; + for (attr = first_attr_; attr; ) { + XmlAttr* to_delete = attr; + attr = attr->next_attr_; + delete to_delete; + } + + XmlChild* pchild; + for (pchild = first_child_; pchild; ) { + XmlChild* to_delete = pchild; + pchild = pchild->next_child_; + delete to_delete; + } +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/xmlelement.h b/third_party/libjingle_xmpp/xmllite/xmlelement.h new file mode 100644 index 0000000..bec6f99 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlelement.h
@@ -0,0 +1,233 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_ + +#include <iosfwd> +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/qname.h" + +namespace buzz { + +class XmlChild; +class XmlText; +class XmlElement; +class XmlAttr; + +class XmlChild { + public: + XmlChild* NextChild() { return next_child_; } + const XmlChild* NextChild() const { return next_child_; } + + bool IsText() const { return IsTextImpl(); } + + XmlElement* AsElement() { return AsElementImpl(); } + const XmlElement* AsElement() const { return AsElementImpl(); } + + XmlText* AsText() { return AsTextImpl(); } + const XmlText* AsText() const { return AsTextImpl(); } + + + protected: + XmlChild() : + next_child_(NULL) { + } + + virtual bool IsTextImpl() const = 0; + virtual XmlElement* AsElementImpl() const = 0; + virtual XmlText* AsTextImpl() const = 0; + + + virtual ~XmlChild(); + + private: + friend class XmlElement; + + XmlChild(const XmlChild& noimpl); + + XmlChild* next_child_; +}; + +class XmlText : public XmlChild { + public: + explicit XmlText(const std::string& text) : + XmlChild(), + text_(text) { + } + explicit XmlText(const XmlText& t) : + XmlChild(), + text_(t.text_) { + } + explicit XmlText(const char* cstr, size_t len) : + XmlChild(), + text_(cstr, len) { + } + virtual ~XmlText(); + + const std::string& Text() const { return text_; } + void SetText(const std::string& text); + void AddParsedText(const char* buf, int len); + void AddText(const std::string& text); + + protected: + virtual bool IsTextImpl() const; + virtual XmlElement* AsElementImpl() const; + virtual XmlText* AsTextImpl() const; + + private: + std::string text_; +}; + +class XmlAttr { + public: + XmlAttr* NextAttr() const { return next_attr_; } + const QName& Name() const { return name_; } + const std::string& Value() const { return value_; } + + private: + friend class XmlElement; + + explicit XmlAttr(const QName& name, const std::string& value) : + next_attr_(NULL), + name_(name), + value_(value) { + } + explicit XmlAttr(const XmlAttr& att) : + next_attr_(NULL), + name_(att.name_), + value_(att.value_) { + } + + XmlAttr* next_attr_; + QName name_; + std::string value_; +}; + +class XmlElement : public XmlChild { + public: + explicit XmlElement(const QName& name); + explicit XmlElement(const QName& name, bool useDefaultNs); + explicit XmlElement(const XmlElement& elt); + + virtual ~XmlElement(); + + const QName& Name() const { return name_; } + void SetName(const QName& name) { name_ = name; } + + const std::string BodyText() const; + void SetBodyText(const std::string& text); + + const QName FirstElementName() const; + + XmlAttr* FirstAttr(); + const XmlAttr* FirstAttr() const + { return const_cast<XmlElement *>(this)->FirstAttr(); } + + // Attr will return an empty string if the attribute isn't there: + // use HasAttr to test presence of an attribute. + const std::string Attr(const StaticQName& name) const; + const std::string Attr(const QName& name) const; + bool HasAttr(const StaticQName& name) const; + bool HasAttr(const QName& name) const; + void SetAttr(const QName& name, const std::string& value); + void ClearAttr(const QName& name); + + XmlChild* FirstChild(); + const XmlChild* FirstChild() const { + return const_cast<XmlElement *>(this)->FirstChild(); + } + + XmlElement* FirstElement(); + const XmlElement* FirstElement() const { + return const_cast<XmlElement *>(this)->FirstElement(); + } + + XmlElement* NextElement(); + const XmlElement* NextElement() const { + return const_cast<XmlElement *>(this)->NextElement(); + } + + XmlElement* FirstWithNamespace(const std::string& ns); + const XmlElement* FirstWithNamespace(const std::string& ns) const { + return const_cast<XmlElement *>(this)->FirstWithNamespace(ns); + } + + XmlElement* NextWithNamespace(const std::string& ns); + const XmlElement* NextWithNamespace(const std::string& ns) const { + return const_cast<XmlElement *>(this)->NextWithNamespace(ns); + } + + XmlElement* FirstNamed(const StaticQName& name); + const XmlElement* FirstNamed(const StaticQName& name) const { + return const_cast<XmlElement *>(this)->FirstNamed(name); + } + + XmlElement* FirstNamed(const QName& name); + const XmlElement* FirstNamed(const QName& name) const { + return const_cast<XmlElement *>(this)->FirstNamed(name); + } + + XmlElement* NextNamed(const StaticQName& name); + const XmlElement* NextNamed(const StaticQName& name) const { + return const_cast<XmlElement *>(this)->NextNamed(name); + } + + XmlElement* NextNamed(const QName& name); + const XmlElement* NextNamed(const QName& name) const { + return const_cast<XmlElement *>(this)->NextNamed(name); + } + + // Finds the first element named 'name'. If that element can't be found then + // adds one and returns it. + XmlElement* FindOrAddNamedChild(const QName& name); + + const std::string TextNamed(const QName& name) const; + + void InsertChildAfter(XmlChild* predecessor, XmlChild* new_child); + void RemoveChildAfter(XmlChild* predecessor); + + void AddParsedText(const char* buf, int len); + // Note: CDATA is not supported by XMPP, therefore using this function will + // generate non-XMPP compatible XML. + void AddCDATAText(const char* buf, int len); + void AddText(const std::string& text); + void AddText(const std::string& text, int depth); + void AddElement(XmlElement* child); + void AddElement(XmlElement* child, int depth); + void AddAttr(const QName& name, const std::string& value); + void AddAttr(const QName& name, const std::string& value, int depth); + void ClearNamedChildren(const QName& name); + void ClearAttributes(); + void ClearChildren(); + + static XmlElement* ForStr(const std::string& str); + std::string Str() const; + + bool IsCDATA() const { return cdata_; } + + protected: + virtual bool IsTextImpl() const; + virtual XmlElement* AsElementImpl() const; + virtual XmlText* AsTextImpl() const; + + private: + QName name_; + XmlAttr* first_attr_; + XmlAttr* last_attr_; + XmlChild* first_child_; + XmlChild* last_child_; + bool cdata_; +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMLLITE_XMLELEMENT_H_
diff --git a/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc b/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc new file mode 100644 index 0000000..f54ae95 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlelement_unittest.cc
@@ -0,0 +1,258 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" +#include "third_party/webrtc/base/thread.h" + +using buzz::QName; +using buzz::XmlAttr; +using buzz::XmlChild; +using buzz::XmlElement; + +std::ostream& operator<<(std::ostream& os, const QName& name) { + os << name.Namespace() << ":" << name.LocalPart(); + return os; +} + +TEST(XmlElementTest, TestConstructors) { + XmlElement elt(QName("google:test", "first")); + EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", elt.Str()); + + XmlElement elt2(QName("google:test", "first"), true); + EXPECT_EQ("<first xmlns=\"google:test\"/>", elt2.Str()); +} + +TEST(XmlElementTest, TestAdd) { + XmlElement elt(QName("google:test", "root"), true); + elt.AddElement(new XmlElement(QName("google:test", "first"))); + elt.AddElement(new XmlElement(QName("google:test", "nested")), 1); + elt.AddText("nested-value", 2); + elt.AddText("between-", 1); + elt.AddText("value", 1); + elt.AddElement(new XmlElement(QName("google:test", "nested2")), 1); + elt.AddElement(new XmlElement(QName("google:test", "second"))); + elt.AddText("init-value", 1); + elt.AddElement(new XmlElement(QName("google:test", "nested3")), 1); + elt.AddText("trailing-value", 1); + + // make sure it looks ok overall + EXPECT_EQ("<root xmlns=\"google:test\">" + "<first><nested>nested-value</nested>between-value<nested2/></first>" + "<second>init-value<nested3/>trailing-value</second></root>", + elt.Str()); + + // make sure text was concatenated + XmlChild * pchild = + elt.FirstChild()->AsElement()->FirstChild()->NextChild(); + EXPECT_TRUE(pchild->IsText()); + EXPECT_EQ("between-value", pchild->AsText()->Text()); +} + +TEST(XmlElementTest, TestAttrs) { + XmlElement elt(QName("", "root")); + elt.SetAttr(QName("", "a"), "avalue"); + EXPECT_EQ("<root a=\"avalue\"/>", elt.Str()); + + elt.SetAttr(QName("", "b"), "bvalue"); + EXPECT_EQ("<root a=\"avalue\" b=\"bvalue\"/>", elt.Str()); + + elt.SetAttr(QName("", "a"), "avalue2"); + EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue\"/>", elt.Str()); + + elt.SetAttr(QName("", "b"), "bvalue2"); + EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\"/>", elt.Str()); + + elt.SetAttr(QName("", "c"), "cvalue"); + EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\"/>", elt.Str()); + + XmlAttr * patt = elt.FirstAttr(); + EXPECT_EQ(QName("", "a"), patt->Name()); + EXPECT_EQ("avalue2", patt->Value()); + + patt = patt->NextAttr(); + EXPECT_EQ(QName("", "b"), patt->Name()); + EXPECT_EQ("bvalue2", patt->Value()); + + patt = patt->NextAttr(); + EXPECT_EQ(QName("", "c"), patt->Name()); + EXPECT_EQ("cvalue", patt->Value()); + + patt = patt->NextAttr(); + EXPECT_TRUE(NULL == patt); + + EXPECT_TRUE(elt.HasAttr(QName("", "a"))); + EXPECT_TRUE(elt.HasAttr(QName("", "b"))); + EXPECT_TRUE(elt.HasAttr(QName("", "c"))); + EXPECT_FALSE(elt.HasAttr(QName("", "d"))); + + elt.SetAttr(QName("", "d"), "dvalue"); + EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>", + elt.Str()); + EXPECT_TRUE(elt.HasAttr(QName("", "d"))); + + elt.ClearAttr(QName("", "z")); // not found, no effect + EXPECT_EQ("<root a=\"avalue2\" b=\"bvalue2\" c=\"cvalue\" d=\"dvalue\"/>", + elt.Str()); + + elt.ClearAttr(QName("", "b")); + EXPECT_EQ("<root a=\"avalue2\" c=\"cvalue\" d=\"dvalue\"/>", elt.Str()); + + elt.ClearAttr(QName("", "a")); + EXPECT_EQ("<root c=\"cvalue\" d=\"dvalue\"/>", elt.Str()); + + elt.ClearAttr(QName("", "d")); + EXPECT_EQ("<root c=\"cvalue\"/>", elt.Str()); + + elt.ClearAttr(QName("", "c")); + EXPECT_EQ("<root/>", elt.Str()); +} + +TEST(XmlElementTest, TestBodyText) { + XmlElement elt(QName("", "root")); + EXPECT_EQ("", elt.BodyText()); + + elt.AddText("body value text"); + + EXPECT_EQ("body value text", elt.BodyText()); + + elt.ClearChildren(); + elt.AddText("more value "); + elt.AddText("text"); + + EXPECT_EQ("more value text", elt.BodyText()); + + elt.ClearChildren(); + elt.AddText("decoy"); + elt.AddElement(new XmlElement(QName("", "dummy"))); + EXPECT_EQ("", elt.BodyText()); + + elt.SetBodyText("replacement"); + EXPECT_EQ("replacement", elt.BodyText()); + + elt.SetBodyText(""); + EXPECT_TRUE(NULL == elt.FirstChild()); + + elt.SetBodyText("goodbye"); + EXPECT_EQ("goodbye", elt.FirstChild()->AsText()->Text()); + EXPECT_EQ("goodbye", elt.BodyText()); +} + +TEST(XmlElementTest, TestCopyConstructor) { + XmlElement * element = XmlElement::ForStr( + "<root xmlns='test-foo'>This is a <em a='avalue' b='bvalue'>" + "little <b>little</b></em> test</root>"); + + XmlElement * pelCopy = new XmlElement(*element); + EXPECT_EQ("<root xmlns=\"test-foo\">This is a <em a=\"avalue\" b=\"bvalue\">" + "little <b>little</b></em> test</root>", pelCopy->Str()); + delete pelCopy; + + pelCopy = new XmlElement(*(element->FirstChild()->NextChild()->AsElement())); + EXPECT_EQ("<foo:em a=\"avalue\" b=\"bvalue\" xmlns:foo=\"test-foo\">" + "little <foo:b>little</foo:b></foo:em>", pelCopy->Str()); + + XmlAttr * patt = pelCopy->FirstAttr(); + EXPECT_EQ(QName("", "a"), patt->Name()); + EXPECT_EQ("avalue", patt->Value()); + + patt = patt->NextAttr(); + EXPECT_EQ(QName("", "b"), patt->Name()); + EXPECT_EQ("bvalue", patt->Value()); + + patt = patt->NextAttr(); + EXPECT_TRUE(NULL == patt); + delete pelCopy; + delete element; +} + +TEST(XmlElementTest, TestNameSearch) { + XmlElement * element = XmlElement::ForStr( + "<root xmlns='test-foo'>" + "<firstname>George</firstname>" + "<middlename>X.</middlename>" + "some text" + "<lastname>Harrison</lastname>" + "<firstname>John</firstname>" + "<middlename>Y.</middlename>" + "<lastname>Lennon</lastname>" + "</root>"); + EXPECT_TRUE(NULL == + element->FirstNamed(QName("", "firstname"))); + EXPECT_EQ(element->FirstChild(), + element->FirstNamed(QName("test-foo", "firstname"))); + EXPECT_EQ(element->FirstChild()->NextChild(), + element->FirstNamed(QName("test-foo", "middlename"))); + EXPECT_EQ(element->FirstElement()->NextElement(), + element->FirstNamed(QName("test-foo", "middlename"))); + EXPECT_EQ("Harrison", + element->TextNamed(QName("test-foo", "lastname"))); + EXPECT_EQ(element->FirstElement()->NextElement()->NextElement(), + element->FirstNamed(QName("test-foo", "lastname"))); + EXPECT_EQ("John", element->FirstNamed(QName("test-foo", "firstname"))-> + NextNamed(QName("test-foo", "firstname"))->BodyText()); + EXPECT_EQ("Y.", element->FirstNamed(QName("test-foo", "middlename"))-> + NextNamed(QName("test-foo", "middlename"))->BodyText()); + EXPECT_EQ("Lennon", element->FirstNamed(QName("test-foo", "lastname"))-> + NextNamed(QName("test-foo", "lastname"))->BodyText()); + EXPECT_TRUE(NULL == element->FirstNamed(QName("test-foo", "firstname"))-> + NextNamed(QName("test-foo", "firstname"))-> + NextNamed(QName("test-foo", "firstname"))); + + delete element; +} + +class XmlElementCreatorThread : public rtc::Thread { + public: + XmlElementCreatorThread(int count, buzz::QName qname) : + count_(count), qname_(qname) {} + + virtual ~XmlElementCreatorThread() { + Stop(); + } + + virtual void Run() { + std::vector<buzz::XmlElement*> elems; + for (int i = 0; i < count_; i++) { + elems.push_back(new XmlElement(qname_)); + } + for (int i = 0; i < count_; i++) { + delete elems[i]; + } + } + + private: + int count_; + buzz::QName qname_; +}; + +// If XmlElement creation and destruction isn't thread safe, +// this test should crash. +TEST(XmlElementTest, TestMultithread) { + int thread_count = 2; // Was 100, but that's too slow. + int elem_count = 100; // Was 100000, but that's too slow. + buzz::QName qname("foo", "bar"); + + std::vector<rtc::Thread*> threads; + for (int i = 0; i < thread_count; i++) { + threads.push_back( + new XmlElementCreatorThread(elem_count, qname)); + threads[i]->Start(); + } + + for (int i = 0; i < thread_count; i++) { + threads[i]->Stop(); + delete threads[i]; + } +}
diff --git a/third_party/libjingle_xmpp/xmllite/xmlnsstack.cc b/third_party/libjingle_xmpp/xmllite/xmlnsstack.cc new file mode 100644 index 0000000..597dc9c0 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlnsstack.cc
@@ -0,0 +1,178 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" + +#include <sstream> +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" + +namespace buzz { + +XmlnsStack::XmlnsStack() : + pxmlnsStack_(new std::vector<std::string>), + pxmlnsDepthStack_(new std::vector<size_t>) { +} + +XmlnsStack::~XmlnsStack() {} + +void XmlnsStack::PushFrame() { + pxmlnsDepthStack_->push_back(pxmlnsStack_->size()); +} + +void XmlnsStack::PopFrame() { + size_t prev_size = pxmlnsDepthStack_->back(); + pxmlnsDepthStack_->pop_back(); + if (prev_size < pxmlnsStack_->size()) { + pxmlnsStack_->erase(pxmlnsStack_->begin() + prev_size, + pxmlnsStack_->end()); + } +} + +std::pair<std::string, bool> XmlnsStack::NsForPrefix( + const std::string& prefix) { + if (prefix.length() >= 3 && + (prefix[0] == 'x' || prefix[0] == 'X') && + (prefix[1] == 'm' || prefix[1] == 'M') && + (prefix[2] == 'l' || prefix[2] == 'L')) { + if (prefix == "xml") + return std::make_pair(NS_XML, true); + if (prefix == "xmlns") + return std::make_pair(NS_XMLNS, true); + // Other names with xml prefix are illegal. + return std::make_pair(STR_EMPTY, false); + } + + std::vector<std::string>::iterator pos; + for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) { + pos -= 2; + if (*pos == prefix) + return std::make_pair(*(pos + 1), true); + } + + if (prefix == STR_EMPTY) + return std::make_pair(STR_EMPTY, true); // default namespace + + return std::make_pair(STR_EMPTY, false); // none found +} + +bool XmlnsStack::PrefixMatchesNs(const std::string& prefix, + const std::string& ns) { + const std::pair<std::string, bool> match = NsForPrefix(prefix); + return match.second && (match.first == ns); +} + +std::pair<std::string, bool> XmlnsStack::PrefixForNs(const std::string& ns, + bool isattr) { + if (ns == NS_XML) + return std::make_pair(std::string("xml"), true); + if (ns == NS_XMLNS) + return std::make_pair(std::string("xmlns"), true); + if (isattr ? ns == STR_EMPTY : PrefixMatchesNs(STR_EMPTY, ns)) + return std::make_pair(STR_EMPTY, true); + + std::vector<std::string>::iterator pos; + for (pos = pxmlnsStack_->end(); pos > pxmlnsStack_->begin(); ) { + pos -= 2; + if (*(pos + 1) == ns && + (!isattr || !pos->empty()) && PrefixMatchesNs(*pos, ns)) + return std::make_pair(*pos, true); + } + + return std::make_pair(STR_EMPTY, false); // none found +} + +std::string XmlnsStack::FormatQName(const QName& name, bool isAttr) { + std::string prefix(PrefixForNs(name.Namespace(), isAttr).first); + if (prefix == STR_EMPTY) + return name.LocalPart(); + else + return prefix + ':' + name.LocalPart(); +} + +void XmlnsStack::AddXmlns(const std::string & prefix, const std::string & ns) { + pxmlnsStack_->push_back(prefix); + pxmlnsStack_->push_back(ns); +} + +void XmlnsStack::RemoveXmlns() { + pxmlnsStack_->pop_back(); + pxmlnsStack_->pop_back(); +} + +static bool IsAsciiLetter(char ch) { + return ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z')); +} + +static std::string AsciiLower(const std::string & s) { + std::string result(s); + size_t i; + for (i = 0; i < result.length(); i++) { + if (result[i] >= 'A' && result[i] <= 'Z') + result[i] += 'a' - 'A'; + } + return result; +} + +static std::string SuggestPrefix(const std::string & ns) { + size_t len = ns.length(); + size_t i = ns.find_last_of('.'); + if (i != std::string::npos && len - i <= 4 + 1) + len = i; // chop off ".html" or ".xsd" or ".?{0,4}" + size_t last = len; + while (last > 0) { + last -= 1; + if (IsAsciiLetter(ns[last])) { + size_t first = last; + last += 1; + while (first > 0) { + if (!IsAsciiLetter(ns[first - 1])) + break; + first -= 1; + } + if (last - first > 4) + last = first + 3; + std::string candidate(AsciiLower(ns.substr(first, last - first))); + if (candidate.find("xml") != 0) + return candidate; + break; + } + } + return "ns"; +} + +std::pair<std::string, bool> XmlnsStack::AddNewPrefix(const std::string& ns, + bool isAttr) { + if (PrefixForNs(ns, isAttr).second) + return std::make_pair(STR_EMPTY, false); + + std::string base(SuggestPrefix(ns)); + std::string result(base); + int i = 2; + while (NsForPrefix(result).second) { + std::stringstream ss; + ss << base; + ss << (i++); + ss >> result; + } + AddXmlns(result, ns); + return std::make_pair(result, true); +} + +void XmlnsStack::Reset() { + pxmlnsStack_->clear(); + pxmlnsDepthStack_->clear(); +} + +}
diff --git a/third_party/libjingle_xmpp/xmllite/xmlnsstack.h b/third_party/libjingle_xmpp/xmllite/xmlnsstack.h new file mode 100644 index 0000000..c6200a9 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlnsstack.h
@@ -0,0 +1,45 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLNSSTACK_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_XMLNSSTACK_H_ + +#include <memory> +#include <string> +#include <vector> +#include "third_party/libjingle_xmpp/xmllite/qname.h" + +namespace buzz { + +class XmlnsStack { +public: + XmlnsStack(); + ~XmlnsStack(); + + void AddXmlns(const std::string& prefix, const std::string& ns); + void RemoveXmlns(); + void PushFrame(); + void PopFrame(); + void Reset(); + + std::pair<std::string, bool> NsForPrefix(const std::string& prefix); + bool PrefixMatchesNs(const std::string & prefix, const std::string & ns); + std::pair<std::string, bool> PrefixForNs(const std::string& ns, bool isAttr); + std::pair<std::string, bool> AddNewPrefix(const std::string& ns, bool isAttr); + std::string FormatQName(const QName & name, bool isAttr); + +private: + + std::unique_ptr<std::vector<std::string> > pxmlnsStack_; + std::unique_ptr<std::vector<size_t> > pxmlnsDepthStack_; +}; +} + +#endif // WEBRTC_LIBJINGLE_XMLLITE_XMLNSSTACK_H_
diff --git a/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc b/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc new file mode 100644 index 0000000..19372a6 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlnsstack_unittest.cc
@@ -0,0 +1,241 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" + +#include <iostream> +#include <sstream> +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::NS_XML; +using buzz::NS_XMLNS; +using buzz::QName; +using buzz::XmlnsStack; + +TEST(XmlnsStackTest, TestBuiltin) { + XmlnsStack stack; + + EXPECT_EQ(std::string(NS_XML), stack.NsForPrefix("xml").first); + EXPECT_EQ(std::string(NS_XMLNS), stack.NsForPrefix("xmlns").first); + EXPECT_EQ("", stack.NsForPrefix("").first); + + EXPECT_EQ("xml", stack.PrefixForNs(NS_XML, false).first); + EXPECT_EQ("xmlns", stack.PrefixForNs(NS_XMLNS, false).first); + EXPECT_EQ("", stack.PrefixForNs("", false).first); + EXPECT_EQ("", stack.PrefixForNs("", true).first); +} + +TEST(XmlnsStackTest, TestNsForPrefix) { + XmlnsStack stack; + stack.AddXmlns("pre1", "ns1"); + stack.AddXmlns("pre2", "ns2"); + stack.AddXmlns("pre1", "ns3"); + stack.AddXmlns("", "ns4"); + + EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first); + EXPECT_TRUE(stack.NsForPrefix("pre1").second); + EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first); + EXPECT_EQ("ns4", stack.NsForPrefix("").first); + EXPECT_EQ("", stack.NsForPrefix("pre3").first); + EXPECT_FALSE(stack.NsForPrefix("pre3").second); +} + +TEST(XmlnsStackTest, TestPrefixForNs) { + XmlnsStack stack; + stack.AddXmlns("pre1", "ns1"); + stack.AddXmlns("pre2", "ns2"); + stack.AddXmlns("pre1", "ns3"); + stack.AddXmlns("pre3", "ns2"); + stack.AddXmlns("pre4", "ns4"); + stack.AddXmlns("", "ns4"); + + EXPECT_EQ("", stack.PrefixForNs("ns1", false).first); + EXPECT_FALSE(stack.PrefixForNs("ns1", false).second); + EXPECT_EQ("", stack.PrefixForNs("ns1", true).first); + EXPECT_FALSE(stack.PrefixForNs("ns1", true).second); + EXPECT_EQ("pre3", stack.PrefixForNs("ns2", false).first); + EXPECT_TRUE(stack.PrefixForNs("ns2", false).second); + EXPECT_EQ("pre3", stack.PrefixForNs("ns2", true).first); + EXPECT_TRUE(stack.PrefixForNs("ns2", true).second); + EXPECT_EQ("pre1", stack.PrefixForNs("ns3", false).first); + EXPECT_EQ("pre1", stack.PrefixForNs("ns3", true).first); + EXPECT_EQ("", stack.PrefixForNs("ns4", false).first); + EXPECT_TRUE(stack.PrefixForNs("ns4", false).second); + EXPECT_EQ("pre4", stack.PrefixForNs("ns4", true).first); + EXPECT_EQ("", stack.PrefixForNs("ns5", false).first); + EXPECT_FALSE(stack.PrefixForNs("ns5", false).second); + EXPECT_EQ("", stack.PrefixForNs("ns5", true).first); + EXPECT_EQ("", stack.PrefixForNs("", false).first); + EXPECT_EQ("", stack.PrefixForNs("", true).first); + + stack.AddXmlns("", "ns6"); + EXPECT_EQ("", stack.PrefixForNs("ns6", false).first); + EXPECT_TRUE(stack.PrefixForNs("ns6", false).second); + EXPECT_EQ("", stack.PrefixForNs("ns6", true).first); + EXPECT_FALSE(stack.PrefixForNs("ns6", true).second); +} + +TEST(XmlnsStackTest, TestFrames) { + XmlnsStack stack; + stack.PushFrame(); + stack.AddXmlns("pre1", "ns1"); + stack.AddXmlns("pre2", "ns2"); + + stack.PushFrame(); + stack.AddXmlns("pre1", "ns3"); + stack.AddXmlns("pre3", "ns2"); + stack.AddXmlns("pre4", "ns4"); + + stack.PushFrame(); + stack.PushFrame(); + stack.AddXmlns("", "ns4"); + + // basic test + EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first); + EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first); + EXPECT_EQ("", stack.NsForPrefix("pre5").first); + EXPECT_FALSE(stack.NsForPrefix("pre5").second); + EXPECT_EQ("ns4", stack.NsForPrefix("").first); + EXPECT_TRUE(stack.NsForPrefix("").second); + + // pop the default xmlns definition + stack.PopFrame(); + EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first); + EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first); + EXPECT_EQ("", stack.NsForPrefix("pre5").first); + EXPECT_FALSE(stack.NsForPrefix("pre5").second); + EXPECT_EQ("", stack.NsForPrefix("").first); + EXPECT_TRUE(stack.NsForPrefix("").second); + + // pop empty frame (nop) + stack.PopFrame(); + EXPECT_EQ("ns3", stack.NsForPrefix("pre1").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre3").first); + EXPECT_EQ("ns4", stack.NsForPrefix("pre4").first); + EXPECT_EQ("", stack.NsForPrefix("pre5").first); + EXPECT_FALSE(stack.NsForPrefix("pre5").second); + EXPECT_EQ("", stack.NsForPrefix("").first); + EXPECT_TRUE(stack.NsForPrefix("").second); + + // pop frame with three defs + stack.PopFrame(); + EXPECT_EQ("ns1", stack.NsForPrefix("pre1").first); + EXPECT_EQ("ns2", stack.NsForPrefix("pre2").first); + EXPECT_EQ("", stack.NsForPrefix("pre3").first); + EXPECT_FALSE(stack.NsForPrefix("pre3").second); + EXPECT_EQ("", stack.NsForPrefix("pre4").first); + EXPECT_FALSE(stack.NsForPrefix("pre4").second); + EXPECT_EQ("", stack.NsForPrefix("pre5").first); + EXPECT_FALSE(stack.NsForPrefix("pre5").second); + EXPECT_EQ("", stack.NsForPrefix("").first); + EXPECT_TRUE(stack.NsForPrefix("").second); + + // pop frame with last two defs + stack.PopFrame(); + EXPECT_FALSE(stack.NsForPrefix("pre1").second); + EXPECT_FALSE(stack.NsForPrefix("pre2").second); + EXPECT_FALSE(stack.NsForPrefix("pre3").second); + EXPECT_FALSE(stack.NsForPrefix("pre4").second); + EXPECT_FALSE(stack.NsForPrefix("pre5").second); + EXPECT_TRUE(stack.NsForPrefix("").second); + EXPECT_EQ("", stack.NsForPrefix("pre1").first); + EXPECT_EQ("", stack.NsForPrefix("pre2").first); + EXPECT_EQ("", stack.NsForPrefix("pre3").first); + EXPECT_EQ("", stack.NsForPrefix("pre4").first); + EXPECT_EQ("", stack.NsForPrefix("pre5").first); + EXPECT_EQ("", stack.NsForPrefix("").first); +} + +TEST(XmlnsStackTest, TestAddNewPrefix) { + XmlnsStack stack; + + // builtin namespaces cannot be added + EXPECT_FALSE(stack.AddNewPrefix("", true).second); + EXPECT_FALSE(stack.AddNewPrefix("", false).second); + EXPECT_FALSE(stack.AddNewPrefix(NS_XML, true).second); + EXPECT_FALSE(stack.AddNewPrefix(NS_XML, false).second); + EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, true).second); + EXPECT_FALSE(stack.AddNewPrefix(NS_XMLNS, false).second); + + // namespaces already added cannot be added again. + EXPECT_EQ("foo", stack.AddNewPrefix("http://a.b.com/foo.htm", true).first); + EXPECT_EQ("bare", stack.AddNewPrefix("http://a.b.com/bare", false).first); + EXPECT_EQ("z", stack.AddNewPrefix("z", false).first); + EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", true).second); + EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", true).second); + EXPECT_FALSE(stack.AddNewPrefix("z", true).second); + EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/foo.htm", false).second); + EXPECT_FALSE(stack.AddNewPrefix("http://a.b.com/bare", false).second); + EXPECT_FALSE(stack.AddNewPrefix("z", false).second); + + // default namespace usable by non-attributes only + stack.AddXmlns("", "http://my/default"); + EXPECT_FALSE(stack.AddNewPrefix("http://my/default", false).second); + EXPECT_EQ("def", stack.AddNewPrefix("http://my/default", true).first); + + // namespace cannot start with 'xml' + EXPECT_EQ("ns", stack.AddNewPrefix("http://a.b.com/xmltest", true).first); + EXPECT_EQ("ns2", stack.AddNewPrefix("xmlagain", false).first); + + // verify added namespaces are still defined + EXPECT_EQ("http://a.b.com/foo.htm", stack.NsForPrefix("foo").first); + EXPECT_TRUE(stack.NsForPrefix("foo").second); + EXPECT_EQ("http://a.b.com/bare", stack.NsForPrefix("bare").first); + EXPECT_TRUE(stack.NsForPrefix("bare").second); + EXPECT_EQ("z", stack.NsForPrefix("z").first); + EXPECT_TRUE(stack.NsForPrefix("z").second); + EXPECT_EQ("http://my/default", stack.NsForPrefix("").first); + EXPECT_TRUE(stack.NsForPrefix("").second); + EXPECT_EQ("http://my/default", stack.NsForPrefix("def").first); + EXPECT_TRUE(stack.NsForPrefix("def").second); + EXPECT_EQ("http://a.b.com/xmltest", stack.NsForPrefix("ns").first); + EXPECT_TRUE(stack.NsForPrefix("ns").second); + EXPECT_EQ("xmlagain", stack.NsForPrefix("ns2").first); + EXPECT_TRUE(stack.NsForPrefix("ns2").second); +} + +TEST(XmlnsStackTest, TestFormatQName) { + XmlnsStack stack; + stack.AddXmlns("pre1", "ns1"); + stack.AddXmlns("pre2", "ns2"); + stack.AddXmlns("pre1", "ns3"); + stack.AddXmlns("", "ns4"); + + EXPECT_EQ("zip", + stack.FormatQName(QName("ns1", "zip"), false)); // no match + EXPECT_EQ("pre2:abracadabra", + stack.FormatQName(QName("ns2", "abracadabra"), false)); + EXPECT_EQ("pre1:a", + stack.FormatQName(QName("ns3", "a"), false)); + EXPECT_EQ("simple", + stack.FormatQName(QName("ns4", "simple"), false)); + EXPECT_EQ("root", + stack.FormatQName(QName("", "root"), false)); // no match + + EXPECT_EQ("zip", + stack.FormatQName(QName("ns1", "zip"), true)); // no match + EXPECT_EQ("pre2:abracadabra", + stack.FormatQName(QName("ns2", "abracadabra"), true)); + EXPECT_EQ("pre1:a", + stack.FormatQName(QName("ns3", "a"), true)); + EXPECT_EQ("simple", + stack.FormatQName(QName("ns4", "simple"), true)); // no match + EXPECT_EQ("root", + stack.FormatQName(QName("", "root"), true)); +}
diff --git a/third_party/libjingle_xmpp/xmllite/xmlparser.cc b/third_party/libjingle_xmpp/xmllite/xmlparser.cc new file mode 100644 index 0000000..1f8153f --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlparser.cc
@@ -0,0 +1,261 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" + +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" +#include "third_party/webrtc/base/common.h" + +namespace buzz { + + +static void +StartElementCallback(void * userData, const char *name, const char **atts) { + (static_cast<XmlParser *>(userData))->ExpatStartElement(name, atts); +} + +static void +EndElementCallback(void * userData, const char *name) { + (static_cast<XmlParser *>(userData))->ExpatEndElement(name); +} + +static void +CharacterDataCallback(void * userData, const char *text, int len) { + (static_cast<XmlParser *>(userData))->ExpatCharacterData(text, len); +} + +static void +XmlDeclCallback(void * userData, const char * ver, const char * enc, int st) { + (static_cast<XmlParser *>(userData))->ExpatXmlDecl(ver, enc, st); +} + +XmlParser::XmlParser(XmlParseHandler *pxph) : + pxph_(pxph), sentError_(false) { + expat_ = XML_ParserCreate(NULL); + XML_SetUserData(expat_, this); + XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback); + XML_SetCharacterDataHandler(expat_, CharacterDataCallback); + XML_SetXmlDeclHandler(expat_, XmlDeclCallback); +} + +void +XmlParser::Reset() { + if (!XML_ParserReset(expat_, NULL)) { + XML_ParserFree(expat_); + expat_ = XML_ParserCreate(NULL); + } + XML_SetUserData(expat_, this); + XML_SetElementHandler(expat_, StartElementCallback, EndElementCallback); + XML_SetCharacterDataHandler(expat_, CharacterDataCallback); + XML_SetXmlDeclHandler(expat_, XmlDeclCallback); + context_.Reset(); + sentError_ = false; +} + +static bool +XmlParser_StartsWithXmlns(const char *name) { + return name[0] == 'x' && + name[1] == 'm' && + name[2] == 'l' && + name[3] == 'n' && + name[4] == 's'; +} + +void +XmlParser::ExpatStartElement(const char *name, const char **atts) { + if (context_.RaisedError() != XML_ERROR_NONE) + return; + const char **att; + context_.StartElement(); + for (att = atts; *att; att += 2) { + if (XmlParser_StartsWithXmlns(*att)) { + if ((*att)[5] == '\0') { + context_.StartNamespace("", *(att + 1)); + } + else if ((*att)[5] == ':') { + if (**(att + 1) == '\0') { + // In XML 1.0 empty namespace illegal with prefix (not in 1.1) + context_.RaiseError(XML_ERROR_SYNTAX); + return; + } + context_.StartNamespace((*att) + 6, *(att + 1)); + } + } + } + context_.SetPosition(XML_GetCurrentLineNumber(expat_), + XML_GetCurrentColumnNumber(expat_), + XML_GetCurrentByteIndex(expat_)); + pxph_->StartElement(&context_, name, atts); +} + +void +XmlParser::ExpatEndElement(const char *name) { + if (context_.RaisedError() != XML_ERROR_NONE) + return; + context_.EndElement(); + context_.SetPosition(XML_GetCurrentLineNumber(expat_), + XML_GetCurrentColumnNumber(expat_), + XML_GetCurrentByteIndex(expat_)); + pxph_->EndElement(&context_, name); +} + +void +XmlParser::ExpatCharacterData(const char *text, int len) { + if (context_.RaisedError() != XML_ERROR_NONE) + return; + context_.SetPosition(XML_GetCurrentLineNumber(expat_), + XML_GetCurrentColumnNumber(expat_), + XML_GetCurrentByteIndex(expat_)); + pxph_->CharacterData(&context_, text, len); +} + +void +XmlParser::ExpatXmlDecl(const char * ver, const char * enc, int standalone) { + if (context_.RaisedError() != XML_ERROR_NONE) + return; + + if (ver && std::string("1.0") != ver) { + context_.RaiseError(XML_ERROR_SYNTAX); + return; + } + + if (standalone == 0) { + context_.RaiseError(XML_ERROR_SYNTAX); + return; + } + + if (enc && !((enc[0] == 'U' || enc[0] == 'u') && + (enc[1] == 'T' || enc[1] == 't') && + (enc[2] == 'F' || enc[2] == 'f') && + enc[3] == '-' && enc[4] =='8')) { + context_.RaiseError(XML_ERROR_INCORRECT_ENCODING); + return; + } + +} + +bool +XmlParser::Parse(const char *data, size_t len, bool isFinal) { + if (sentError_) + return false; + + if (XML_Parse(expat_, data, static_cast<int>(len), isFinal) != + XML_STATUS_OK) { + context_.SetPosition(XML_GetCurrentLineNumber(expat_), + XML_GetCurrentColumnNumber(expat_), + XML_GetCurrentByteIndex(expat_)); + context_.RaiseError(XML_GetErrorCode(expat_)); + } + + if (context_.RaisedError() != XML_ERROR_NONE) { + sentError_ = true; + pxph_->Error(&context_, context_.RaisedError()); + return false; + } + + return true; +} + +XmlParser::~XmlParser() { + XML_ParserFree(expat_); +} + +void +XmlParser::ParseXml(XmlParseHandler *pxph, std::string text) { + XmlParser parser(pxph); + parser.Parse(text.c_str(), text.length(), true); +} + +XmlParser::ParseContext::ParseContext() : + xmlnsstack_(), + raised_(XML_ERROR_NONE), + line_number_(0), + column_number_(0), + byte_index_(0) { +} + +void +XmlParser::ParseContext::StartNamespace(const char *prefix, const char *ns) { + xmlnsstack_.AddXmlns(*prefix ? prefix : STR_EMPTY, ns); +} + +void +XmlParser::ParseContext::StartElement() { + xmlnsstack_.PushFrame(); +} + +void +XmlParser::ParseContext::EndElement() { + xmlnsstack_.PopFrame(); +} + +QName +XmlParser::ParseContext::ResolveQName(const char* qname, bool isAttr) { + const char *c; + for (c = qname; *c; ++c) { + if (*c == ':') { + const std::pair<std::string, bool> result = + xmlnsstack_.NsForPrefix(std::string(qname, c - qname)); + if (!result.second) + return QName(); + return QName(result.first, c + 1); + } + } + if (isAttr) + return QName(STR_EMPTY, qname); + + std::pair<std::string, bool> result = xmlnsstack_.NsForPrefix(STR_EMPTY); + if (!result.second) + return QName(); + + return QName(result.first, qname); +} + +void +XmlParser::ParseContext::Reset() { + xmlnsstack_.Reset(); + raised_ = XML_ERROR_NONE; +} + +void +XmlParser::ParseContext::SetPosition(int line, int column, + long byte_index) { + line_number_ = line; + column_number_ = column; + byte_index_ = byte_index; +} + +void +XmlParser::ParseContext::GetPosition(unsigned long * line, + unsigned long * column, + unsigned long * byte_index) { + if (line != NULL) { + *line = static_cast<unsigned long>(line_number_); + } + + if (column != NULL) { + *column = static_cast<unsigned long>(column_number_); + } + + if (byte_index != NULL) { + *byte_index = static_cast<unsigned long>(byte_index_); + } +} + +XmlParser::ParseContext::~ParseContext() { +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/xmlparser.h b/third_party/libjingle_xmpp/xmllite/xmlparser.h new file mode 100644 index 0000000..677dec6 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlparser.h
@@ -0,0 +1,103 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLPARSER_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_XMLPARSER_H_ + +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" +#ifdef EXPAT_RELATIVE_PATH +#include "expat.h" +#else +#include "third_party/expat/v2_0_1/Source/lib/expat.h" +#endif // EXPAT_RELATIVE_PATH + +struct XML_ParserStruct; +typedef struct XML_ParserStruct* XML_Parser; + +namespace buzz { + +class XmlParseHandler; +class XmlParseContext; +class XmlParser; + +class XmlParseContext { +public: + virtual ~XmlParseContext() {} + virtual QName ResolveQName(const char * qname, bool isAttr) = 0; + virtual void RaiseError(XML_Error err) = 0; + virtual void GetPosition(unsigned long * line, unsigned long * column, + unsigned long * byte_index) = 0; +}; + +class XmlParseHandler { +public: + virtual ~XmlParseHandler() {} + virtual void StartElement(XmlParseContext * pctx, + const char * name, const char ** atts) = 0; + virtual void EndElement(XmlParseContext * pctx, + const char * name) = 0; + virtual void CharacterData(XmlParseContext * pctx, + const char * text, int len) = 0; + virtual void Error(XmlParseContext * pctx, + XML_Error errorCode) = 0; +}; + +class XmlParser { +public: + static void ParseXml(XmlParseHandler * pxph, std::string text); + + explicit XmlParser(XmlParseHandler * pxph); + bool Parse(const char * data, size_t len, bool isFinal); + void Reset(); + virtual ~XmlParser(); + + // expat callbacks + void ExpatStartElement(const char * name, const char ** atts); + void ExpatEndElement(const char * name); + void ExpatCharacterData(const char * text, int len); + void ExpatXmlDecl(const char * ver, const char * enc, int standalone); + +private: + + class ParseContext : public XmlParseContext { + public: + ParseContext(); + virtual ~ParseContext(); + virtual QName ResolveQName(const char * qname, bool isAttr); + virtual void RaiseError(XML_Error err) { if (!raised_) raised_ = err; } + virtual void GetPosition(unsigned long * line, unsigned long * column, + unsigned long * byte_index); + XML_Error RaisedError() { return raised_; } + void Reset(); + + void StartElement(); + void EndElement(); + void StartNamespace(const char * prefix, const char * ns); + void SetPosition(int line, int column, long byte_index); + + private: + XmlnsStack xmlnsstack_; + XML_Error raised_; + XML_Size line_number_; + XML_Size column_number_; + XML_Index byte_index_; + }; + + ParseContext context_; + XML_Parser expat_; + XmlParseHandler * pxph_; + bool sentError_; +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMLLITE_XMLPARSER_H_
diff --git a/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc b/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc new file mode 100644 index 0000000..a0a6101 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlparser_unittest.cc
@@ -0,0 +1,285 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::QName; +using buzz::XmlParser; +using buzz::XmlParseContext; +using buzz::XmlParseHandler; + +class XmlParserTestHandler : public XmlParseHandler { + public: + virtual void StartElement(XmlParseContext * pctx, + const char * name, const char ** atts) { + ss_ << "START (" << pctx->ResolveQName(name, false).Merged(); + while (*atts) { + ss_ << ", " << pctx->ResolveQName(*atts, true).Merged() + << "='" << *(atts+1) << "'"; + atts += 2; + } + ss_ << ") "; + } + virtual void EndElement(XmlParseContext * pctx, const char * name) { + RTC_UNUSED(pctx); + RTC_UNUSED(name); + ss_ << "END "; + } + virtual void CharacterData(XmlParseContext * pctx, + const char * text, int len) { + RTC_UNUSED(pctx); + ss_ << "TEXT (" << std::string(text, len) << ") "; + } + virtual void Error(XmlParseContext * pctx, XML_Error code) { + RTC_UNUSED(pctx); + ss_ << "ERROR (" << static_cast<int>(code) << ") "; + } + virtual ~XmlParserTestHandler() { + } + + std::string Str() { + return ss_.str(); + } + + std::string StrClear() { + std::string result = ss_.str(); + ss_.str(""); + return result; + } + + private: + std::stringstream ss_; +}; + + +TEST(XmlParserTest, TestTrivial) { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<testing/>"); + EXPECT_EQ("START (testing) END ", handler.Str()); +} + +TEST(XmlParserTest, TestAttributes) { + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<testing a='b'/>"); + EXPECT_EQ("START (testing, a='b') END ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<testing e='' long='some text'/>"); + EXPECT_EQ("START (testing, e='', long='some text') END ", handler.Str()); + } +} + +TEST(XmlParserTest, TestNesting) { + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<top><first/><second><third></third></second></top>"); + EXPECT_EQ("START (top) START (first) END START (second) START (third) " + "END END END ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<top><fifth><deeper><and><deeper/></and>" + "<sibling><leaf/></sibling></deeper></fifth><first/><second>" + "<third></third></second></top>"); + EXPECT_EQ("START (top) START (fifth) START (deeper) START (and) START " + "(deeper) END END START (sibling) START (leaf) END END END " + "END START (first) END START (second) START (third) END END END ", + handler.Str()); + } +} + +TEST(XmlParserTest, TestXmlDecl) { + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<?xml version=\"1.0\"?><testing/>"); + EXPECT_EQ("START (testing) END ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<?xml version=\"1.0\" encoding=\"utf-8\"?><testing/>"); + EXPECT_EQ("START (testing) END ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "<testing/>"); + EXPECT_EQ("START (testing) END ", handler.Str()); + } +} + +TEST(XmlParserTest, TestNamespace) { + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<top xmlns='my-namespace' a='b'/>"); + EXPECT_EQ("START (my-namespace:top, xmlns='my-namespace', a='b') END ", + handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<foo:top xmlns:foo='my-namespace' " + "a='b' foo:c='d'/>"); + EXPECT_EQ("START (my-namespace:top, " + "http://www.w3.org/2000/xmlns/:foo='my-namespace', " + "a='b', my-namespace:c='d') END ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<top><nested xmlns='my-namespace'><leaf/>" + "</nested><sibling/></top>"); + EXPECT_EQ("START (top) START (my-namespace:nested, xmlns='my-namespace') " + "START (my-namespace:leaf) END END START (sibling) END END ", + handler.Str()); + } +} + +TEST(XmlParserTest, TestIncremental) { + XmlParserTestHandler handler; + XmlParser parser(&handler); + std::string fragment; + + fragment = "<stream:stream"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = " id=\"abcdefg\" xmlns=\""; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = "j:c\" xmlns:stream='hm"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = "ph'><test"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (hmph:stream, id='abcdefg', xmlns='j:c', " + "http://www.w3.org/2000/xmlns/:stream='hmph') ", handler.StrClear()); + + fragment = "ing/><again/>abracad"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (j:c:testing) END START (j:c:again) END TEXT (abracad) ", + handler.StrClear()); + + fragment = "abra</stream:"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("TEXT (abra) ", handler.StrClear()); + + fragment = "stream>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("END ", handler.StrClear()); +} + +TEST(XmlParserTest, TestReset) { + { + XmlParserTestHandler handler; + XmlParser parser(&handler); + std::string fragment; + + fragment = "<top><first/><second><third></third>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (top) START (first) END START (second) START (third) END ", + handler.StrClear()); + + parser.Reset(); + fragment = "<tip><first/><second><third></third>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (tip) START (first) END START (second) START (third) END ", + handler.StrClear()); + } + { + XmlParserTestHandler handler; + XmlParser parser(&handler); + std::string fragment; + + fragment = "<top xmlns='m'>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (m:top, xmlns='m') ", handler.StrClear()); + + fragment = "<testing/><frag"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (m:testing) END ", handler.StrClear()); + + parser.Reset(); + fragment = "<testing><fragment/"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (testing) ", handler.StrClear()); + + fragment = ">"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START (fragment) END ", handler.StrClear()); + } +} + +TEST(XmlParserTest, TestError) { + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "junk"); + EXPECT_EQ("ERROR (2) ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<top/> garbage "); + EXPECT_EQ("START (top) END ERROR (9) ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<-hm->"); + EXPECT_EQ("ERROR (4) ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, "<hello>&foobar;</hello>"); + EXPECT_EQ("START (hello) ERROR (11) ", handler.Str()); + } + { + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<!DOCTYPE HTML PUBLIC \"foobar\" \"barfoo\">"); + EXPECT_EQ("ERROR (3) ", handler.Str()); + } + { + // XmlParser requires utf-8 + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><test/>"); + EXPECT_EQ("ERROR (19) ", handler.Str()); + } + { + // XmlParser requires version 1.0 + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<?xml version=\"2.0\"?><test/>"); + EXPECT_EQ("ERROR (2) ", handler.Str()); + } + { + // XmlParser requires standalone documents + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<?xml version=\"1.0\" standalone=\"no\"?><test/>"); + EXPECT_EQ("ERROR (2) ", handler.Str()); + } + { + // XmlParser doesn't like empty namespace URIs + XmlParserTestHandler handler; + XmlParser::ParseXml(&handler, + "<test xmlns:foo='' foo:bar='huh?'>"); + EXPECT_EQ("ERROR (2) ", handler.Str()); + } +}
diff --git a/third_party/libjingle_xmpp/xmllite/xmlprinter.cc b/third_party/libjingle_xmpp/xmllite/xmlprinter.cc new file mode 100644 index 0000000..5245aa1 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlprinter.cc
@@ -0,0 +1,174 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" + +#include <sstream> +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" + +namespace buzz { + +class XmlPrinterImpl { +public: + XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack); + void PrintElement(const XmlElement* element); + void PrintQuotedValue(const std::string& text); + void PrintBodyText(const std::string& text); + void PrintCDATAText(const std::string& text); + +private: + std::ostream *pout_; + XmlnsStack* ns_stack_; +}; + +void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) { + XmlnsStack ns_stack; + PrintXml(pout, element, &ns_stack); +} + +void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element, + XmlnsStack* ns_stack) { + XmlPrinterImpl printer(pout, ns_stack); + printer.PrintElement(element); +} + +XmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack) + : pout_(pout), + ns_stack_(ns_stack) { +} + +void XmlPrinterImpl::PrintElement(const XmlElement* element) { + ns_stack_->PushFrame(); + + // first go through attrs of pel to add xmlns definitions + const XmlAttr* attr; + for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { + if (attr->Name() == QN_XMLNS) { + ns_stack_->AddXmlns(STR_EMPTY, attr->Value()); + } else if (attr->Name().Namespace() == NS_XMLNS) { + ns_stack_->AddXmlns(attr->Name().LocalPart(), + attr->Value()); + } + } + + // then go through qnames to make sure needed xmlns definitons are added + std::vector<std::string> new_ns; + std::pair<std::string, bool> prefix; + prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false); + if (prefix.second) { + new_ns.push_back(prefix.first); + new_ns.push_back(element->Name().Namespace()); + } + + for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { + prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true); + if (prefix.second) { + new_ns.push_back(prefix.first); + new_ns.push_back(attr->Name().Namespace()); + } + } + + // print the element name + *pout_ << '<' << ns_stack_->FormatQName(element->Name(), false); + + // and the attributes + for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) { + *pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\""; + PrintQuotedValue(attr->Value()); + *pout_ << '"'; + } + + // and the extra xmlns declarations + std::vector<std::string>::iterator i(new_ns.begin()); + while (i < new_ns.end()) { + if (*i == STR_EMPTY) { + *pout_ << " xmlns=\"" << *(i + 1) << '"'; + } else { + *pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"'; + } + i += 2; + } + + // now the children + const XmlChild* child = element->FirstChild(); + + if (child == NULL) + *pout_ << "/>"; + else { + *pout_ << '>'; + while (child) { + if (child->IsText()) { + if (element->IsCDATA()) { + PrintCDATAText(child->AsText()->Text()); + } else { + PrintBodyText(child->AsText()->Text()); + } + } else { + PrintElement(child->AsElement()); + } + child = child->NextChild(); + } + *pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>'; + } + + ns_stack_->PopFrame(); +} + +void XmlPrinterImpl::PrintQuotedValue(const std::string& text) { + size_t safe = 0; + for (;;) { + size_t unsafe = text.find_first_of("<>&\"", safe); + if (unsafe == std::string::npos) + unsafe = text.length(); + *pout_ << text.substr(safe, unsafe - safe); + if (unsafe == text.length()) + return; + switch (text[unsafe]) { + case '<': *pout_ << "<"; break; + case '>': *pout_ << ">"; break; + case '&': *pout_ << "&"; break; + case '"': *pout_ << """; break; + } + safe = unsafe + 1; + if (safe == text.length()) + return; + } +} + +void XmlPrinterImpl::PrintBodyText(const std::string& text) { + size_t safe = 0; + for (;;) { + size_t unsafe = text.find_first_of("<>&", safe); + if (unsafe == std::string::npos) + unsafe = text.length(); + *pout_ << text.substr(safe, unsafe - safe); + if (unsafe == text.length()) + return; + switch (text[unsafe]) { + case '<': *pout_ << "<"; break; + case '>': *pout_ << ">"; break; + case '&': *pout_ << "&"; break; + } + safe = unsafe + 1; + if (safe == text.length()) + return; + } +} + +void XmlPrinterImpl::PrintCDATAText(const std::string& text) { + *pout_ << "<![CDATA[" << text << "]]>"; +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmllite/xmlprinter.h b/third_party/libjingle_xmpp/xmllite/xmlprinter.h new file mode 100644 index 0000000..40cf195 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlprinter.h
@@ -0,0 +1,32 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMLLITE_XMLPRINTER_H_ +#define WEBRTC_LIBJINGLE_XMLLITE_XMLPRINTER_H_ + +#include <iosfwd> +#include <string> + +namespace buzz { + +class XmlElement; +class XmlnsStack; + +class XmlPrinter { + public: + static void PrintXml(std::ostream* pout, const XmlElement* pelt); + + static void PrintXml(std::ostream* pout, const XmlElement* pelt, + XmlnsStack* ns_stack); +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMLLITE_XMLPRINTER_H_
diff --git a/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc b/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc new file mode 100644 index 0000000..f40491d0 --- /dev/null +++ b/third_party/libjingle_xmpp/xmllite/xmlprinter_unittest.cc
@@ -0,0 +1,45 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" + +#include <sstream> +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlnsstack.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::QName; +using buzz::XmlElement; +using buzz::XmlnsStack; +using buzz::XmlPrinter; + +TEST(XmlPrinterTest, TestBasicPrinting) { + XmlElement elt(QName("google:test", "first")); + std::stringstream ss; + XmlPrinter::PrintXml(&ss, &elt); + EXPECT_EQ("<test:first xmlns:test=\"google:test\"/>", ss.str()); +} + +TEST(XmlPrinterTest, TestNamespacedPrinting) { + XmlElement elt(QName("google:test", "first")); + elt.AddElement(new XmlElement(QName("nested:test", "second"))); + std::stringstream ss; + + XmlnsStack ns_stack; + ns_stack.AddXmlns("gg", "google:test"); + ns_stack.AddXmlns("", "nested:test"); + + XmlPrinter::PrintXml(&ss, &elt, &ns_stack); + EXPECT_EQ("<gg:first><second/></gg:first>", ss.str()); +}
diff --git a/third_party/libjingle_xmpp/xmpp/DEPS b/third_party/libjingle_xmpp/xmpp/DEPS new file mode 100644 index 0000000..30a60a4 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/DEPS
@@ -0,0 +1,10 @@ +include_rules = [ + "+third_party/expat", + "+third_party/webrtc/base", + "+third_party/webrtc/p2p", +] +specific_include_rules = { + "xmpplogintask_unittest\.cc": [ + "+third_party/webrtc/typedefs.h", + ], +}
diff --git a/third_party/libjingle_xmpp/xmpp/asyncsocket.h b/third_party/libjingle_xmpp/xmpp/asyncsocket.h new file mode 100644 index 0000000..b4f31e5 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/asyncsocket.h
@@ -0,0 +1,72 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_ +#define WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_ + +#include <string> + +#include "third_party/webrtc/base/sigslot.h" + +namespace rtc { + class SocketAddress; +} + +namespace buzz { + +class AsyncSocket { +public: + enum State { + STATE_CLOSED = 0, //!< Socket is not open. + STATE_CLOSING, //!< Socket is closing but can have buffered data + STATE_CONNECTING, //!< In the process of + STATE_OPEN, //!< Socket is connected +#if defined(FEATURE_ENABLE_SSL) + STATE_TLS_CONNECTING, //!< Establishing TLS connection + STATE_TLS_OPEN, //!< TLS connected +#endif + }; + + enum Error { + ERROR_NONE = 0, //!< No error + ERROR_WINSOCK, //!< Winsock error + ERROR_DNS, //!< Couldn't resolve host name + ERROR_WRONGSTATE, //!< Call made while socket is in the wrong state +#if defined(FEATURE_ENABLE_SSL) + ERROR_SSL, //!< Something went wrong with OpenSSL +#endif + }; + + virtual ~AsyncSocket() {} + virtual State state() = 0; + virtual Error error() = 0; + virtual int GetError() = 0; // winsock error code + + virtual bool Connect(const rtc::SocketAddress& addr) = 0; + virtual bool Read(char * data, size_t len, size_t* len_read) = 0; + virtual bool Write(const char * data, size_t len) = 0; + virtual bool Close() = 0; +#if defined(FEATURE_ENABLE_SSL) + // We allow matching any passed domain. This allows us to avoid + // handling the valuable certificates for logins into proxies. If + // both names are passed as empty, we do not require a match. + virtual bool StartTls(const std::string & domainname) = 0; +#endif + + sigslot::signal0<> SignalConnected; + sigslot::signal0<> SignalSSLConnected; + sigslot::signal0<> SignalClosed; + sigslot::signal0<> SignalRead; + sigslot::signal0<> SignalError; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_ASYNCSOCKET_H_
diff --git a/third_party/libjingle_xmpp/xmpp/constants.cc b/third_party/libjingle_xmpp/xmpp/constants.cc new file mode 100644 index 0000000..2d4c039 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/constants.cc
@@ -0,0 +1,613 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/constants.h" + +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" + +namespace buzz { + +// TODO: Remove static objects of complex types, particularly +// Jid and QName. + +const char NS_CLIENT[] = "jabber:client"; +const char NS_SERVER[] = "jabber:server"; +const char NS_STREAM[] = "http://etherx.jabber.org/streams"; +const char NS_XSTREAM[] = "urn:ietf:params:xml:ns:xmpp-streams"; +const char NS_TLS[] = "urn:ietf:params:xml:ns:xmpp-tls"; +const char NS_SASL[] = "urn:ietf:params:xml:ns:xmpp-sasl"; +const char NS_BIND[] = "urn:ietf:params:xml:ns:xmpp-bind"; +const char NS_DIALBACK[] = "jabber:server:dialback"; +const char NS_SESSION[] = "urn:ietf:params:xml:ns:xmpp-session"; +const char NS_STANZA[] = "urn:ietf:params:xml:ns:xmpp-stanzas"; +const char NS_PRIVACY[] = "jabber:iq:privacy"; +const char NS_ROSTER[] = "jabber:iq:roster"; +const char NS_VCARD[] = "vcard-temp"; +const char NS_AVATAR_HASH[] = "google:avatar"; +const char NS_VCARD_UPDATE[] = "vcard-temp:x:update"; +const char STR_CLIENT[] = "client"; +const char STR_SERVER[] = "server"; +const char STR_STREAM[] = "stream"; + +const char STR_GET[] = "get"; +const char STR_SET[] = "set"; +const char STR_RESULT[] = "result"; +const char STR_ERROR[] = "error"; + +const char STR_FORM[] = "form"; +const char STR_SUBMIT[] = "submit"; +const char STR_TEXT_SINGLE[] = "text-single"; +const char STR_LIST_SINGLE[] = "list-single"; +const char STR_LIST_MULTI[] = "list-multi"; +const char STR_HIDDEN[] = "hidden"; +const char STR_FORM_TYPE[] = "FORM_TYPE"; + +const char STR_FROM[] = "from"; +const char STR_TO[] = "to"; +const char STR_BOTH[] = "both"; +const char STR_REMOVE[] = "remove"; +const char STR_TRUE[] = "true"; + +const char STR_TYPE[] = "type"; +const char STR_NAME[] = "name"; +const char STR_ID[] = "id"; +const char STR_JID[] = "jid"; +const char STR_SUBSCRIPTION[] = "subscription"; +const char STR_ASK[] = "ask"; +const char STR_X[] = "x"; +const char STR_GOOGLE_COM[] = "google.com"; +const char STR_GMAIL_COM[] = "gmail.com"; +const char STR_GOOGLEMAIL_COM[] = "googlemail.com"; +const char STR_DEFAULT_DOMAIN[] = "default.talk.google.com"; +const char STR_TALK_GOOGLE_COM[] = "talk.google.com"; +const char STR_TALKX_L_GOOGLE_COM[] = "talkx.l.google.com"; +const char STR_XMPP_GOOGLE_COM[] = "xmpp.google.com"; +const char STR_XMPPX_L_GOOGLE_COM[] = "xmppx.l.google.com"; + +#ifdef FEATURE_ENABLE_VOICEMAIL +const char STR_VOICEMAIL[] = "voicemail"; +const char STR_OUTGOINGVOICEMAIL[] = "outgoingvoicemail"; +#endif + +const char STR_UNAVAILABLE[] = "unavailable"; + +const char NS_PING[] = "urn:xmpp:ping"; +const StaticQName QN_PING = { NS_PING, "ping" }; + +const char NS_MUC_UNIQUE[] = "http://jabber.org/protocol/muc#unique"; +const StaticQName QN_MUC_UNIQUE_QUERY = { NS_MUC_UNIQUE, "unique" }; +const StaticQName QN_HANGOUT_ID = { STR_EMPTY, "hangout-id" }; + +const char STR_GOOGLE_MUC_LOOKUP_JID[] = "lookup.groupchat.google.com"; + +const char STR_MUC_ROOMCONFIG_ROOMNAME[] = "muc#roomconfig_roomname"; +const char STR_MUC_ROOMCONFIG_FEATURES[] = "muc#roomconfig_features"; +const char STR_MUC_ROOM_FEATURE_ENTERPRISE[] = "muc_enterprise"; +const char STR_MUC_ROOMCONFIG[] = "http://jabber.org/protocol/muc#roomconfig"; +const char STR_MUC_ROOM_FEATURE_HANGOUT[] = "muc_es"; +const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[] = "muc_lite"; +const char STR_MUC_ROOM_FEATURE_BROADCAST[] = "broadcast"; +const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[] = "muc_muvc"; +const char STR_MUC_ROOM_FEATURE_RECORDABLE[] = "recordable"; +const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[] = "custom_recording"; +const char STR_MUC_ROOM_OWNER_PROFILE_ID[] = "muc#roominfo_owner_profile_id"; +const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[] = "abuse_recordable"; + +const char STR_ID_TYPE_CONVERSATION[] = "conversation"; +const char NS_GOOGLE_MUC_HANGOUT[] = "google:muc#hangout"; +const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE = + { NS_GOOGLE_MUC_HANGOUT, "invite" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE = + { NS_GOOGLE_MUC_HANGOUT, "invite-type" }; +const StaticQName QN_ATTR_CREATE_ACTIVITY = + { STR_EMPTY, "create-activity" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC = + { NS_GOOGLE_MUC_HANGOUT, "public" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE = + { NS_GOOGLE_MUC_HANGOUT, "invitee" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS = + { NS_GOOGLE_MUC_HANGOUT, "notification-status" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE = { + NS_GOOGLE_MUC_HANGOUT, "notification-type" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT = { + NS_GOOGLE_MUC_HANGOUT, "hangout-start-context" }; +const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID = { + NS_GOOGLE_MUC_HANGOUT, "conversation-id" }; + +const StaticQName QN_STREAM_STREAM = { NS_STREAM, STR_STREAM }; +const StaticQName QN_STREAM_FEATURES = { NS_STREAM, "features" }; +const StaticQName QN_STREAM_ERROR = { NS_STREAM, "error" }; + +const StaticQName QN_XSTREAM_BAD_FORMAT = { NS_XSTREAM, "bad-format" }; +const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX = + { NS_XSTREAM, "bad-namespace-prefix" }; +const StaticQName QN_XSTREAM_CONFLICT = { NS_XSTREAM, "conflict" }; +const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT = + { NS_XSTREAM, "connection-timeout" }; +const StaticQName QN_XSTREAM_HOST_GONE = { NS_XSTREAM, "host-gone" }; +const StaticQName QN_XSTREAM_HOST_UNKNOWN = { NS_XSTREAM, "host-unknown" }; +const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING = + { NS_XSTREAM, "improper-addressing" }; +const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR = + { NS_XSTREAM, "internal-server-error" }; +const StaticQName QN_XSTREAM_INVALID_FROM = { NS_XSTREAM, "invalid-from" }; +const StaticQName QN_XSTREAM_INVALID_ID = { NS_XSTREAM, "invalid-id" }; +const StaticQName QN_XSTREAM_INVALID_NAMESPACE = + { NS_XSTREAM, "invalid-namespace" }; +const StaticQName QN_XSTREAM_INVALID_XML = { NS_XSTREAM, "invalid-xml" }; +const StaticQName QN_XSTREAM_NOT_AUTHORIZED = { NS_XSTREAM, "not-authorized" }; +const StaticQName QN_XSTREAM_POLICY_VIOLATION = + { NS_XSTREAM, "policy-violation" }; +const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED = + { NS_XSTREAM, "remote-connection-failed" }; +const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT = + { NS_XSTREAM, "resource-constraint" }; +const StaticQName QN_XSTREAM_RESTRICTED_XML = { NS_XSTREAM, "restricted-xml" }; +const StaticQName QN_XSTREAM_SEE_OTHER_HOST = { NS_XSTREAM, "see-other-host" }; +const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN = + { NS_XSTREAM, "system-shutdown" }; +const StaticQName QN_XSTREAM_UNDEFINED_CONDITION = + { NS_XSTREAM, "undefined-condition" }; +const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING = + { NS_XSTREAM, "unsupported-encoding" }; +const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE = + { NS_XSTREAM, "unsupported-stanza-type" }; +const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION = + { NS_XSTREAM, "unsupported-version" }; +const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED = + { NS_XSTREAM, "xml-not-well-formed" }; +const StaticQName QN_XSTREAM_TEXT = { NS_XSTREAM, "text" }; + +const StaticQName QN_TLS_STARTTLS = { NS_TLS, "starttls" }; +const StaticQName QN_TLS_REQUIRED = { NS_TLS, "required" }; +const StaticQName QN_TLS_PROCEED = { NS_TLS, "proceed" }; +const StaticQName QN_TLS_FAILURE = { NS_TLS, "failure" }; + +const StaticQName QN_SASL_MECHANISMS = { NS_SASL, "mechanisms" }; +const StaticQName QN_SASL_MECHANISM = { NS_SASL, "mechanism" }; +const StaticQName QN_SASL_AUTH = { NS_SASL, "auth" }; +const StaticQName QN_SASL_CHALLENGE = { NS_SASL, "challenge" }; +const StaticQName QN_SASL_RESPONSE = { NS_SASL, "response" }; +const StaticQName QN_SASL_ABORT = { NS_SASL, "abort" }; +const StaticQName QN_SASL_SUCCESS = { NS_SASL, "success" }; +const StaticQName QN_SASL_FAILURE = { NS_SASL, "failure" }; +const StaticQName QN_SASL_ABORTED = { NS_SASL, "aborted" }; +const StaticQName QN_SASL_INCORRECT_ENCODING = + { NS_SASL, "incorrect-encoding" }; +const StaticQName QN_SASL_INVALID_AUTHZID = { NS_SASL, "invalid-authzid" }; +const StaticQName QN_SASL_INVALID_MECHANISM = { NS_SASL, "invalid-mechanism" }; +const StaticQName QN_SASL_MECHANISM_TOO_WEAK = + { NS_SASL, "mechanism-too-weak" }; +const StaticQName QN_SASL_NOT_AUTHORIZED = { NS_SASL, "not-authorized" }; +const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE = + { NS_SASL, "temporary-auth-failure" }; + +// These are non-standard. +const char NS_GOOGLE_AUTH_PROTOCOL[] = + "http://www.google.com/talk/protocol/auth"; +const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT = + { NS_GOOGLE_AUTH_PROTOCOL, "client-uses-full-bind-result" }; +const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN = + { NS_GOOGLE_AUTH_PROTOCOL, "allow-non-google-login" }; +const StaticQName QN_GOOGLE_AUTH_SERVICE = + { NS_GOOGLE_AUTH_PROTOCOL, "service" }; + +const StaticQName QN_DIALBACK_RESULT = { NS_DIALBACK, "result" }; +const StaticQName QN_DIALBACK_VERIFY = { NS_DIALBACK, "verify" }; + +const StaticQName QN_STANZA_BAD_REQUEST = { NS_STANZA, "bad-request" }; +const StaticQName QN_STANZA_CONFLICT = { NS_STANZA, "conflict" }; +const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED = + { NS_STANZA, "feature-not-implemented" }; +const StaticQName QN_STANZA_FORBIDDEN = { NS_STANZA, "forbidden" }; +const StaticQName QN_STANZA_GONE = { NS_STANZA, "gone" }; +const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR = + { NS_STANZA, "internal-server-error" }; +const StaticQName QN_STANZA_ITEM_NOT_FOUND = { NS_STANZA, "item-not-found" }; +const StaticQName QN_STANZA_JID_MALFORMED = { NS_STANZA, "jid-malformed" }; +const StaticQName QN_STANZA_NOT_ACCEPTABLE = { NS_STANZA, "not-acceptable" }; +const StaticQName QN_STANZA_NOT_ALLOWED = { NS_STANZA, "not-allowed" }; +const StaticQName QN_STANZA_PAYMENT_REQUIRED = + { NS_STANZA, "payment-required" }; +const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE = + { NS_STANZA, "recipient-unavailable" }; +const StaticQName QN_STANZA_REDIRECT = { NS_STANZA, "redirect" }; +const StaticQName QN_STANZA_REGISTRATION_REQUIRED = + { NS_STANZA, "registration-required" }; +const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND = + { NS_STANZA, "remote-server-not-found" }; +const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT = + { NS_STANZA, "remote-server-timeout" }; +const StaticQName QN_STANZA_RESOURCE_CONSTRAINT = + { NS_STANZA, "resource-constraint" }; +const StaticQName QN_STANZA_SERVICE_UNAVAILABLE = + { NS_STANZA, "service-unavailable" }; +const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED = + { NS_STANZA, "subscription-required" }; +const StaticQName QN_STANZA_UNDEFINED_CONDITION = + { NS_STANZA, "undefined-condition" }; +const StaticQName QN_STANZA_UNEXPECTED_REQUEST = + { NS_STANZA, "unexpected-request" }; +const StaticQName QN_STANZA_TEXT = { NS_STANZA, "text" }; + +const StaticQName QN_BIND_BIND = { NS_BIND, "bind" }; +const StaticQName QN_BIND_RESOURCE = { NS_BIND, "resource" }; +const StaticQName QN_BIND_JID = { NS_BIND, "jid" }; + +const StaticQName QN_MESSAGE = { NS_CLIENT, "message" }; +const StaticQName QN_BODY = { NS_CLIENT, "body" }; +const StaticQName QN_SUBJECT = { NS_CLIENT, "subject" }; +const StaticQName QN_THREAD = { NS_CLIENT, "thread" }; +const StaticQName QN_PRESENCE = { NS_CLIENT, "presence" }; +const StaticQName QN_SHOW = { NS_CLIENT, "show" }; +const StaticQName QN_STATUS = { NS_CLIENT, "status" }; +const StaticQName QN_LANG = { NS_CLIENT, "lang" }; +const StaticQName QN_PRIORITY = { NS_CLIENT, "priority" }; +const StaticQName QN_IQ = { NS_CLIENT, "iq" }; +const StaticQName QN_ERROR = { NS_CLIENT, "error" }; + +const StaticQName QN_SERVER_MESSAGE = { NS_SERVER, "message" }; +const StaticQName QN_SERVER_BODY = { NS_SERVER, "body" }; +const StaticQName QN_SERVER_SUBJECT = { NS_SERVER, "subject" }; +const StaticQName QN_SERVER_THREAD = { NS_SERVER, "thread" }; +const StaticQName QN_SERVER_PRESENCE = { NS_SERVER, "presence" }; +const StaticQName QN_SERVER_SHOW = { NS_SERVER, "show" }; +const StaticQName QN_SERVER_STATUS = { NS_SERVER, "status" }; +const StaticQName QN_SERVER_LANG = { NS_SERVER, "lang" }; +const StaticQName QN_SERVER_PRIORITY = { NS_SERVER, "priority" }; +const StaticQName QN_SERVER_IQ = { NS_SERVER, "iq" }; +const StaticQName QN_SERVER_ERROR = { NS_SERVER, "error" }; + +const StaticQName QN_SESSION_SESSION = { NS_SESSION, "session" }; + +const StaticQName QN_PRIVACY_QUERY = { NS_PRIVACY, "query" }; +const StaticQName QN_PRIVACY_ACTIVE = { NS_PRIVACY, "active" }; +const StaticQName QN_PRIVACY_DEFAULT = { NS_PRIVACY, "default" }; +const StaticQName QN_PRIVACY_LIST = { NS_PRIVACY, "list" }; +const StaticQName QN_PRIVACY_ITEM = { NS_PRIVACY, "item" }; +const StaticQName QN_PRIVACY_IQ = { NS_PRIVACY, "iq" }; +const StaticQName QN_PRIVACY_MESSAGE = { NS_PRIVACY, "message" }; +const StaticQName QN_PRIVACY_PRESENCE_IN = { NS_PRIVACY, "presence-in" }; +const StaticQName QN_PRIVACY_PRESENCE_OUT = { NS_PRIVACY, "presence-out" }; + +const StaticQName QN_ROSTER_QUERY = { NS_ROSTER, "query" }; +const StaticQName QN_ROSTER_ITEM = { NS_ROSTER, "item" }; +const StaticQName QN_ROSTER_GROUP = { NS_ROSTER, "group" }; + +const StaticQName QN_VCARD = { NS_VCARD, "vCard" }; +const StaticQName QN_VCARD_FN = { NS_VCARD, "FN" }; +const StaticQName QN_VCARD_PHOTO = { NS_VCARD, "PHOTO" }; +const StaticQName QN_VCARD_PHOTO_BINVAL = { NS_VCARD, "BINVAL" }; +const StaticQName QN_VCARD_AVATAR_HASH = { NS_AVATAR_HASH, "hash" }; +const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED = + { NS_AVATAR_HASH, "modified" }; + +const StaticQName QN_NAME = { STR_EMPTY, "name" }; +const StaticQName QN_AFFILIATION = { STR_EMPTY, "affiliation" }; +const StaticQName QN_ROLE = { STR_EMPTY, "role" }; + +#if defined(FEATURE_ENABLE_PSTN) +const StaticQName QN_VCARD_TEL = { NS_VCARD, "TEL" }; +const StaticQName QN_VCARD_VOICE = { NS_VCARD, "VOICE" }; +const StaticQName QN_VCARD_HOME = { NS_VCARD, "HOME" }; +const StaticQName QN_VCARD_WORK = { NS_VCARD, "WORK" }; +const StaticQName QN_VCARD_CELL = { NS_VCARD, "CELL" }; +const StaticQName QN_VCARD_NUMBER = { NS_VCARD, "NUMBER" }; +#endif + +const StaticQName QN_XML_LANG = { NS_XML, "lang" }; + +const StaticQName QN_ENCODING = { STR_EMPTY, STR_ENCODING }; +const StaticQName QN_VERSION = { STR_EMPTY, STR_VERSION }; +const StaticQName QN_TO = { STR_EMPTY, "to" }; +const StaticQName QN_FROM = { STR_EMPTY, "from" }; +const StaticQName QN_TYPE = { STR_EMPTY, "type" }; +const StaticQName QN_ID = { STR_EMPTY, "id" }; +const StaticQName QN_CODE = { STR_EMPTY, "code" }; + +const StaticQName QN_VALUE = { STR_EMPTY, "value" }; +const StaticQName QN_ACTION = { STR_EMPTY, "action" }; +const StaticQName QN_ORDER = { STR_EMPTY, "order" }; +const StaticQName QN_MECHANISM = { STR_EMPTY, "mechanism" }; +const StaticQName QN_ASK = { STR_EMPTY, "ask" }; +const StaticQName QN_JID = { STR_EMPTY, "jid" }; +const StaticQName QN_NICK = { STR_EMPTY, "nick" }; +const StaticQName QN_SUBSCRIPTION = { STR_EMPTY, "subscription" }; +const StaticQName QN_TITLE1 = { STR_EMPTY, "title1" }; +const StaticQName QN_TITLE2 = { STR_EMPTY, "title2" }; + +const StaticQName QN_XMLNS_CLIENT = { NS_XMLNS, STR_CLIENT }; +const StaticQName QN_XMLNS_SERVER = { NS_XMLNS, STR_SERVER }; +const StaticQName QN_XMLNS_STREAM = { NS_XMLNS, STR_STREAM }; + + +// Presence +const char STR_SHOW_AWAY[] = "away"; +const char STR_SHOW_CHAT[] = "chat"; +const char STR_SHOW_DND[] = "dnd"; +const char STR_SHOW_XA[] = "xa"; +const char STR_SHOW_OFFLINE[] = "offline"; + +const char NS_GOOGLE_PSTN_CONFERENCE[] = "http://www.google.com/pstn-conference"; +const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS = { NS_GOOGLE_PSTN_CONFERENCE, "status" }; +const StaticQName QN_ATTR_STATUS = { STR_EMPTY, "status" }; + +// Presence connection status +const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[] = "connecting"; +const char STR_PSTN_CONFERENCE_STATUS_JOINING[] = "joining"; +const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[] = "connected"; +const char STR_PSTN_CONFERENCE_STATUS_HANGUP[] = "hangup"; + +// Subscription +const char STR_SUBSCRIBE[] = "subscribe"; +const char STR_SUBSCRIBED[] = "subscribed"; +const char STR_UNSUBSCRIBE[] = "unsubscribe"; +const char STR_UNSUBSCRIBED[] = "unsubscribed"; + +// Google Invite +const char NS_GOOGLE_SUBSCRIBE[] = "google:subscribe"; +const StaticQName QN_INVITATION = { NS_GOOGLE_SUBSCRIBE, "invitation" }; +const StaticQName QN_INVITE_NAME = { NS_GOOGLE_SUBSCRIBE, "name" }; +const StaticQName QN_INVITE_SUBJECT = { NS_GOOGLE_SUBSCRIBE, "subject" }; +const StaticQName QN_INVITE_MESSAGE = { NS_GOOGLE_SUBSCRIBE, "body" }; + +// Kick +const char NS_GOOGLE_MUC_ADMIN[] = "google:muc#admin"; +const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY = { NS_GOOGLE_MUC_ADMIN, "query" }; +const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM = + { NS_GOOGLE_MUC_ADMIN, "item" }; +const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON = + { NS_GOOGLE_MUC_ADMIN, "reason" }; + +// PubSub: http://xmpp.org/extensions/xep-0060.html +const char NS_PUBSUB[] = "http://jabber.org/protocol/pubsub"; +const StaticQName QN_PUBSUB = { NS_PUBSUB, "pubsub" }; +const StaticQName QN_PUBSUB_ITEMS = { NS_PUBSUB, "items" }; +const StaticQName QN_PUBSUB_ITEM = { NS_PUBSUB, "item" }; +const StaticQName QN_PUBSUB_PUBLISH = { NS_PUBSUB, "publish" }; +const StaticQName QN_PUBSUB_RETRACT = { NS_PUBSUB, "retract" }; +const StaticQName QN_ATTR_PUBLISHER = { STR_EMPTY, "publisher" }; + +const char NS_PUBSUB_EVENT[] = "http://jabber.org/protocol/pubsub#event"; +const StaticQName QN_NODE = { STR_EMPTY, "node" }; +const StaticQName QN_PUBSUB_EVENT = { NS_PUBSUB_EVENT, "event" }; +const StaticQName QN_PUBSUB_EVENT_ITEMS = { NS_PUBSUB_EVENT, "items" }; +const StaticQName QN_PUBSUB_EVENT_ITEM = { NS_PUBSUB_EVENT, "item" }; +const StaticQName QN_PUBSUB_EVENT_RETRACT = { NS_PUBSUB_EVENT, "retract" }; +const StaticQName QN_NOTIFY = { STR_EMPTY, "notify" }; + +const char NS_PRESENTER[] = "google:presenter"; +const StaticQName QN_PRESENTER_PRESENTER = { NS_PRESENTER, "presenter" }; +const StaticQName QN_PRESENTER_PRESENTATION_ITEM = + { NS_PRESENTER, "presentation-item" }; +const StaticQName QN_PRESENTER_PRESENTATION_TYPE = + { NS_PRESENTER, "presentation-type" }; +const StaticQName QN_PRESENTER_PRESENTATION_ID = + { NS_PRESENTER, "presentation-id" }; + +// JEP 0030 +const StaticQName QN_CATEGORY = { STR_EMPTY, "category" }; +const StaticQName QN_VAR = { STR_EMPTY, "var" }; +const char NS_DISCO_INFO[] = "http://jabber.org/protocol/disco#info"; +const char NS_DISCO_ITEMS[] = "http://jabber.org/protocol/disco#items"; +const StaticQName QN_DISCO_INFO_QUERY = { NS_DISCO_INFO, "query" }; +const StaticQName QN_DISCO_IDENTITY = { NS_DISCO_INFO, "identity" }; +const StaticQName QN_DISCO_FEATURE = { NS_DISCO_INFO, "feature" }; + +const StaticQName QN_DISCO_ITEMS_QUERY = { NS_DISCO_ITEMS, "query" }; +const StaticQName QN_DISCO_ITEM = { NS_DISCO_ITEMS, "item" }; + +// JEP 0020 +const char NS_FEATURE[] = "http://jabber.org/protocol/feature-neg"; +const StaticQName QN_FEATURE_FEATURE = { NS_FEATURE, "feature" }; + +// JEP 0004 +const char NS_XDATA[] = "jabber:x:data"; +const StaticQName QN_XDATA_X = { NS_XDATA, "x" }; +const StaticQName QN_XDATA_INSTRUCTIONS = { NS_XDATA, "instructions" }; +const StaticQName QN_XDATA_TITLE = { NS_XDATA, "title" }; +const StaticQName QN_XDATA_FIELD = { NS_XDATA, "field" }; +const StaticQName QN_XDATA_REPORTED = { NS_XDATA, "reported" }; +const StaticQName QN_XDATA_ITEM = { NS_XDATA, "item" }; +const StaticQName QN_XDATA_DESC = { NS_XDATA, "desc" }; +const StaticQName QN_XDATA_REQUIRED = { NS_XDATA, "required" }; +const StaticQName QN_XDATA_VALUE = { NS_XDATA, "value" }; +const StaticQName QN_XDATA_OPTION = { NS_XDATA, "option" }; + +// JEP 0045 +const char NS_MUC[] = "http://jabber.org/protocol/muc"; +const StaticQName QN_MUC_X = { NS_MUC, "x" }; +const StaticQName QN_MUC_ITEM = { NS_MUC, "item" }; +const StaticQName QN_MUC_AFFILIATION = { NS_MUC, "affiliation" }; +const StaticQName QN_MUC_ROLE = { NS_MUC, "role" }; +const char STR_AFFILIATION_NONE[] = "none"; +const char STR_ROLE_PARTICIPANT[] = "participant"; + +const char NS_GOOGLE_SESSION[] = "http://www.google.com/session"; +const StaticQName QN_GOOGLE_CIRCLE_ID = { STR_EMPTY, "google-circle-id" }; +const StaticQName QN_GOOGLE_USER_ID = { STR_EMPTY, "google-user-id" }; +const StaticQName QN_GOOGLE_SESSION_BLOCKED = { NS_GOOGLE_SESSION, "blocked" }; +const StaticQName QN_GOOGLE_SESSION_BLOCKING = + { NS_GOOGLE_SESSION, "blocking" }; + +const char NS_MUC_OWNER[] = "http://jabber.org/protocol/muc#owner"; +const StaticQName QN_MUC_OWNER_QUERY = { NS_MUC_OWNER, "query" }; + +const char NS_MUC_USER[] = "http://jabber.org/protocol/muc#user"; +const StaticQName QN_MUC_USER_CONTINUE = { NS_MUC_USER, "continue" }; +const StaticQName QN_MUC_USER_X = { NS_MUC_USER, "x" }; +const StaticQName QN_MUC_USER_ITEM = { NS_MUC_USER, "item" }; +const StaticQName QN_MUC_USER_STATUS = { NS_MUC_USER, "status" }; +const StaticQName QN_MUC_USER_REASON = { NS_MUC_USER, "reason" }; +const StaticQName QN_MUC_USER_ABUSE_VIOLATION = { NS_MUC_USER, "abuse-violation" }; + +// JEP 0055 - Jabber Search +const char NS_SEARCH[] = "jabber:iq:search"; +const StaticQName QN_SEARCH_QUERY = { NS_SEARCH, "query" }; +const StaticQName QN_SEARCH_ITEM = { NS_SEARCH, "item" }; +const StaticQName QN_SEARCH_ROOM_NAME = { NS_SEARCH, "room-name" }; +const StaticQName QN_SEARCH_ROOM_DOMAIN = { NS_SEARCH, "room-domain" }; +const StaticQName QN_SEARCH_ROOM_JID = { NS_SEARCH, "room-jid" }; +const StaticQName QN_SEARCH_HANGOUT_ID = { NS_SEARCH, "hangout-id" }; +const StaticQName QN_SEARCH_EXTERNAL_ID = { NS_SEARCH, "external-id" }; + +// JEP 0115 +const char NS_CAPS[] = "http://jabber.org/protocol/caps"; +const StaticQName QN_CAPS_C = { NS_CAPS, "c" }; +const StaticQName QN_VER = { STR_EMPTY, "ver" }; +const StaticQName QN_EXT = { STR_EMPTY, "ext" }; + +// JEP 0153 +const char kNSVCard[] = "vcard-temp:x:update"; +const StaticQName kQnVCardX = { kNSVCard, "x" }; +const StaticQName kQnVCardPhoto = { kNSVCard, "photo" }; + +// JEP 0172 User Nickname +const char NS_NICKNAME[] = "http://jabber.org/protocol/nick"; +const StaticQName QN_NICKNAME = { NS_NICKNAME, "nick" }; + +// JEP 0085 chat state +const char NS_CHATSTATE[] = "http://jabber.org/protocol/chatstates"; +const StaticQName QN_CS_ACTIVE = { NS_CHATSTATE, "active" }; +const StaticQName QN_CS_COMPOSING = { NS_CHATSTATE, "composing" }; +const StaticQName QN_CS_PAUSED = { NS_CHATSTATE, "paused" }; +const StaticQName QN_CS_INACTIVE = { NS_CHATSTATE, "inactive" }; +const StaticQName QN_CS_GONE = { NS_CHATSTATE, "gone" }; + +// JEP 0091 Delayed Delivery +const char kNSDelay[] = "jabber:x:delay"; +const StaticQName kQnDelayX = { kNSDelay, "x" }; +const StaticQName kQnStamp = { STR_EMPTY, "stamp" }; + +// Google time stamping (higher resolution) +const char kNSTimestamp[] = "google:timestamp"; +const StaticQName kQnTime = { kNSTimestamp, "time" }; +const StaticQName kQnMilliseconds = { STR_EMPTY, "ms" }; + +// Jingle Info +const char NS_JINGLE_INFO[] = "google:jingleinfo"; +const StaticQName QN_JINGLE_INFO_QUERY = { NS_JINGLE_INFO, "query" }; +const StaticQName QN_JINGLE_INFO_STUN = { NS_JINGLE_INFO, "stun" }; +const StaticQName QN_JINGLE_INFO_RELAY = { NS_JINGLE_INFO, "relay" }; +const StaticQName QN_JINGLE_INFO_SERVER = { NS_JINGLE_INFO, "server" }; +const StaticQName QN_JINGLE_INFO_TOKEN = { NS_JINGLE_INFO, "token" }; +const StaticQName QN_JINGLE_INFO_HOST = { STR_EMPTY, "host" }; +const StaticQName QN_JINGLE_INFO_TCP = { STR_EMPTY, "tcp" }; +const StaticQName QN_JINGLE_INFO_UDP = { STR_EMPTY, "udp" }; +const StaticQName QN_JINGLE_INFO_TCPSSL = { STR_EMPTY, "tcpssl" }; + +// Call Performance Logging +const char NS_GOOGLE_CALLPERF_STATS[] = "google:call-perf-stats"; +const StaticQName QN_CALLPERF_STATS = + { NS_GOOGLE_CALLPERF_STATS, "callPerfStats" }; +const StaticQName QN_CALLPERF_SESSIONID = { STR_EMPTY, "sessionId" }; +const StaticQName QN_CALLPERF_LOCALUSER = { STR_EMPTY, "localUser" }; +const StaticQName QN_CALLPERF_REMOTEUSER = { STR_EMPTY, "remoteUser" }; +const StaticQName QN_CALLPERF_STARTTIME = { STR_EMPTY, "startTime" }; +const StaticQName QN_CALLPERF_CALL_LENGTH = { STR_EMPTY, "callLength" }; +const StaticQName QN_CALLPERF_CALL_ACCEPTED = { STR_EMPTY, "callAccepted" }; +const StaticQName QN_CALLPERF_CALL_ERROR_CODE = { STR_EMPTY, "callErrorCode" }; +const StaticQName QN_CALLPERF_TERMINATE_CODE = { STR_EMPTY, "terminateCode" }; +const StaticQName QN_CALLPERF_DATAPOINT = + { NS_GOOGLE_CALLPERF_STATS, "dataPoint" }; +const StaticQName QN_CALLPERF_DATAPOINT_TIME = { STR_EMPTY, "timeStamp" }; +const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST = + { STR_EMPTY, "fraction_lost" }; +const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST = { STR_EMPTY, "cum_lost" }; +const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX = { STR_EMPTY, "ext_max" }; +const StaticQName QN_CALLPERF_DATAPOINT_JITTER = { STR_EMPTY, "jitter" }; +const StaticQName QN_CALLPERF_DATAPOINT_RTT = { STR_EMPTY, "RTT" }; +const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R = + { STR_EMPTY, "bytesReceived" }; +const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R = + { STR_EMPTY, "packetsReceived" }; +const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S = { STR_EMPTY, "bytesSent" }; +const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S = + { STR_EMPTY, "packetsSent" }; +const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU = + { STR_EMPTY, "processCpu" }; +const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU = { STR_EMPTY, "systemCpu" }; +const StaticQName QN_CALLPERF_DATAPOINT_CPUS = { STR_EMPTY, "cpus" }; +const StaticQName QN_CALLPERF_CONNECTION = + { NS_GOOGLE_CALLPERF_STATS, "connection" }; +const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS = + { STR_EMPTY, "localAddress" }; +const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS = + { STR_EMPTY, "remoteAddress" }; +const StaticQName QN_CALLPERF_CONNECTION_FLAGS = { STR_EMPTY, "flags" }; +const StaticQName QN_CALLPERF_CONNECTION_RTT = { STR_EMPTY, "rtt" }; +const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S = + { STR_EMPTY, "totalBytesSent" }; +const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S = + { STR_EMPTY, "bytesSecondSent" }; +const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R = + { STR_EMPTY, "totalBytesRecv" }; +const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R = + { STR_EMPTY, "bytesSecondRecv" }; +const StaticQName QN_CALLPERF_CANDIDATE = + { NS_GOOGLE_CALLPERF_STATS, "candidate" }; +const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT = { STR_EMPTY, "endpoint" }; +const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL = { STR_EMPTY, "protocol" }; +const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS = { STR_EMPTY, "address" }; +const StaticQName QN_CALLPERF_MEDIA = { NS_GOOGLE_CALLPERF_STATS, "media" }; +const StaticQName QN_CALLPERF_MEDIA_DIRECTION = { STR_EMPTY, "direction" }; +const StaticQName QN_CALLPERF_MEDIA_SSRC = { STR_EMPTY, "SSRC" }; +const StaticQName QN_CALLPERF_MEDIA_ENERGY = { STR_EMPTY, "energy" }; +const StaticQName QN_CALLPERF_MEDIA_FIR = { STR_EMPTY, "fir" }; +const StaticQName QN_CALLPERF_MEDIA_NACK = { STR_EMPTY, "nack" }; +const StaticQName QN_CALLPERF_MEDIA_FPS = { STR_EMPTY, "fps" }; +const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK = { STR_EMPTY, "fpsNetwork" }; +const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED = { STR_EMPTY, "fpsDecoded" }; +const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE = + { STR_EMPTY, "jitterBufferSize" }; +const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE = + { STR_EMPTY, "preferredJitterBufferSize" }; +const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY = + { STR_EMPTY, "totalPlayoutDelay" }; + +// Muc invites. +const StaticQName QN_MUC_USER_INVITE = { NS_MUC_USER, "invite" }; + +// Multiway audio/video. +const char NS_GOOGLE_MUC_USER[] = "google:muc#user"; +const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA = + { NS_GOOGLE_MUC_USER, "available-media" }; +const StaticQName QN_GOOGLE_MUC_USER_ENTRY = { NS_GOOGLE_MUC_USER, "entry" }; +const StaticQName QN_GOOGLE_MUC_USER_MEDIA = { NS_GOOGLE_MUC_USER, "media" }; +const StaticQName QN_GOOGLE_MUC_USER_TYPE = { NS_GOOGLE_MUC_USER, "type" }; +const StaticQName QN_GOOGLE_MUC_USER_SRC_ID = { NS_GOOGLE_MUC_USER, "src-id" }; +const StaticQName QN_GOOGLE_MUC_USER_STATUS = { NS_GOOGLE_MUC_USER, "status" }; +const StaticQName QN_CLIENT_VERSION = { NS_GOOGLE_MUC_USER, "client-version" }; +const StaticQName QN_LOCALE = { NS_GOOGLE_MUC_USER, "locale" }; +const StaticQName QN_LABEL = { STR_EMPTY, "label" }; + +const char NS_GOOGLE_MUC_MEDIA[] = "google:muc#media"; +const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE = + { NS_GOOGLE_MUC_MEDIA, "audio-mute" }; +const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE = + { NS_GOOGLE_MUC_MEDIA, "video-mute" }; +const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE = + { NS_GOOGLE_MUC_MEDIA, "video-pause" }; +const StaticQName QN_GOOGLE_MUC_RECORDING = + { NS_GOOGLE_MUC_MEDIA, "recording" }; +const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK = { NS_GOOGLE_MUC_MEDIA, "block" }; +const StaticQName QN_STATE_ATTR = { STR_EMPTY, "state" }; + +const char AUTH_MECHANISM_GOOGLE_COOKIE[] = "X-GOOGLE-COOKIE"; +const char AUTH_MECHANISM_GOOGLE_TOKEN[] = "X-GOOGLE-TOKEN"; +const char AUTH_MECHANISM_OAUTH2[] = "X-OAUTH2"; +const char AUTH_MECHANISM_PLAIN[] = "PLAIN"; + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmpp/constants.h b/third_party/libjingle_xmpp/xmpp/constants.h new file mode 100644 index 0000000..dad55bf8 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/constants.h
@@ -0,0 +1,551 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_ +#define WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_ + +#include <string> +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" + +namespace buzz { + +extern const char NS_CLIENT[]; +extern const char NS_SERVER[]; +extern const char NS_STREAM[]; +extern const char NS_XSTREAM[]; +extern const char NS_TLS[]; +extern const char NS_SASL[]; +extern const char NS_BIND[]; +extern const char NS_DIALBACK[]; +extern const char NS_SESSION[]; +extern const char NS_STANZA[]; +extern const char NS_PRIVACY[]; +extern const char NS_ROSTER[]; +extern const char NS_VCARD[]; +extern const char NS_AVATAR_HASH[]; +extern const char NS_VCARD_UPDATE[]; +extern const char STR_CLIENT[]; +extern const char STR_SERVER[]; +extern const char STR_STREAM[]; + +extern const char STR_GET[]; +extern const char STR_SET[]; +extern const char STR_RESULT[]; +extern const char STR_ERROR[]; + +extern const char STR_FORM[]; +extern const char STR_SUBMIT[]; +extern const char STR_TEXT_SINGLE[]; +extern const char STR_LIST_SINGLE[]; +extern const char STR_LIST_MULTI[]; +extern const char STR_HIDDEN[]; +extern const char STR_FORM_TYPE[]; + +extern const char STR_FROM[]; +extern const char STR_TO[]; +extern const char STR_BOTH[]; +extern const char STR_REMOVE[]; +extern const char STR_TRUE[]; + +extern const char STR_TYPE[]; +extern const char STR_NAME[]; +extern const char STR_ID[]; +extern const char STR_JID[]; +extern const char STR_SUBSCRIPTION[]; +extern const char STR_ASK[]; +extern const char STR_X[]; +extern const char STR_GOOGLE_COM[]; +extern const char STR_GMAIL_COM[]; +extern const char STR_GOOGLEMAIL_COM[]; +extern const char STR_DEFAULT_DOMAIN[]; +extern const char STR_TALK_GOOGLE_COM[]; +extern const char STR_TALKX_L_GOOGLE_COM[]; +extern const char STR_XMPP_GOOGLE_COM[]; +extern const char STR_XMPPX_L_GOOGLE_COM[]; + +#ifdef FEATURE_ENABLE_VOICEMAIL +extern const char STR_VOICEMAIL[]; +extern const char STR_OUTGOINGVOICEMAIL[]; +#endif + +extern const char STR_UNAVAILABLE[]; + +extern const char NS_PING[]; +extern const StaticQName QN_PING; + +extern const char NS_MUC_UNIQUE[]; +extern const StaticQName QN_MUC_UNIQUE_QUERY; +extern const StaticQName QN_HANGOUT_ID; + +extern const char STR_GOOGLE_MUC_LOOKUP_JID[]; +extern const char STR_MUC_ROOMCONFIG_ROOMNAME[]; +extern const char STR_MUC_ROOMCONFIG_FEATURES[]; +extern const char STR_MUC_ROOM_FEATURE_ENTERPRISE[]; +extern const char STR_MUC_ROOMCONFIG[]; +extern const char STR_MUC_ROOM_FEATURE_HANGOUT[]; +extern const char STR_MUC_ROOM_FEATURE_HANGOUT_LITE[]; +extern const char STR_MUC_ROOM_FEATURE_BROADCAST[]; +extern const char STR_MUC_ROOM_FEATURE_MULTI_USER_VC[]; +extern const char STR_MUC_ROOM_FEATURE_RECORDABLE[]; +extern const char STR_MUC_ROOM_FEATURE_CUSTOM_RECORDING[]; +extern const char STR_MUC_ROOM_OWNER_PROFILE_ID[]; +extern const char STR_MUC_ROOM_FEATURE_ABUSE_RECORDABLE[]; + +extern const char STR_ID_TYPE_CONVERSATION[]; +extern const char NS_GOOGLE_MUC_HANGOUT[]; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITE_TYPE; +extern const StaticQName QN_ATTR_CREATE_ACTIVITY; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_PUBLIC; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_INVITEE; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_STATUS; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_NOTIFICATION_TYPE; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_HANGOUT_START_CONTEXT; +extern const StaticQName QN_GOOGLE_MUC_HANGOUT_CONVERSATION_ID; + +extern const StaticQName QN_STREAM_STREAM; +extern const StaticQName QN_STREAM_FEATURES; +extern const StaticQName QN_STREAM_ERROR; + +extern const StaticQName QN_XSTREAM_BAD_FORMAT; +extern const StaticQName QN_XSTREAM_BAD_NAMESPACE_PREFIX; +extern const StaticQName QN_XSTREAM_CONFLICT; +extern const StaticQName QN_XSTREAM_CONNECTION_TIMEOUT; +extern const StaticQName QN_XSTREAM_HOST_GONE; +extern const StaticQName QN_XSTREAM_HOST_UNKNOWN; +extern const StaticQName QN_XSTREAM_IMPROPER_ADDRESSIING; +extern const StaticQName QN_XSTREAM_INTERNAL_SERVER_ERROR; +extern const StaticQName QN_XSTREAM_INVALID_FROM; +extern const StaticQName QN_XSTREAM_INVALID_ID; +extern const StaticQName QN_XSTREAM_INVALID_NAMESPACE; +extern const StaticQName QN_XSTREAM_INVALID_XML; +extern const StaticQName QN_XSTREAM_NOT_AUTHORIZED; +extern const StaticQName QN_XSTREAM_POLICY_VIOLATION; +extern const StaticQName QN_XSTREAM_REMOTE_CONNECTION_FAILED; +extern const StaticQName QN_XSTREAM_RESOURCE_CONSTRAINT; +extern const StaticQName QN_XSTREAM_RESTRICTED_XML; +extern const StaticQName QN_XSTREAM_SEE_OTHER_HOST; +extern const StaticQName QN_XSTREAM_SYSTEM_SHUTDOWN; +extern const StaticQName QN_XSTREAM_UNDEFINED_CONDITION; +extern const StaticQName QN_XSTREAM_UNSUPPORTED_ENCODING; +extern const StaticQName QN_XSTREAM_UNSUPPORTED_STANZA_TYPE; +extern const StaticQName QN_XSTREAM_UNSUPPORTED_VERSION; +extern const StaticQName QN_XSTREAM_XML_NOT_WELL_FORMED; +extern const StaticQName QN_XSTREAM_TEXT; + +extern const StaticQName QN_TLS_STARTTLS; +extern const StaticQName QN_TLS_REQUIRED; +extern const StaticQName QN_TLS_PROCEED; +extern const StaticQName QN_TLS_FAILURE; + +extern const StaticQName QN_SASL_MECHANISMS; +extern const StaticQName QN_SASL_MECHANISM; +extern const StaticQName QN_SASL_AUTH; +extern const StaticQName QN_SASL_CHALLENGE; +extern const StaticQName QN_SASL_RESPONSE; +extern const StaticQName QN_SASL_ABORT; +extern const StaticQName QN_SASL_SUCCESS; +extern const StaticQName QN_SASL_FAILURE; +extern const StaticQName QN_SASL_ABORTED; +extern const StaticQName QN_SASL_INCORRECT_ENCODING; +extern const StaticQName QN_SASL_INVALID_AUTHZID; +extern const StaticQName QN_SASL_INVALID_MECHANISM; +extern const StaticQName QN_SASL_MECHANISM_TOO_WEAK; +extern const StaticQName QN_SASL_NOT_AUTHORIZED; +extern const StaticQName QN_SASL_TEMPORARY_AUTH_FAILURE; + +// These are non-standard. +extern const char NS_GOOGLE_AUTH[]; +extern const char NS_GOOGLE_AUTH_PROTOCOL[]; +extern const StaticQName QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT; +extern const StaticQName QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN; +extern const StaticQName QN_GOOGLE_AUTH_SERVICE; + +extern const StaticQName QN_DIALBACK_RESULT; +extern const StaticQName QN_DIALBACK_VERIFY; + +extern const StaticQName QN_STANZA_BAD_REQUEST; +extern const StaticQName QN_STANZA_CONFLICT; +extern const StaticQName QN_STANZA_FEATURE_NOT_IMPLEMENTED; +extern const StaticQName QN_STANZA_FORBIDDEN; +extern const StaticQName QN_STANZA_GONE; +extern const StaticQName QN_STANZA_INTERNAL_SERVER_ERROR; +extern const StaticQName QN_STANZA_ITEM_NOT_FOUND; +extern const StaticQName QN_STANZA_JID_MALFORMED; +extern const StaticQName QN_STANZA_NOT_ACCEPTABLE; +extern const StaticQName QN_STANZA_NOT_ALLOWED; +extern const StaticQName QN_STANZA_PAYMENT_REQUIRED; +extern const StaticQName QN_STANZA_RECIPIENT_UNAVAILABLE; +extern const StaticQName QN_STANZA_REDIRECT; +extern const StaticQName QN_STANZA_REGISTRATION_REQUIRED; +extern const StaticQName QN_STANZA_REMOTE_SERVER_NOT_FOUND; +extern const StaticQName QN_STANZA_REMOTE_SERVER_TIMEOUT; +extern const StaticQName QN_STANZA_RESOURCE_CONSTRAINT; +extern const StaticQName QN_STANZA_SERVICE_UNAVAILABLE; +extern const StaticQName QN_STANZA_SUBSCRIPTION_REQUIRED; +extern const StaticQName QN_STANZA_UNDEFINED_CONDITION; +extern const StaticQName QN_STANZA_UNEXPECTED_REQUEST; +extern const StaticQName QN_STANZA_TEXT; + +extern const StaticQName QN_BIND_BIND; +extern const StaticQName QN_BIND_RESOURCE; +extern const StaticQName QN_BIND_JID; + +extern const StaticQName QN_MESSAGE; +extern const StaticQName QN_BODY; +extern const StaticQName QN_SUBJECT; +extern const StaticQName QN_THREAD; +extern const StaticQName QN_PRESENCE; +extern const StaticQName QN_SHOW; +extern const StaticQName QN_STATUS; +extern const StaticQName QN_LANG; +extern const StaticQName QN_PRIORITY; +extern const StaticQName QN_IQ; +extern const StaticQName QN_ERROR; + +extern const StaticQName QN_SERVER_MESSAGE; +extern const StaticQName QN_SERVER_BODY; +extern const StaticQName QN_SERVER_SUBJECT; +extern const StaticQName QN_SERVER_THREAD; +extern const StaticQName QN_SERVER_PRESENCE; +extern const StaticQName QN_SERVER_SHOW; +extern const StaticQName QN_SERVER_STATUS; +extern const StaticQName QN_SERVER_LANG; +extern const StaticQName QN_SERVER_PRIORITY; +extern const StaticQName QN_SERVER_IQ; +extern const StaticQName QN_SERVER_ERROR; + +extern const StaticQName QN_SESSION_SESSION; + +extern const StaticQName QN_PRIVACY_QUERY; +extern const StaticQName QN_PRIVACY_ACTIVE; +extern const StaticQName QN_PRIVACY_DEFAULT; +extern const StaticQName QN_PRIVACY_LIST; +extern const StaticQName QN_PRIVACY_ITEM; +extern const StaticQName QN_PRIVACY_IQ; +extern const StaticQName QN_PRIVACY_MESSAGE; +extern const StaticQName QN_PRIVACY_PRESENCE_IN; +extern const StaticQName QN_PRIVACY_PRESENCE_OUT; + +extern const StaticQName QN_ROSTER_QUERY; +extern const StaticQName QN_ROSTER_ITEM; +extern const StaticQName QN_ROSTER_GROUP; + +extern const StaticQName QN_VCARD; +extern const StaticQName QN_VCARD_FN; +extern const StaticQName QN_VCARD_PHOTO; +extern const StaticQName QN_VCARD_PHOTO_BINVAL; +extern const StaticQName QN_VCARD_AVATAR_HASH; +extern const StaticQName QN_VCARD_AVATAR_HASH_MODIFIED; + +#if defined(FEATURE_ENABLE_PSTN) +extern const StaticQName QN_VCARD_TEL; +extern const StaticQName QN_VCARD_VOICE; +extern const StaticQName QN_VCARD_HOME; +extern const StaticQName QN_VCARD_WORK; +extern const StaticQName QN_VCARD_CELL; +extern const StaticQName QN_VCARD_NUMBER; +#endif + +#if defined(FEATURE_ENABLE_RICHPROFILES) +extern const StaticQName QN_USER_PROFILE_QUERY; +extern const StaticQName QN_USER_PROFILE_URL; + +extern const StaticQName QN_ATOM_FEED; +extern const StaticQName QN_ATOM_ENTRY; +extern const StaticQName QN_ATOM_TITLE; +extern const StaticQName QN_ATOM_ID; +extern const StaticQName QN_ATOM_MODIFIED; +extern const StaticQName QN_ATOM_IMAGE; +extern const StaticQName QN_ATOM_LINK; +extern const StaticQName QN_ATOM_HREF; +#endif + +extern const StaticQName QN_XML_LANG; + +extern const StaticQName QN_ENCODING; +extern const StaticQName QN_VERSION; +extern const StaticQName QN_TO; +extern const StaticQName QN_FROM; +extern const StaticQName QN_TYPE; +extern const StaticQName QN_ID; +extern const StaticQName QN_CODE; +extern const StaticQName QN_NAME; +extern const StaticQName QN_VALUE; +extern const StaticQName QN_ACTION; +extern const StaticQName QN_ORDER; +extern const StaticQName QN_MECHANISM; +extern const StaticQName QN_ASK; +extern const StaticQName QN_JID; +extern const StaticQName QN_NICK; +extern const StaticQName QN_SUBSCRIPTION; +extern const StaticQName QN_TITLE1; +extern const StaticQName QN_TITLE2; +extern const StaticQName QN_AFFILIATION; +extern const StaticQName QN_ROLE; +extern const StaticQName QN_TIME; + +extern const StaticQName QN_XMLNS_CLIENT; +extern const StaticQName QN_XMLNS_SERVER; +extern const StaticQName QN_XMLNS_STREAM; + +// Presence +extern const char STR_SHOW_AWAY[]; +extern const char STR_SHOW_CHAT[]; +extern const char STR_SHOW_DND[]; +extern const char STR_SHOW_XA[]; +extern const char STR_SHOW_OFFLINE[]; + +extern const char NS_GOOGLE_PSTN_CONFERENCE[]; +extern const StaticQName QN_GOOGLE_PSTN_CONFERENCE_STATUS; +extern const StaticQName QN_ATTR_STATUS; + +// Presence connection status +extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTING[]; +extern const char STR_PSTN_CONFERENCE_STATUS_JOINING[]; +extern const char STR_PSTN_CONFERENCE_STATUS_CONNECTED[]; +extern const char STR_PSTN_CONFERENCE_STATUS_HANGUP[]; + +// Subscription +extern const char STR_SUBSCRIBE[]; +extern const char STR_SUBSCRIBED[]; +extern const char STR_UNSUBSCRIBE[]; +extern const char STR_UNSUBSCRIBED[]; + +// Google Invite +extern const char NS_GOOGLE_SUBSCRIBE[]; +extern const StaticQName QN_INVITATION; +extern const StaticQName QN_INVITE_NAME; +extern const StaticQName QN_INVITE_SUBJECT; +extern const StaticQName QN_INVITE_MESSAGE; + +// Kick +extern const char NS_GOOGLE_MUC_ADMIN[]; +extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY; +extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM; +extern const StaticQName QN_GOOGLE_MUC_ADMIN_QUERY_ITEM_REASON; + +// PubSub: http://xmpp.org/extensions/xep-0060.html +extern const char NS_PUBSUB[]; +extern const StaticQName QN_PUBSUB; +extern const StaticQName QN_PUBSUB_ITEMS; +extern const StaticQName QN_PUBSUB_ITEM; +extern const StaticQName QN_PUBSUB_PUBLISH; +extern const StaticQName QN_PUBSUB_RETRACT; +extern const StaticQName QN_ATTR_PUBLISHER; + +extern const char NS_PUBSUB_EVENT[]; +extern const StaticQName QN_NODE; +extern const StaticQName QN_PUBSUB_EVENT; +extern const StaticQName QN_PUBSUB_EVENT_ITEMS; +extern const StaticQName QN_PUBSUB_EVENT_ITEM; +extern const StaticQName QN_PUBSUB_EVENT_RETRACT; +extern const StaticQName QN_NOTIFY; + +extern const char NS_PRESENTER[]; +extern const StaticQName QN_PRESENTER_PRESENTER; +extern const StaticQName QN_PRESENTER_PRESENTATION_ITEM; +extern const StaticQName QN_PRESENTER_PRESENTATION_TYPE; +extern const StaticQName QN_PRESENTER_PRESENTATION_ID; + +// JEP 0030 +extern const StaticQName QN_CATEGORY; +extern const StaticQName QN_VAR; +extern const char NS_DISCO_INFO[]; +extern const char NS_DISCO_ITEMS[]; + +extern const StaticQName QN_DISCO_INFO_QUERY; +extern const StaticQName QN_DISCO_IDENTITY; +extern const StaticQName QN_DISCO_FEATURE; + +extern const StaticQName QN_DISCO_ITEMS_QUERY; +extern const StaticQName QN_DISCO_ITEM; + +// JEP 0020 +extern const char NS_FEATURE[]; +extern const StaticQName QN_FEATURE_FEATURE; + +// JEP 0004 +extern const char NS_XDATA[]; +extern const StaticQName QN_XDATA_X; +extern const StaticQName QN_XDATA_INSTRUCTIONS; +extern const StaticQName QN_XDATA_TITLE; +extern const StaticQName QN_XDATA_FIELD; +extern const StaticQName QN_XDATA_REPORTED; +extern const StaticQName QN_XDATA_ITEM; +extern const StaticQName QN_XDATA_DESC; +extern const StaticQName QN_XDATA_REQUIRED; +extern const StaticQName QN_XDATA_VALUE; +extern const StaticQName QN_XDATA_OPTION; + +// JEP 0045 +extern const char NS_MUC[]; +extern const StaticQName QN_MUC_X; +extern const StaticQName QN_MUC_ITEM; +extern const StaticQName QN_MUC_AFFILIATION; +extern const StaticQName QN_MUC_ROLE; +extern const StaticQName QN_CLIENT_VERSION; +extern const StaticQName QN_LOCALE; +extern const char STR_AFFILIATION_NONE[]; +extern const char STR_ROLE_PARTICIPANT[]; + +extern const char NS_GOOGLE_SESSION[]; +extern const StaticQName QN_GOOGLE_USER_ID; +extern const StaticQName QN_GOOGLE_CIRCLE_ID; +extern const StaticQName QN_GOOGLE_SESSION_BLOCKED; +extern const StaticQName QN_GOOGLE_SESSION_BLOCKING; + +extern const char NS_MUC_OWNER[]; +extern const StaticQName QN_MUC_OWNER_QUERY; + +extern const char NS_MUC_USER[]; +extern const StaticQName QN_MUC_USER_CONTINUE; +extern const StaticQName QN_MUC_USER_X; +extern const StaticQName QN_MUC_USER_ITEM; +extern const StaticQName QN_MUC_USER_STATUS; +extern const StaticQName QN_MUC_USER_REASON; +extern const StaticQName QN_MUC_USER_ABUSE_VIOLATION; + +// JEP 0055 - Jabber Search +extern const char NS_SEARCH[]; +extern const StaticQName QN_SEARCH_QUERY; +extern const StaticQName QN_SEARCH_ITEM; +extern const StaticQName QN_SEARCH_ROOM_NAME; +extern const StaticQName QN_SEARCH_ROOM_JID; +extern const StaticQName QN_SEARCH_ROOM_DOMAIN; +extern const StaticQName QN_SEARCH_HANGOUT_ID; +extern const StaticQName QN_SEARCH_EXTERNAL_ID; + +// JEP 0115 +extern const char NS_CAPS[]; +extern const StaticQName QN_CAPS_C; +extern const StaticQName QN_VER; +extern const StaticQName QN_EXT; + + +// Avatar - JEP 0153 +extern const char kNSVCard[]; +extern const StaticQName kQnVCardX; +extern const StaticQName kQnVCardPhoto; + +// JEP 0172 User Nickname +extern const char NS_NICKNAME[]; +extern const StaticQName QN_NICKNAME; + +// JEP 0085 chat state +extern const char NS_CHATSTATE[]; +extern const StaticQName QN_CS_ACTIVE; +extern const StaticQName QN_CS_COMPOSING; +extern const StaticQName QN_CS_PAUSED; +extern const StaticQName QN_CS_INACTIVE; +extern const StaticQName QN_CS_GONE; + +// JEP 0091 Delayed Delivery +extern const char kNSDelay[]; +extern const StaticQName kQnDelayX; +extern const StaticQName kQnStamp; + +// Google time stamping (higher resolution) +extern const char kNSTimestamp[]; +extern const StaticQName kQnTime; +extern const StaticQName kQnMilliseconds; + +extern const char NS_JINGLE_INFO[]; +extern const StaticQName QN_JINGLE_INFO_QUERY; +extern const StaticQName QN_JINGLE_INFO_STUN; +extern const StaticQName QN_JINGLE_INFO_RELAY; +extern const StaticQName QN_JINGLE_INFO_SERVER; +extern const StaticQName QN_JINGLE_INFO_TOKEN; +extern const StaticQName QN_JINGLE_INFO_HOST; +extern const StaticQName QN_JINGLE_INFO_TCP; +extern const StaticQName QN_JINGLE_INFO_UDP; +extern const StaticQName QN_JINGLE_INFO_TCPSSL; + +extern const char NS_GOOGLE_CALLPERF_STATS[]; +extern const StaticQName QN_CALLPERF_STATS; +extern const StaticQName QN_CALLPERF_SESSIONID; +extern const StaticQName QN_CALLPERF_LOCALUSER; +extern const StaticQName QN_CALLPERF_REMOTEUSER; +extern const StaticQName QN_CALLPERF_STARTTIME; +extern const StaticQName QN_CALLPERF_CALL_LENGTH; +extern const StaticQName QN_CALLPERF_CALL_ACCEPTED; +extern const StaticQName QN_CALLPERF_CALL_ERROR_CODE; +extern const StaticQName QN_CALLPERF_TERMINATE_CODE; +extern const StaticQName QN_CALLPERF_DATAPOINT; +extern const StaticQName QN_CALLPERF_DATAPOINT_TIME; +extern const StaticQName QN_CALLPERF_DATAPOINT_FRACTION_LOST; +extern const StaticQName QN_CALLPERF_DATAPOINT_CUM_LOST; +extern const StaticQName QN_CALLPERF_DATAPOINT_EXT_MAX; +extern const StaticQName QN_CALLPERF_DATAPOINT_JITTER; +extern const StaticQName QN_CALLPERF_DATAPOINT_RTT; +extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_R; +extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_R; +extern const StaticQName QN_CALLPERF_DATAPOINT_BYTES_S; +extern const StaticQName QN_CALLPERF_DATAPOINT_PACKETS_S; +extern const StaticQName QN_CALLPERF_DATAPOINT_PROCESS_CPU; +extern const StaticQName QN_CALLPERF_DATAPOINT_SYSTEM_CPU; +extern const StaticQName QN_CALLPERF_DATAPOINT_CPUS; +extern const StaticQName QN_CALLPERF_CONNECTION; +extern const StaticQName QN_CALLPERF_CONNECTION_LOCAL_ADDRESS; +extern const StaticQName QN_CALLPERF_CONNECTION_REMOTE_ADDRESS; +extern const StaticQName QN_CALLPERF_CONNECTION_FLAGS; +extern const StaticQName QN_CALLPERF_CONNECTION_RTT; +extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_S; +extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_S; +extern const StaticQName QN_CALLPERF_CONNECTION_TOTAL_BYTES_R; +extern const StaticQName QN_CALLPERF_CONNECTION_BYTES_SECOND_R; +extern const StaticQName QN_CALLPERF_CANDIDATE; +extern const StaticQName QN_CALLPERF_CANDIDATE_ENDPOINT; +extern const StaticQName QN_CALLPERF_CANDIDATE_PROTOCOL; +extern const StaticQName QN_CALLPERF_CANDIDATE_ADDRESS; +extern const StaticQName QN_CALLPERF_MEDIA; +extern const StaticQName QN_CALLPERF_MEDIA_DIRECTION; +extern const StaticQName QN_CALLPERF_MEDIA_SSRC; +extern const StaticQName QN_CALLPERF_MEDIA_ENERGY; +extern const StaticQName QN_CALLPERF_MEDIA_FIR; +extern const StaticQName QN_CALLPERF_MEDIA_NACK; +extern const StaticQName QN_CALLPERF_MEDIA_FPS; +extern const StaticQName QN_CALLPERF_MEDIA_FPS_NETWORK; +extern const StaticQName QN_CALLPERF_MEDIA_FPS_DECODED; +extern const StaticQName QN_CALLPERF_MEDIA_JITTER_BUFFER_SIZE; +extern const StaticQName QN_CALLPERF_MEDIA_PREFERRED_JITTER_BUFFER_SIZE; +extern const StaticQName QN_CALLPERF_MEDIA_TOTAL_PLAYOUT_DELAY; + +// Muc invites. +extern const StaticQName QN_MUC_USER_INVITE; + +// Multiway audio/video. +extern const char NS_GOOGLE_MUC_USER[]; +extern const StaticQName QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA; +extern const StaticQName QN_GOOGLE_MUC_USER_ENTRY; +extern const StaticQName QN_GOOGLE_MUC_USER_MEDIA; +extern const StaticQName QN_GOOGLE_MUC_USER_TYPE; +extern const StaticQName QN_GOOGLE_MUC_USER_SRC_ID; +extern const StaticQName QN_GOOGLE_MUC_USER_STATUS; +extern const StaticQName QN_LABEL; + +extern const char NS_GOOGLE_MUC_MEDIA[]; +extern const StaticQName QN_GOOGLE_MUC_AUDIO_MUTE; +extern const StaticQName QN_GOOGLE_MUC_VIDEO_MUTE; +extern const StaticQName QN_GOOGLE_MUC_VIDEO_PAUSE; +extern const StaticQName QN_GOOGLE_MUC_RECORDING; +extern const StaticQName QN_GOOGLE_MUC_MEDIA_BLOCK; +extern const StaticQName QN_STATE_ATTR; + + +extern const char AUTH_MECHANISM_GOOGLE_COOKIE[]; +extern const char AUTH_MECHANISM_GOOGLE_TOKEN[]; +extern const char AUTH_MECHANISM_OAUTH2[]; +extern const char AUTH_MECHANISM_PLAIN[]; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMPP_CONSTANTS_H_
diff --git a/third_party/libjingle_xmpp/xmpp/fakexmppclient.h b/third_party/libjingle_xmpp/xmpp/fakexmppclient.h new file mode 100644 index 0000000..988fbe3 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/fakexmppclient.h
@@ -0,0 +1,107 @@ +/* + * Copyright 2011 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// A fake XmppClient for use in unit tests. + +#ifndef WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_ +#define WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_ + +#include <algorithm> +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" + +namespace buzz { + +class XmlElement; + +class FakeXmppClient : public XmppTaskParentInterface, + public XmppClientInterface { + public: + explicit FakeXmppClient(rtc::TaskParent* parent) + : XmppTaskParentInterface(parent) { + } + + // As XmppTaskParentInterface + virtual XmppClientInterface* GetClient() { + return this; + } + + virtual int ProcessStart() { + return STATE_RESPONSE; + } + + // As XmppClientInterface + virtual XmppEngine::State GetState() const { + return XmppEngine::STATE_OPEN; + } + + virtual const Jid& jid() const { + return jid_; + } + + virtual std::string NextId() { + // Implement if needed for tests. + return "0"; + } + + virtual XmppReturnStatus SendStanza(const XmlElement* stanza) { + sent_stanzas_.push_back(stanza); + return XMPP_RETURN_OK; + } + + const std::vector<const XmlElement*>& sent_stanzas() { + return sent_stanzas_; + } + + virtual XmppReturnStatus SendStanzaError( + const XmlElement * pelOriginal, + XmppStanzaError code, + const std::string & text) { + // Implement if needed for tests. + return XMPP_RETURN_OK; + } + + virtual void AddXmppTask(XmppTask* task, + XmppEngine::HandlerLevel level) { + tasks_.push_back(task); + } + + virtual void RemoveXmppTask(XmppTask* task) { + std::remove(tasks_.begin(), tasks_.end(), task); + } + + // As FakeXmppClient + void set_jid(const Jid& jid) { + jid_ = jid; + } + + // Takes ownership of stanza. + void HandleStanza(XmlElement* stanza) { + for (std::vector<XmppTask*>::iterator task = tasks_.begin(); + task != tasks_.end(); ++task) { + if ((*task)->HandleStanza(stanza)) { + delete stanza; + return; + } + } + delete stanza; + } + + private: + Jid jid_; + std::vector<XmppTask*> tasks_; + std::vector<const XmlElement*> sent_stanzas_; +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMPP_FAKEXMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/jid.cc b/third_party/libjingle_xmpp/xmpp/jid.cc new file mode 100644 index 0000000..53f7f8a --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/jid.cc
@@ -0,0 +1,379 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/jid.h" + +#include <ctype.h> + +#include <algorithm> +#include <string> + +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc_overrides/webrtc/base/logging.h" + +namespace buzz { + +Jid::Jid() { +} + +Jid::Jid(const std::string& jid_string) { + if (jid_string.empty()) + return; + + // First find the slash and slice off that part + size_t slash = jid_string.find('/'); + resource_name_ = (slash == std::string::npos ? STR_EMPTY : + jid_string.substr(slash + 1)); + + // Now look for the node + size_t at = jid_string.find('@'); + size_t domain_begin; + if (at < slash && at != std::string::npos) { + node_name_ = jid_string.substr(0, at); + domain_begin = at + 1; + } else { + domain_begin = 0; + } + + // Now take what is left as the domain + size_t domain_length = (slash == std::string::npos) ? + (jid_string.length() - domain_begin) : (slash - domain_begin); + domain_name_ = jid_string.substr(domain_begin, domain_length); + + ValidateOrReset(); +} + +Jid::Jid(const std::string& node_name, + const std::string& domain_name, + const std::string& resource_name) + : node_name_(node_name), + domain_name_(domain_name), + resource_name_(resource_name) { + ValidateOrReset(); +} + +void Jid::ValidateOrReset() { + bool valid_node; + bool valid_domain; + bool valid_resource; + + node_name_ = PrepNode(node_name_, &valid_node); + domain_name_ = PrepDomain(domain_name_, &valid_domain); + resource_name_ = PrepResource(resource_name_, &valid_resource); + + if (!valid_node || !valid_domain || !valid_resource) { + node_name_.clear(); + domain_name_.clear(); + resource_name_.clear(); + } +} + +std::string Jid::Str() const { + if (!IsValid()) + return STR_EMPTY; + + std::string ret; + + if (!node_name_.empty()) + ret = node_name_ + "@"; + + ASSERT(domain_name_ != STR_EMPTY); + ret += domain_name_; + + if (!resource_name_.empty()) + ret += "/" + resource_name_; + + return ret; +} + +Jid::~Jid() { +} + +bool Jid::IsEmpty() const { + return (node_name_.empty() && domain_name_.empty() && + resource_name_.empty()); +} + +bool Jid::IsValid() const { + return !domain_name_.empty(); +} + +bool Jid::IsBare() const { + if (IsEmpty()) { + LOG(LS_VERBOSE) << "Warning: Calling IsBare() on the empty jid."; + return true; + } + return IsValid() && resource_name_.empty(); +} + +bool Jid::IsFull() const { + return IsValid() && !resource_name_.empty(); +} + +Jid Jid::BareJid() const { + if (!IsValid()) + return Jid(); + if (!IsFull()) + return *this; + return Jid(node_name_, domain_name_, STR_EMPTY); +} + +bool Jid::BareEquals(const Jid& other) const { + return other.node_name_ == node_name_ && + other.domain_name_ == domain_name_; +} + +void Jid::CopyFrom(const Jid& jid) { + this->node_name_ = jid.node_name_; + this->domain_name_ = jid.domain_name_; + this->resource_name_ = jid.resource_name_; +} + +bool Jid::operator==(const Jid& other) const { + return other.node_name_ == node_name_ && + other.domain_name_ == domain_name_ && + other.resource_name_ == resource_name_; +} + +int Jid::Compare(const Jid& other) const { + int compare_result; + compare_result = node_name_.compare(other.node_name_); + if (0 != compare_result) + return compare_result; + compare_result = domain_name_.compare(other.domain_name_); + if (0 != compare_result) + return compare_result; + compare_result = resource_name_.compare(other.resource_name_); + return compare_result; +} + +// --- JID parsing code: --- + +// Checks and normalizes the node part of a JID. +std::string Jid::PrepNode(const std::string& node, bool* valid) { + *valid = false; + std::string result; + + for (std::string::const_iterator i = node.begin(); i < node.end(); ++i) { + bool char_valid = true; + unsigned char ch = *i; + if (ch <= 0x7F) { + result += PrepNodeAscii(ch, &char_valid); + } + else { + // TODO: implement the correct stringprep protocol for these + result += tolower(ch); + } + if (!char_valid) { + return STR_EMPTY; + } + } + + if (result.length() > 1023) { + return STR_EMPTY; + } + *valid = true; + return result; +} + + +// Returns the appropriate mapping for an ASCII character in a node. +char Jid::PrepNodeAscii(char ch, bool* valid) { + *valid = true; + switch (ch) { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': + case 'V': case 'W': case 'X': case 'Y': case 'Z': + return (char)(ch + ('a' - 'A')); + + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: + case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: + case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case ' ': case '&': case '/': case ':': case '<': case '>': case '@': + case '\"': case '\'': + case 0x7F: + *valid = false; + return 0; + + default: + return ch; + } +} + + +// Checks and normalizes the resource part of a JID. +std::string Jid::PrepResource(const std::string& resource, bool* valid) { + *valid = false; + std::string result; + + for (std::string::const_iterator i = resource.begin(); + i < resource.end(); ++i) { + bool char_valid = true; + unsigned char ch = *i; + if (ch <= 0x7F) { + result += PrepResourceAscii(ch, &char_valid); + } + else { + // TODO: implement the correct stringprep protocol for these + result += ch; + } + } + + if (result.length() > 1023) { + return STR_EMPTY; + } + *valid = true; + return result; +} + +// Returns the appropriate mapping for an ASCII character in a resource. +char Jid::PrepResourceAscii(char ch, bool* valid) { + *valid = true; + switch (ch) { + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: + case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: + case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x7F: + *valid = false; + return 0; + + default: + return ch; + } +} + +// Checks and normalizes the domain part of a JID. +std::string Jid::PrepDomain(const std::string& domain, bool* valid) { + *valid = false; + std::string result; + + // TODO: if the domain contains a ':', then we should parse it + // as an IPv6 address rather than giving an error about illegal domain. + PrepDomain(domain, &result, valid); + if (!*valid) { + return STR_EMPTY; + } + + if (result.length() > 1023) { + return STR_EMPTY; + } + *valid = true; + return result; +} + + +// Checks and normalizes an IDNA domain. +void Jid::PrepDomain(const std::string& domain, std::string* buf, bool* valid) { + *valid = false; + std::string::const_iterator last = domain.begin(); + for (std::string::const_iterator i = domain.begin(); i < domain.end(); ++i) { + bool label_valid = true; + char ch = *i; + switch (ch) { + case 0x002E: +#if 0 // FIX: This isn't UTF-8-aware. + case 0x3002: + case 0xFF0E: + case 0xFF61: +#endif + PrepDomainLabel(last, i, buf, &label_valid); + *buf += '.'; + last = i + 1; + break; + } + if (!label_valid) { + return; + } + } + PrepDomainLabel(last, domain.end(), buf, valid); +} + +// Checks and normalizes a domain label. +void Jid::PrepDomainLabel( + std::string::const_iterator start, std::string::const_iterator end, + std::string* buf, bool* valid) { + *valid = false; + + int start_len = static_cast<int>(buf->length()); + for (std::string::const_iterator i = start; i < end; ++i) { + bool char_valid = true; + unsigned char ch = *i; + if (ch <= 0x7F) { + *buf += PrepDomainLabelAscii(ch, &char_valid); + } + else { + // TODO: implement ToASCII for these + *buf += ch; + } + if (!char_valid) { + return; + } + } + + int count = static_cast<int>(buf->length() - start_len); + if (count == 0) { + return; + } + else if (count > 63) { + return; + } + + // Is this check needed? See comment in PrepDomainLabelAscii. + if ((*buf)[start_len] == '-') { + return; + } + if ((*buf)[buf->length() - 1] == '-') { + return; + } + *valid = true; +} + + +// Returns the appropriate mapping for an ASCII character in a domain label. +char Jid::PrepDomainLabelAscii(char ch, bool* valid) { + *valid = true; + // TODO: A literal reading of the spec seems to say that we do + // not need to check for these illegal characters (an "internationalized + // domain label" runs ToASCII with UseSTD3... set to false). But that + // can't be right. We should at least be checking that there are no '/' + // or '@' characters in the domain. Perhaps we should see what others + // do in this case. + + switch (ch) { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': + case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': + case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': + case 'V': case 'W': case 'X': case 'Y': case 'Z': + return (char)(ch + ('a' - 'A')); + + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: + case 0x06: case 0x07: case 0x08: case 0x09: case 0x0A: case 0x0B: + case 0x0C: case 0x0D: case 0x0E: case 0x0F: case 0x10: case 0x11: + case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: + case 0x1E: case 0x1F: case 0x20: case 0x21: case 0x22: case 0x23: + case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: + case 0x2A: case 0x2B: case 0x2C: case 0x2E: case 0x2F: case 0x3A: + case 0x3B: case 0x3C: case 0x3D: case 0x3E: case 0x3F: case 0x40: + case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: case 0x60: + case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: + *valid = false; + return 0; + + default: + return ch; + } +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmpp/jid.h b/third_party/libjingle_xmpp/xmpp/jid.h new file mode 100644 index 0000000..5443b05 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/jid.h
@@ -0,0 +1,80 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_JID_H_ +#define WEBRTC_LIBJINGLE_XMPP_JID_H_ + +#include <string> +#include "third_party/libjingle_xmpp/xmllite/xmlconstants.h" + +namespace buzz { + +// The Jid class encapsulates and provides parsing help for Jids. A Jid +// consists of three parts: the node, the domain and the resource, e.g.: +// +// node@domain/resource +// +// The node and resource are both optional. A valid jid is defined to have +// a domain. A bare jid is defined to not have a resource and a full jid +// *does* have a resource. +class Jid { +public: + explicit Jid(); + explicit Jid(const std::string& jid_string); + explicit Jid(const std::string& node_name, + const std::string& domain_name, + const std::string& resource_name); + ~Jid(); + + const std::string & node() const { return node_name_; } + const std::string & domain() const { return domain_name_; } + const std::string & resource() const { return resource_name_; } + + std::string Str() const; + Jid BareJid() const; + + bool IsEmpty() const; + bool IsValid() const; + bool IsBare() const; + bool IsFull() const; + + bool BareEquals(const Jid& other) const; + void CopyFrom(const Jid& jid); + bool operator==(const Jid& other) const; + bool operator!=(const Jid& other) const { return !operator==(other); } + + bool operator<(const Jid& other) const { return Compare(other) < 0; }; + bool operator>(const Jid& other) const { return Compare(other) > 0; }; + + int Compare(const Jid & other) const; + +private: + void ValidateOrReset(); + + static std::string PrepNode(const std::string& node, bool* valid); + static char PrepNodeAscii(char ch, bool* valid); + static std::string PrepResource(const std::string& start, bool* valid); + static char PrepResourceAscii(char ch, bool* valid); + static std::string PrepDomain(const std::string& domain, bool* valid); + static void PrepDomain(const std::string& domain, + std::string* buf, bool* valid); + static void PrepDomainLabel( + std::string::const_iterator start, std::string::const_iterator end, + std::string* buf, bool* valid); + static char PrepDomainLabelAscii(char ch, bool *valid); + + std::string node_name_; + std::string domain_name_; + std::string resource_name_; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_JID_H_
diff --git a/third_party/libjingle_xmpp/xmpp/jid_unittest.cc b/third_party/libjingle_xmpp/xmpp/jid_unittest.cc new file mode 100644 index 0000000..2fd5ded --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/jid_unittest.cc
@@ -0,0 +1,122 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/jid.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::Jid; + +TEST(JidTest, TestDomain) { + Jid jid("dude"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("dude", jid.domain()); + EXPECT_EQ("", jid.resource()); + EXPECT_EQ("dude", jid.Str()); + EXPECT_EQ("dude", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_TRUE(jid.IsBare()); + EXPECT_FALSE(jid.IsFull()); +} + +TEST(JidTest, TestNodeDomain) { + Jid jid("walter@dude"); + EXPECT_EQ("walter", jid.node()); + EXPECT_EQ("dude", jid.domain()); + EXPECT_EQ("", jid.resource()); + EXPECT_EQ("walter@dude", jid.Str()); + EXPECT_EQ("walter@dude", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_TRUE(jid.IsBare()); + EXPECT_FALSE(jid.IsFull()); +} + +TEST(JidTest, TestDomainResource) { + Jid jid("dude/bowlingalley"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("dude", jid.domain()); + EXPECT_EQ("bowlingalley", jid.resource()); + EXPECT_EQ("dude/bowlingalley", jid.Str()); + EXPECT_EQ("dude", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_FALSE(jid.IsBare()); + EXPECT_TRUE(jid.IsFull()); +} + +TEST(JidTest, TestNodeDomainResource) { + Jid jid("walter@dude/bowlingalley"); + EXPECT_EQ("walter", jid.node()); + EXPECT_EQ("dude", jid.domain()); + EXPECT_EQ("bowlingalley", jid.resource()); + EXPECT_EQ("walter@dude/bowlingalley", jid.Str()); + EXPECT_EQ("walter@dude", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_FALSE(jid.IsBare()); + EXPECT_TRUE(jid.IsFull()); +} + +TEST(JidTest, TestNode) { + Jid jid("walter@"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("", jid.domain()); + EXPECT_EQ("", jid.resource()); + EXPECT_EQ("", jid.Str()); + EXPECT_EQ("", jid.BareJid().Str()); + EXPECT_FALSE(jid.IsValid()); + EXPECT_TRUE(jid.IsBare()); + EXPECT_FALSE(jid.IsFull()); +} + +TEST(JidTest, TestResource) { + Jid jid("/bowlingalley"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("", jid.domain()); + EXPECT_EQ("", jid.resource()); + EXPECT_EQ("", jid.Str()); + EXPECT_EQ("", jid.BareJid().Str()); + EXPECT_FALSE(jid.IsValid()); + EXPECT_TRUE(jid.IsBare()); + EXPECT_FALSE(jid.IsFull()); +} + +TEST(JidTest, TestNodeResource) { + Jid jid("walter@/bowlingalley"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("", jid.domain()); + EXPECT_EQ("", jid.resource()); + EXPECT_EQ("", jid.Str()); + EXPECT_EQ("", jid.BareJid().Str()); + EXPECT_FALSE(jid.IsValid()); + EXPECT_TRUE(jid.IsBare()); + EXPECT_FALSE(jid.IsFull()); +} + +TEST(JidTest, TestFunky) { + Jid jid("bowling@muchat/walter@dude"); + EXPECT_EQ("bowling", jid.node()); + EXPECT_EQ("muchat", jid.domain()); + EXPECT_EQ("walter@dude", jid.resource()); + EXPECT_EQ("bowling@muchat/walter@dude", jid.Str()); + EXPECT_EQ("bowling@muchat", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_FALSE(jid.IsBare()); + EXPECT_TRUE(jid.IsFull()); +} + +TEST(JidTest, TestFunky2) { + Jid jid("muchat/walter@dude"); + EXPECT_EQ("", jid.node()); + EXPECT_EQ("muchat", jid.domain()); + EXPECT_EQ("walter@dude", jid.resource()); + EXPECT_EQ("muchat/walter@dude", jid.Str()); + EXPECT_EQ("muchat", jid.BareJid().Str()); + EXPECT_TRUE(jid.IsValid()); + EXPECT_FALSE(jid.IsBare()); + EXPECT_TRUE(jid.IsFull()); +}
diff --git a/third_party/libjingle_xmpp/xmpp/jingleinfotask.cc b/third_party/libjingle_xmpp/xmpp/jingleinfotask.cc new file mode 100644 index 0000000..ccad354b --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/jingleinfotask.cc
@@ -0,0 +1,115 @@ +/* + * Copyright 2010 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/jingleinfotask.h" + +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" +#include "third_party/webrtc/base/socketaddress.h" + +namespace buzz { + +class JingleInfoTask::JingleInfoGetTask : public XmppTask { + public: + explicit JingleInfoGetTask(XmppTaskParentInterface* parent) + : XmppTask(parent, XmppEngine::HL_SINGLE), done_(false) {} + + virtual int ProcessStart() { + rtc::scoped_ptr<XmlElement> get(MakeIq(STR_GET, Jid(), task_id())); + get->AddElement(new XmlElement(QN_JINGLE_INFO_QUERY, true)); + if (SendStanza(get.get()) != XMPP_RETURN_OK) { + return STATE_ERROR; + } + return STATE_RESPONSE; + } + virtual int ProcessResponse() { + if (done_) + return STATE_DONE; + return STATE_BLOCKED; + } + + protected: + virtual bool HandleStanza(const XmlElement* stanza) { + if (!MatchResponseIq(stanza, Jid(), task_id())) + return false; + + if (stanza->Attr(QN_TYPE) != STR_RESULT) + return false; + + // Queue the stanza with the parent so these don't get handled out of order + JingleInfoTask* parent = static_cast<JingleInfoTask*>(GetParent()); + parent->QueueStanza(stanza); + + // Wake ourselves so we can go into the done state + done_ = true; + Wake(); + return true; + } + + bool done_; +}; + +void JingleInfoTask::RefreshJingleInfoNow() { + JingleInfoGetTask* get_task = new JingleInfoGetTask(this); + get_task->Start(); +} + +bool JingleInfoTask::HandleStanza(const XmlElement* stanza) { + if (!MatchRequestIq(stanza, "set", QN_JINGLE_INFO_QUERY)) + return false; + + // only respect relay push from the server + Jid from(stanza->Attr(QN_FROM)); + if (!from.IsEmpty() && !from.BareEquals(GetClient()->jid()) && + from != Jid(GetClient()->jid().domain())) + return false; + + QueueStanza(stanza); + return true; +} + +int JingleInfoTask::ProcessStart() { + std::vector<std::string> relay_hosts; + std::vector<rtc::SocketAddress> stun_hosts; + std::string relay_token; + const XmlElement* stanza = NextStanza(); + if (stanza == NULL) + return STATE_BLOCKED; + const XmlElement* query = stanza->FirstNamed(QN_JINGLE_INFO_QUERY); + if (query == NULL) + return STATE_START; + const XmlElement* stun = query->FirstNamed(QN_JINGLE_INFO_STUN); + if (stun) { + for (const XmlElement* server = stun->FirstNamed(QN_JINGLE_INFO_SERVER); + server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) { + std::string host = server->Attr(QN_JINGLE_INFO_HOST); + std::string port = server->Attr(QN_JINGLE_INFO_UDP); + if (host != STR_EMPTY && host != STR_EMPTY) { + stun_hosts.push_back(rtc::SocketAddress(host, atoi(port.c_str()))); + } + } + } + + const XmlElement* relay = query->FirstNamed(QN_JINGLE_INFO_RELAY); + if (relay) { + relay_token = relay->TextNamed(QN_JINGLE_INFO_TOKEN); + for (const XmlElement* server = relay->FirstNamed(QN_JINGLE_INFO_SERVER); + server != NULL; server = server->NextNamed(QN_JINGLE_INFO_SERVER)) { + std::string host = server->Attr(QN_JINGLE_INFO_HOST); + if (host != STR_EMPTY) { + relay_hosts.push_back(host); + } + } + } + SignalJingleInfo(relay_token, relay_hosts, stun_hosts); + return STATE_START; +} +}
diff --git a/third_party/libjingle_xmpp/xmpp/jingleinfotask.h b/third_party/libjingle_xmpp/xmpp/jingleinfotask.h new file mode 100644 index 0000000..da1fa9a81 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/jingleinfotask.h
@@ -0,0 +1,44 @@ +/* + * Copyright 2010 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef THIRD_PARTY_XMPP_JINGLEINFOTASK_H_ +#define THIRD_PARTY_XMPP_JINGLEINFOTASK_H_ + +#include <vector> + +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" +#include "third_party/webrtc/base/sigslot.h" +#include "third_party/webrtc/p2p/client/httpportallocator.h" + +namespace buzz { + +class JingleInfoTask : public XmppTask { + public: + explicit JingleInfoTask(XmppTaskParentInterface* parent) + : XmppTask(parent, XmppEngine::HL_TYPE) {} + + virtual int ProcessStart(); + void RefreshJingleInfoNow(); + + sigslot::signal3<const std::string&, + const std::vector<std::string>&, + const std::vector<rtc::SocketAddress>&> + SignalJingleInfo; + + protected: + class JingleInfoGetTask; + friend class JingleInfoGetTask; + + virtual bool HandleStanza(const XmlElement* stanza); +}; +} + +#endif // THIRD_PARTY_XMPP_JINGLEINFOTASK_H_
diff --git a/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h b/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h new file mode 100644 index 0000000..894570e9 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/plainsaslhandler.h
@@ -0,0 +1,64 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_ +#define WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_ + +#include <algorithm> +#include "third_party/libjingle_xmpp/xmpp/saslhandler.h" +#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" +#include "third_party/webrtc/base/cryptstring.h" + +namespace buzz { + +class PlainSaslHandler : public SaslHandler { +public: + PlainSaslHandler(const Jid & jid, const rtc::CryptString & password, + bool allow_plain) : jid_(jid), password_(password), + allow_plain_(allow_plain) {} + + virtual ~PlainSaslHandler() {} + + // Should pick the best method according to this handler + // returns the empty string if none are suitable + virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) { + + if (!encrypted && !allow_plain_) { + return ""; + } + + std::vector<std::string>::const_iterator it = std::find(mechanisms.begin(), mechanisms.end(), "PLAIN"); + if (it == mechanisms.end()) { + return ""; + } + else { + return "PLAIN"; + } + } + + // Creates a SaslMechanism for the given mechanism name (you own it + // once you get it). If not handled, return NULL. + virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) { + if (mechanism == "PLAIN") { + return new SaslPlainMechanism(jid_, password_); + } + return NULL; + } + +private: + Jid jid_; + rtc::CryptString password_; + bool allow_plain_; +}; + + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_PLAINSASLHANDLER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/prexmppauth.h b/third_party/libjingle_xmpp/xmpp/prexmppauth.h new file mode 100644 index 0000000..92cb6db --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/prexmppauth.h
@@ -0,0 +1,71 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_ +#define WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_ + +#include "third_party/libjingle_xmpp/xmpp/saslhandler.h" +#include "third_party/webrtc/base/cryptstring.h" +#include "third_party/webrtc/base/sigslot.h" + +namespace rtc { + class SocketAddress; +} + +namespace buzz { + +class Jid; +class SaslMechanism; + +class CaptchaChallenge { + public: + CaptchaChallenge() : captcha_needed_(false) {} + CaptchaChallenge(const std::string& token, const std::string& url) + : captcha_needed_(true), captcha_token_(token), captcha_image_url_(url) { + } + + bool captcha_needed() const { return captcha_needed_; } + const std::string& captcha_token() const { return captcha_token_; } + + // This url is relative to the gaia server. Once we have better tools + // for cracking URLs, we should probably make this a full URL + const std::string& captcha_image_url() const { return captcha_image_url_; } + + private: + bool captcha_needed_; + std::string captcha_token_; + std::string captcha_image_url_; +}; + +class PreXmppAuth : public SaslHandler { +public: + virtual ~PreXmppAuth() {} + + virtual void StartPreXmppAuth( + const Jid& jid, + const rtc::SocketAddress& server, + const rtc::CryptString& pass, + const std::string& auth_mechanism, + const std::string& auth_token) = 0; + + sigslot::signal0<> SignalAuthDone; + + virtual bool IsAuthDone() const = 0; + virtual bool IsAuthorized() const = 0; + virtual bool HadError() const = 0; + virtual int GetError() const = 0; + virtual CaptchaChallenge GetCaptchaChallenge() const = 0; + virtual std::string GetAuthMechanism() const = 0; + virtual std::string GetAuthToken() const = 0; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_PREXMPPAUTH_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h b/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h new file mode 100644 index 0000000..83442b95 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/saslcookiemechanism.h
@@ -0,0 +1,69 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_ +#define WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_ + +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h" + +namespace buzz { + +class SaslCookieMechanism : public SaslMechanism { + +public: + SaslCookieMechanism(const std::string & mechanism, + const std::string & username, + const std::string & cookie, + const std::string & token_service) + : mechanism_(mechanism), + username_(username), + cookie_(cookie), + token_service_(token_service) {} + + SaslCookieMechanism(const std::string & mechanism, + const std::string & username, + const std::string & cookie) + : mechanism_(mechanism), + username_(username), + cookie_(cookie), + token_service_("") {} + + virtual std::string GetMechanismName() { return mechanism_; } + + virtual XmlElement * StartSaslAuth() { + // send initial request + XmlElement * el = new XmlElement(QN_SASL_AUTH, true); + el->AddAttr(QN_MECHANISM, mechanism_); + if (!token_service_.empty()) { + el->AddAttr(QN_GOOGLE_AUTH_SERVICE, token_service_); + } + + std::string credential; + credential.append("\0", 1); + credential.append(username_); + credential.append("\0", 1); + credential.append(cookie_); + el->AddText(Base64Encode(credential)); + return el; + } + +private: + std::string mechanism_; + std::string username_; + std::string cookie_; + std::string token_service_; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_SASLCOOKIEMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslhandler.h b/third_party/libjingle_xmpp/xmpp/saslhandler.h new file mode 100644 index 0000000..0dccf41 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/saslhandler.h
@@ -0,0 +1,42 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_ +#define WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_ + +#include <string> +#include <vector> + +namespace buzz { + +class XmlElement; +class SaslMechanism; + +// Creates mechanisms to deal with a given mechanism +class SaslHandler { + +public: + + // Intended to be subclassed + virtual ~SaslHandler() {} + + // Should pick the best method according to this handler + // returns the empty string if none are suitable + virtual std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) = 0; + + // Creates a SaslMechanism for the given mechanism name (you own it + // once you get it). + // If not handled, return NULL. + virtual SaslMechanism * CreateSaslMechanism(const std::string & mechanism) = 0; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_SASLHANDLER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslmechanism.cc b/third_party/libjingle_xmpp/xmpp/saslmechanism.cc new file mode 100644 index 0000000..30ac9c77 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/saslmechanism.cc
@@ -0,0 +1,55 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h" +#include "third_party/webrtc/base/base64.h" + +using rtc::Base64; + +namespace buzz { + +XmlElement * +SaslMechanism::StartSaslAuth() { + return new XmlElement(QN_SASL_AUTH, true); +} + +XmlElement * +SaslMechanism::HandleSaslChallenge(const XmlElement * challenge) { + return new XmlElement(QN_SASL_ABORT, true); +} + +void +SaslMechanism::HandleSaslSuccess(const XmlElement * success) { +} + +void +SaslMechanism::HandleSaslFailure(const XmlElement * failure) { +} + +std::string +SaslMechanism::Base64Encode(const std::string & plain) { + return Base64::Encode(plain); +} + +std::string +SaslMechanism::Base64Decode(const std::string & encoded) { + return Base64::Decode(encoded, Base64::DO_LAX); +} + +std::string +SaslMechanism::Base64EncodeFromArray(const char * plain, size_t length) { + std::string result; + Base64::EncodeFromArray(plain, length, &result); + return result; +} + +}
diff --git a/third_party/libjingle_xmpp/xmpp/saslmechanism.h b/third_party/libjingle_xmpp/xmpp/saslmechanism.h new file mode 100644 index 0000000..14b93df --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/saslmechanism.h
@@ -0,0 +1,57 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_ +#define WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_ + +#include <string> + +namespace buzz { + +class XmlElement; + + +// Defines a mechnanism to do SASL authentication. +// Subclass instances should have a self-contained way to present +// credentials. +class SaslMechanism { + +public: + + // Intended to be subclassed + virtual ~SaslMechanism() {} + + // Should return the name of the SASL mechanism, e.g., "PLAIN" + virtual std::string GetMechanismName() = 0; + + // Should generate the initial "auth" request. Default is just <auth/>. + virtual XmlElement * StartSaslAuth(); + + // Should respond to a SASL "<challenge>" request. Default is + // to abort (for mechanisms that do not do challenge-response) + virtual XmlElement * HandleSaslChallenge(const XmlElement * challenge); + + // Notification of a SASL "<success>". Sometimes information + // is passed on success. + virtual void HandleSaslSuccess(const XmlElement * success); + + // Notification of a SASL "<failure>". Sometimes information + // for the user is passed on failure. + virtual void HandleSaslFailure(const XmlElement * failure); + +protected: + static std::string Base64Encode(const std::string & plain); + static std::string Base64Decode(const std::string & encoded); + static std::string Base64EncodeFromArray(const char * plain, size_t length); +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_SASLMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h b/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h new file mode 100644 index 0000000..b173c52 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/saslplainmechanism.h
@@ -0,0 +1,48 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_ +#define WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_ + +#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h" +#include "third_party/webrtc/base/cryptstring.h" + +namespace buzz { + +class SaslPlainMechanism : public SaslMechanism { + +public: + SaslPlainMechanism(const buzz::Jid user_jid, const rtc::CryptString & password) : + user_jid_(user_jid), password_(password) {} + + virtual std::string GetMechanismName() { return "PLAIN"; } + + virtual XmlElement * StartSaslAuth() { + // send initial request + XmlElement * el = new XmlElement(QN_SASL_AUTH, true); + el->AddAttr(QN_MECHANISM, "PLAIN"); + + rtc::FormatCryptString credential; + credential.Append("\0", 1); + credential.Append(user_jid_.node()); + credential.Append("\0", 1); + credential.Append(&password_); + el->AddText(Base64EncodeFromArray(credential.GetData(), credential.GetLength())); + return el; + } + +private: + Jid user_jid_; + rtc::CryptString password_; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_SASLPLAINMECHANISM_H_
diff --git a/third_party/libjingle_xmpp/xmpp/util_unittest.cc b/third_party/libjingle_xmpp/xmpp/util_unittest.cc new file mode 100644 index 0000000..bd2b349 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/util_unittest.cc
@@ -0,0 +1,109 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/util_unittest.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc/base/gunit.h" + +namespace buzz { + +void XmppTestHandler::WriteOutput(const char * bytes, size_t len) { + output_ << std::string(bytes, len); +} + +void XmppTestHandler::StartTls(const std::string & cname) { + output_ << "[START-TLS " << cname << "]"; +} + +void XmppTestHandler::CloseConnection() { + output_ << "[CLOSED]"; +} + +void XmppTestHandler::OnStateChange(int state) { + switch (static_cast<XmppEngine::State>(state)) { + case XmppEngine::STATE_START: + session_ << "[START]"; + break; + case XmppEngine::STATE_OPENING: + session_ << "[OPENING]"; + break; + case XmppEngine::STATE_OPEN: + session_ << "[OPEN]"; + break; + case XmppEngine::STATE_CLOSED: + session_ << "[CLOSED]"; + switch (engine_->GetError(NULL)) { + case XmppEngine::ERROR_NONE: + // do nothing + break; + case XmppEngine::ERROR_XML: + session_ << "[ERROR-XML]"; + break; + case XmppEngine::ERROR_STREAM: + session_ << "[ERROR-STREAM]"; + break; + case XmppEngine::ERROR_VERSION: + session_ << "[ERROR-VERSION]"; + break; + case XmppEngine::ERROR_UNAUTHORIZED: + session_ << "[ERROR-UNAUTHORIZED]"; + break; + case XmppEngine::ERROR_TLS: + session_ << "[ERROR-TLS]"; + break; + case XmppEngine::ERROR_AUTH: + session_ << "[ERROR-AUTH]"; + break; + case XmppEngine::ERROR_BIND: + session_ << "[ERROR-BIND]"; + break; + case XmppEngine::ERROR_CONNECTION_CLOSED: + session_ << "[ERROR-CONNECTION-CLOSED]"; + break; + case XmppEngine::ERROR_DOCUMENT_CLOSED: + session_ << "[ERROR-DOCUMENT-CLOSED]"; + break; + default: + break; + } + break; + default: + break; + } +} + +bool XmppTestHandler::HandleStanza(const XmlElement * stanza) { + stanza_ << stanza->Str(); + return true; +} + +std::string XmppTestHandler::OutputActivity() { + std::string result = output_.str(); + output_.str(""); + return result; +} + +std::string XmppTestHandler::SessionActivity() { + std::string result = session_.str(); + session_.str(""); + return result; +} + +std::string XmppTestHandler::StanzaActivity() { + std::string result = stanza_.str(); + stanza_.str(""); + return result; +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmpp/util_unittest.h b/third_party/libjingle_xmpp/xmpp/util_unittest.h new file mode 100644 index 0000000..c0f796aa --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/util_unittest.h
@@ -0,0 +1,58 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_ +#define WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_ + +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" + +namespace buzz { + +// This class captures callbacks from engine. +class XmppTestHandler : public XmppOutputHandler, public XmppSessionHandler, + public XmppStanzaHandler { + public: + explicit XmppTestHandler(XmppEngine* engine) : engine_(engine) {} + virtual ~XmppTestHandler() {} + + void SetEngine(XmppEngine* engine); + + // Output handler + virtual void WriteOutput(const char * bytes, size_t len); + virtual void StartTls(const std::string & cname); + virtual void CloseConnection(); + + // Session handler + virtual void OnStateChange(int state); + + // Stanza handler + virtual bool HandleStanza(const XmlElement* stanza); + + std::string OutputActivity(); + std::string SessionActivity(); + std::string StanzaActivity(); + + private: + XmppEngine* engine_; + std::stringstream output_; + std::stringstream session_; + std::stringstream stanza_; +}; + +} // namespace buzz + +inline std::ostream& operator<<(std::ostream& os, const buzz::Jid& jid) { + os << jid.Str(); + return os; +} + +#endif // WEBRTC_LIBJINGLE_XMPP_UTIL_UNITTEST_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclient.cc b/third_party/libjingle_xmpp/xmpp/xmppclient.cc new file mode 100644 index 0000000..c8b0265 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppclient.cc
@@ -0,0 +1,423 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" + +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h" +#include "third_party/libjingle_xmpp/xmpp/prexmppauth.h" +#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" +#include "third_party/webrtc/base/sigslot.h" +#include "third_party/webrtc/base/stringutils.h" +#include "third_party/webrtc_overrides/webrtc/base/logging.h" +#include "xmpptask.h" + +namespace buzz { + +class XmppClient::Private : + public sigslot::has_slots<>, + public XmppSessionHandler, + public XmppOutputHandler { +public: + + explicit Private(XmppClient* client) : + client_(client), + socket_(), + engine_(), + proxy_port_(0), + pre_engine_error_(XmppEngine::ERROR_NONE), + pre_engine_subcode_(0), + signal_closed_(false), + allow_plain_(false) {} + + virtual ~Private() { + // We need to disconnect from socket_ before engine_ is destructed (by + // the auto-generated destructor code). + ResetSocket(); + } + + // the owner + XmppClient* const client_; + + // the two main objects + std::unique_ptr<AsyncSocket> socket_; + std::unique_ptr<XmppEngine> engine_; + std::unique_ptr<PreXmppAuth> pre_auth_; + rtc::CryptString pass_; + std::string auth_mechanism_; + std::string auth_token_; + rtc::SocketAddress server_; + std::string proxy_host_; + int proxy_port_; + XmppEngine::Error pre_engine_error_; + int pre_engine_subcode_; + CaptchaChallenge captcha_challenge_; + bool signal_closed_; + bool allow_plain_; + + void ResetSocket() { + if (socket_) { + socket_->SignalConnected.disconnect(this); + socket_->SignalRead.disconnect(this); + socket_->SignalClosed.disconnect(this); + socket_.reset(NULL); + } + } + + // implementations of interfaces + void OnStateChange(int state); + void WriteOutput(const char* bytes, size_t len); + void StartTls(const std::string& domainname); + void CloseConnection(); + + // slots for socket signals + void OnSocketConnected(); + void OnSocketRead(); + void OnSocketClosed(); +}; + +bool IsTestServer(const std::string& server_name, + const std::string& test_server_domain) { + return (!test_server_domain.empty() && + rtc::ends_with(server_name.c_str(), + test_server_domain.c_str())); +} + +XmppReturnStatus XmppClient::Connect( + const XmppClientSettings& settings, + const std::string& lang, AsyncSocket* socket, PreXmppAuth* pre_auth) { + if (socket == NULL) + return XMPP_RETURN_BADARGUMENT; + if (d_->socket_) + return XMPP_RETURN_BADSTATE; + + d_->socket_.reset(socket); + + d_->socket_->SignalConnected.connect(d_.get(), &Private::OnSocketConnected); + d_->socket_->SignalRead.connect(d_.get(), &Private::OnSocketRead); + d_->socket_->SignalClosed.connect(d_.get(), &Private::OnSocketClosed); + + d_->engine_.reset(XmppEngine::Create()); + d_->engine_->SetSessionHandler(d_.get()); + d_->engine_->SetOutputHandler(d_.get()); + if (!settings.resource().empty()) { + d_->engine_->SetRequestedResource(settings.resource()); + } + d_->engine_->SetTls(settings.use_tls()); + + // The talk.google.com server returns a certificate with common-name: + // CN="gmail.com" for @gmail.com accounts, + // CN="googlemail.com" for @googlemail.com accounts, + // CN="talk.google.com" for other accounts (such as @example.com), + // so we tweak the tls server setting for those other accounts to match the + // returned certificate CN of "talk.google.com". + // For other servers, we leave the strings empty, which causes the jid's + // domain to be used. We do the same for gmail.com and googlemail.com as the + // returned CN matches the account domain in those cases. + std::string server_name = settings.server().HostAsURIString(); + if (server_name == buzz::STR_TALK_GOOGLE_COM || + server_name == buzz::STR_TALKX_L_GOOGLE_COM || + server_name == buzz::STR_XMPP_GOOGLE_COM || + server_name == buzz::STR_XMPPX_L_GOOGLE_COM || + IsTestServer(server_name, settings.test_server_domain())) { + if (settings.host() != STR_GMAIL_COM && + settings.host() != STR_GOOGLEMAIL_COM) { + d_->engine_->SetTlsServer("", STR_TALK_GOOGLE_COM); + } + } + + // Set language + d_->engine_->SetLanguage(lang); + + d_->engine_->SetUser(buzz::Jid(settings.user(), settings.host(), STR_EMPTY)); + + d_->pass_ = settings.pass(); + d_->auth_mechanism_ = settings.auth_mechanism(); + d_->auth_token_ = settings.auth_token(); + d_->server_ = settings.server(); + d_->proxy_host_ = settings.proxy_host(); + d_->proxy_port_ = settings.proxy_port(); + d_->allow_plain_ = settings.allow_plain(); + d_->pre_auth_.reset(pre_auth); + + return XMPP_RETURN_OK; +} + +XmppEngine::State XmppClient::GetState() const { + if (!d_->engine_) + return XmppEngine::STATE_NONE; + return d_->engine_->GetState(); +} + +XmppEngine::Error XmppClient::GetError(int* subcode) { + if (subcode) { + *subcode = 0; + } + if (!d_->engine_) + return XmppEngine::ERROR_NONE; + if (d_->pre_engine_error_ != XmppEngine::ERROR_NONE) { + if (subcode) { + *subcode = d_->pre_engine_subcode_; + } + return d_->pre_engine_error_; + } + return d_->engine_->GetError(subcode); +} + +const XmlElement* XmppClient::GetStreamError() { + if (!d_->engine_) { + return NULL; + } + return d_->engine_->GetStreamError(); +} + +CaptchaChallenge XmppClient::GetCaptchaChallenge() { + if (!d_->engine_) + return CaptchaChallenge(); + return d_->captcha_challenge_; +} + +std::string XmppClient::GetAuthMechanism() { + if (!d_->engine_) + return ""; + return d_->auth_mechanism_; +} + +std::string XmppClient::GetAuthToken() { + if (!d_->engine_) + return ""; + return d_->auth_token_; +} + +int XmppClient::ProcessStart() { + // Should not happen, but was observed in crash reports + if (!d_->socket_) { + LOG(LS_ERROR) << "socket_ already reset"; + return STATE_DONE; + } + + if (d_->pre_auth_) { + d_->pre_auth_->SignalAuthDone.connect(this, &XmppClient::OnAuthDone); + d_->pre_auth_->StartPreXmppAuth( + d_->engine_->GetUser(), d_->server_, d_->pass_, + d_->auth_mechanism_, d_->auth_token_); + d_->pass_.Clear(); // done with this; + return STATE_PRE_XMPP_LOGIN; + } + else { + d_->engine_->SetSaslHandler(new PlainSaslHandler( + d_->engine_->GetUser(), d_->pass_, d_->allow_plain_)); + d_->pass_.Clear(); // done with this; + return STATE_START_XMPP_LOGIN; + } +} + +void XmppClient::OnAuthDone() { + Wake(); +} + +int XmppClient::ProcessTokenLogin() { + // Should not happen, but was observed in crash reports + if (!d_->socket_) { + LOG(LS_ERROR) << "socket_ already reset"; + return STATE_DONE; + } + + // Don't know how this could happen, but crash reports show it as NULL + if (!d_->pre_auth_) { + d_->pre_engine_error_ = XmppEngine::ERROR_AUTH; + EnsureClosed(); + return STATE_ERROR; + } + + // Wait until pre authentication is done is done + if (!d_->pre_auth_->IsAuthDone()) + return STATE_BLOCKED; + + if (!d_->pre_auth_->IsAuthorized()) { + // maybe split out a case when gaia is down? + if (d_->pre_auth_->HadError()) { + d_->pre_engine_error_ = XmppEngine::ERROR_AUTH; + d_->pre_engine_subcode_ = d_->pre_auth_->GetError(); + } + else { + d_->pre_engine_error_ = XmppEngine::ERROR_UNAUTHORIZED; + d_->pre_engine_subcode_ = 0; + d_->captcha_challenge_ = d_->pre_auth_->GetCaptchaChallenge(); + } + d_->pre_auth_.reset(NULL); // done with this + EnsureClosed(); + return STATE_ERROR; + } + + // Save auth token as a result + + d_->auth_mechanism_ = d_->pre_auth_->GetAuthMechanism(); + d_->auth_token_ = d_->pre_auth_->GetAuthToken(); + + // transfer ownership of pre_auth_ to engine + d_->engine_->SetSaslHandler(d_->pre_auth_.release()); + return STATE_START_XMPP_LOGIN; +} + +int XmppClient::ProcessStartXmppLogin() { + // Should not happen, but was observed in crash reports + if (!d_->socket_) { + LOG(LS_ERROR) << "socket_ already reset"; + return STATE_DONE; + } + + // Done with pre-connect tasks - connect! + if (!d_->socket_->Connect(d_->server_)) { + EnsureClosed(); + return STATE_ERROR; + } + + return STATE_RESPONSE; +} + +int XmppClient::ProcessResponse() { + // Hang around while we are connected. + if (!delivering_signal_ && + (!d_->engine_ || d_->engine_->GetState() == XmppEngine::STATE_CLOSED)) + return STATE_DONE; + return STATE_BLOCKED; +} + +XmppReturnStatus XmppClient::Disconnect() { + if (!d_->socket_) + return XMPP_RETURN_BADSTATE; + Abort(); + d_->engine_->Disconnect(); + d_->ResetSocket(); + return XMPP_RETURN_OK; +} + +XmppClient::XmppClient(TaskParent* parent) + : XmppTaskParentInterface(parent), + delivering_signal_(false), + valid_(false) { + d_.reset(new Private(this)); + valid_ = true; +} + +XmppClient::~XmppClient() { + valid_ = false; +} + +const Jid& XmppClient::jid() const { + return d_->engine_->FullJid(); +} + + +std::string XmppClient::NextId() { + return d_->engine_->NextId(); +} + +XmppReturnStatus XmppClient::SendStanza(const XmlElement* stanza) { + return d_->engine_->SendStanza(stanza); +} + +XmppReturnStatus XmppClient::SendStanzaError( + const XmlElement* old_stanza, XmppStanzaError xse, + const std::string& message) { + return d_->engine_->SendStanzaError(old_stanza, xse, message); +} + +XmppReturnStatus XmppClient::SendRaw(const std::string& text) { + return d_->engine_->SendRaw(text); +} + +XmppEngine* XmppClient::engine() { + return d_->engine_.get(); +} + +void XmppClient::Private::OnSocketConnected() { + engine_->Connect(); +} + +void XmppClient::Private::OnSocketRead() { + char bytes[4096]; + size_t bytes_read; + for (;;) { + // Should not happen, but was observed in crash reports + if (!socket_) { + LOG(LS_ERROR) << "socket_ already reset"; + return; + } + + if (!socket_->Read(bytes, sizeof(bytes), &bytes_read)) { + // TODO: deal with error information + return; + } + + if (bytes_read == 0) + return; + +//#if !defined(NDEBUG) + client_->SignalLogInput(bytes, static_cast<int>(bytes_read)); +//#endif + + engine_->HandleInput(bytes, bytes_read); + } +} + +void XmppClient::Private::OnSocketClosed() { + int code = socket_->GetError(); + engine_->ConnectionClosed(code); +} + +void XmppClient::Private::OnStateChange(int state) { + if (state == XmppEngine::STATE_CLOSED) { + client_->EnsureClosed(); + } + else { + client_->SignalStateChange((XmppEngine::State)state); + } + client_->Wake(); +} + +void XmppClient::Private::WriteOutput(const char* bytes, size_t len) { +//#if !defined(NDEBUG) + client_->SignalLogOutput(bytes, static_cast<int>(len)); +//#endif + + socket_->Write(bytes, len); + // TODO: deal with error information +} + +void XmppClient::Private::StartTls(const std::string& domain) { +#if defined(FEATURE_ENABLE_SSL) + socket_->StartTls(domain); +#endif +} + +void XmppClient::Private::CloseConnection() { + socket_->Close(); +} + +void XmppClient::AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) { + d_->engine_->AddStanzaHandler(task, level); +} + +void XmppClient::RemoveXmppTask(XmppTask* task) { + d_->engine_->RemoveStanzaHandler(task); +} + +void XmppClient::EnsureClosed() { + if (!d_->signal_closed_) { + d_->signal_closed_ = true; + delivering_signal_ = true; + SignalStateChange(XmppEngine::STATE_CLOSED); + delivering_signal_ = false; + } +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclient.h b/third_party/libjingle_xmpp/xmpp/xmppclient.h new file mode 100644 index 0000000..e3acb63a --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppclient.h
@@ -0,0 +1,149 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_ + +#include <memory> +#include <string> + +#include "third_party/libjingle_xmpp/xmpp/asyncsocket.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclientsettings.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" +#include "third_party/webrtc/base/sigslot.h" +#include "third_party/webrtc/base/task.h" + +namespace buzz { + +class PreXmppAuth; +class CaptchaChallenge; + +// Just some non-colliding number. Could have picked "1". +#define XMPP_CLIENT_TASK_CODE 0x366c1e47 + +///////////////////////////////////////////////////////////////////// +// +// XMPPCLIENT +// +///////////////////////////////////////////////////////////////////// +// +// See Task first. XmppClient is a parent task for XmppTasks. +// +// XmppClient is a task which is designed to be the parent task for +// all tasks that depend on a single Xmpp connection. If you want to, +// for example, listen for subscription requests forever, then your +// listener should be a task that is a child of the XmppClient that owns +// the connection you are using. XmppClient has all the utility methods +// that basically drill through to XmppEngine. +// +// XmppClient is just a wrapper for XmppEngine, and if I were writing it +// all over again, I would make XmppClient == XmppEngine. Why? +// XmppEngine needs tasks too, for example it has an XmppLoginTask which +// should just be the same kind of Task instead of an XmppEngine specific +// thing. It would help do certain things like GAIA auth cleaner. +// +///////////////////////////////////////////////////////////////////// + +class XmppClient : public XmppTaskParentInterface, + public XmppClientInterface, + public sigslot::has_slots<> +{ +public: + explicit XmppClient(rtc::TaskParent * parent); + virtual ~XmppClient(); + + XmppReturnStatus Connect(const XmppClientSettings & settings, + const std::string & lang, + AsyncSocket * socket, + PreXmppAuth * preauth); + + virtual int ProcessStart(); + virtual int ProcessResponse(); + XmppReturnStatus Disconnect(); + + sigslot::signal1<XmppEngine::State> SignalStateChange; + XmppEngine::Error GetError(int *subcode); + + // When there is a <stream:error> stanza, return the stanza + // so that they can be handled. + const XmlElement *GetStreamError(); + + // When there is an authentication error, we may have captcha info + // that the user can use to unlock their account + CaptchaChallenge GetCaptchaChallenge(); + + // When authentication is successful, this returns the service token + // (if we used GAIA authentication) + std::string GetAuthMechanism(); + std::string GetAuthToken(); + + XmppReturnStatus SendRaw(const std::string & text); + + XmppEngine* engine(); + + sigslot::signal2<const char *, int> SignalLogInput; + sigslot::signal2<const char *, int> SignalLogOutput; + + // As XmppTaskParentIntreface + virtual XmppClientInterface* GetClient() { return this; } + + // As XmppClientInterface + virtual XmppEngine::State GetState() const; + virtual const Jid& jid() const; + virtual std::string NextId(); + virtual XmppReturnStatus SendStanza(const XmlElement *stanza); + virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal, + XmppStanzaError code, + const std::string & text); + virtual void AddXmppTask(XmppTask *, XmppEngine::HandlerLevel); + virtual void RemoveXmppTask(XmppTask *); + + private: + friend class XmppTask; + + void OnAuthDone(); + + // Internal state management + enum { + STATE_PRE_XMPP_LOGIN = STATE_NEXT, + STATE_START_XMPP_LOGIN = STATE_NEXT + 1, + }; + int Process(int state) { + switch (state) { + case STATE_PRE_XMPP_LOGIN: return ProcessTokenLogin(); + case STATE_START_XMPP_LOGIN: return ProcessStartXmppLogin(); + default: return Task::Process(state); + } + } + + std::string GetStateName(int state) const { + switch (state) { + case STATE_PRE_XMPP_LOGIN: return "PRE_XMPP_LOGIN"; + case STATE_START_XMPP_LOGIN: return "START_XMPP_LOGIN"; + default: return Task::GetStateName(state); + } + } + + int ProcessTokenLogin(); + int ProcessStartXmppLogin(); + void EnsureClosed(); + + class Private; + friend class Private; + std::unique_ptr<Private> d_; + + bool delivering_signal_; + bool valid_; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h b/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h new file mode 100644 index 0000000..a60ab97 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppclientsettings.h
@@ -0,0 +1,111 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPCLIENTSETTINGS_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPCLIENTSETTINGS_H_ + +#include "third_party/webrtc/p2p/base/port.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc/base/cryptstring.h" + +namespace buzz { + +class XmppUserSettings { + public: + XmppUserSettings() + : use_tls_(buzz::TLS_DISABLED), + allow_plain_(false) { + } + + void set_user(const std::string& user) { user_ = user; } + void set_host(const std::string& host) { host_ = host; } + void set_pass(const rtc::CryptString& pass) { pass_ = pass; } + void set_auth_token(const std::string& mechanism, + const std::string& token) { + auth_mechanism_ = mechanism; + auth_token_ = token; + } + void set_resource(const std::string& resource) { resource_ = resource; } + void set_use_tls(const TlsOptions use_tls) { use_tls_ = use_tls; } + void set_allow_plain(bool f) { allow_plain_ = f; } + void set_test_server_domain(const std::string& test_server_domain) { + test_server_domain_ = test_server_domain; + } + void set_token_service(const std::string& token_service) { + token_service_ = token_service; + } + + const std::string& user() const { return user_; } + const std::string& host() const { return host_; } + const rtc::CryptString& pass() const { return pass_; } + const std::string& auth_mechanism() const { return auth_mechanism_; } + const std::string& auth_token() const { return auth_token_; } + const std::string& resource() const { return resource_; } + TlsOptions use_tls() const { return use_tls_; } + bool allow_plain() const { return allow_plain_; } + const std::string& test_server_domain() const { return test_server_domain_; } + const std::string& token_service() const { return token_service_; } + + private: + std::string user_; + std::string host_; + rtc::CryptString pass_; + std::string auth_mechanism_; + std::string auth_token_; + std::string resource_; + TlsOptions use_tls_; + bool allow_plain_; + std::string test_server_domain_; + std::string token_service_; +}; + +class XmppClientSettings : public XmppUserSettings { + public: + XmppClientSettings() + : protocol_(cricket::PROTO_TCP), + proxy_(rtc::PROXY_NONE), + proxy_port_(80), + use_proxy_auth_(false) { + } + + void set_server(const rtc::SocketAddress& server) { + server_ = server; + } + void set_protocol(cricket::ProtocolType protocol) { protocol_ = protocol; } + void set_proxy(rtc::ProxyType f) { proxy_ = f; } + void set_proxy_host(const std::string& host) { proxy_host_ = host; } + void set_proxy_port(int port) { proxy_port_ = port; }; + void set_use_proxy_auth(bool f) { use_proxy_auth_ = f; } + void set_proxy_user(const std::string& user) { proxy_user_ = user; } + void set_proxy_pass(const rtc::CryptString& pass) { proxy_pass_ = pass; } + + const rtc::SocketAddress& server() const { return server_; } + cricket::ProtocolType protocol() const { return protocol_; } + rtc::ProxyType proxy() const { return proxy_; } + const std::string& proxy_host() const { return proxy_host_; } + int proxy_port() const { return proxy_port_; } + bool use_proxy_auth() const { return use_proxy_auth_; } + const std::string& proxy_user() const { return proxy_user_; } + const rtc::CryptString& proxy_pass() const { return proxy_pass_; } + + private: + rtc::SocketAddress server_; + cricket::ProtocolType protocol_; + rtc::ProxyType proxy_; + std::string proxy_host_; + int proxy_port_; + bool use_proxy_auth_; + std::string proxy_user_; + rtc::CryptString proxy_pass_; +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPCLIENT_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengine.h b/third_party/libjingle_xmpp/xmpp/xmppengine.h new file mode 100644 index 0000000..fbbcf08 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppengine.h
@@ -0,0 +1,332 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_ + +// also part of the API +#include "third_party/libjingle_xmpp/xmllite/qname.h" +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" + + +namespace buzz { + +class XmppEngine; +class SaslHandler; +typedef void * XmppIqCookie; + +//! XMPP stanza error codes. +//! Used in XmppEngine.SendStanzaError(). +enum XmppStanzaError { + XSE_BAD_REQUEST, + XSE_CONFLICT, + XSE_FEATURE_NOT_IMPLEMENTED, + XSE_FORBIDDEN, + XSE_GONE, + XSE_INTERNAL_SERVER_ERROR, + XSE_ITEM_NOT_FOUND, + XSE_JID_MALFORMED, + XSE_NOT_ACCEPTABLE, + XSE_NOT_ALLOWED, + XSE_PAYMENT_REQUIRED, + XSE_RECIPIENT_UNAVAILABLE, + XSE_REDIRECT, + XSE_REGISTRATION_REQUIRED, + XSE_SERVER_NOT_FOUND, + XSE_SERVER_TIMEOUT, + XSE_RESOURCE_CONSTRAINT, + XSE_SERVICE_UNAVAILABLE, + XSE_SUBSCRIPTION_REQUIRED, + XSE_UNDEFINED_CONDITION, + XSE_UNEXPECTED_REQUEST, +}; + +// XmppReturnStatus +// This is used by API functions to synchronously return status. +enum XmppReturnStatus { + XMPP_RETURN_OK, + XMPP_RETURN_BADARGUMENT, + XMPP_RETURN_BADSTATE, + XMPP_RETURN_PENDING, + XMPP_RETURN_UNEXPECTED, + XMPP_RETURN_NOTYETIMPLEMENTED, +}; + +// TlsOptions +// This is used by API to identify TLS setting. +enum TlsOptions { + TLS_DISABLED, + TLS_ENABLED, + TLS_REQUIRED +}; + +//! Callback for socket output for an XmppEngine connection. +//! Register via XmppEngine.SetOutputHandler. An XmppEngine +//! can call back to this handler while it is processing +//! Connect, SendStanza, SendIq, Disconnect, or HandleInput. +class XmppOutputHandler { +public: + virtual ~XmppOutputHandler() {} + + //! Deliver the specified bytes to the XMPP socket. + virtual void WriteOutput(const char * bytes, size_t len) = 0; + + //! Initiate TLS encryption on the socket. + //! The implementation must verify that the SSL + //! certificate matches the given domainname. + virtual void StartTls(const std::string & domainname) = 0; + + //! Called when engine wants the connecton closed. + virtual void CloseConnection() = 0; +}; + +//! Callback to deliver engine state change notifications +//! to the object managing the engine. +class XmppSessionHandler { +public: + virtual ~XmppSessionHandler() {} + //! Called when engine changes state. Argument is new state. + virtual void OnStateChange(int state) = 0; +}; + +//! Callback to deliver stanzas to an Xmpp application module. +//! Register via XmppEngine.SetDefaultSessionHandler or via +//! XmppEngine.AddSessionHAndler. +class XmppStanzaHandler { +public: + virtual ~XmppStanzaHandler() {} + //! Process the given stanza. + //! The handler must return true if it has handled the stanza. + //! A false return value causes the stanza to be passed on to + //! the next registered handler. + virtual bool HandleStanza(const XmlElement * stanza) = 0; +}; + +//! Callback to deliver iq responses (results and errors). +//! Register while sending an iq via XmppEngine.SendIq. +//! Iq responses are routed to matching XmppIqHandlers in preference +//! to sending to any registered SessionHandlers. +class XmppIqHandler { +public: + virtual ~XmppIqHandler() {} + //! Called to handle the iq response. + //! The response may be either a result or an error, and will have + //! an 'id' that matches the request and a 'from' that matches the + //! 'to' of the request. Called no more than once; once this is + //! called, the handler is automatically unregistered. + virtual void IqResponse(XmppIqCookie cookie, const XmlElement * pelStanza) = 0; +}; + +//! The XMPP connection engine. +//! This engine implements the client side of the 'core' XMPP protocol. +//! To use it, register an XmppOutputHandler to handle socket output +//! and pass socket input to HandleInput. Then application code can +//! set up the connection with a user, password, and other settings, +//! and then call Connect() to initiate the connection. +//! An application can listen for events and receive stanzas by +//! registering an XmppStanzaHandler via AddStanzaHandler(). +class XmppEngine { +public: + static XmppEngine * Create(); + virtual ~XmppEngine() {} + + //! Error codes. See GetError(). + enum Error { + ERROR_NONE = 0, //!< No error + ERROR_XML, //!< Malformed XML or encoding error + ERROR_STREAM, //!< XMPP stream error - see GetStreamError() + ERROR_VERSION, //!< XMPP version error + ERROR_UNAUTHORIZED, //!< User is not authorized (rejected credentials) + ERROR_TLS, //!< TLS could not be negotiated + ERROR_AUTH, //!< Authentication could not be negotiated + ERROR_BIND, //!< Resource or session binding could not be negotiated + ERROR_CONNECTION_CLOSED,//!< Connection closed by output handler. + ERROR_DOCUMENT_CLOSED, //!< Closed by </stream:stream> + ERROR_SOCKET, //!< Socket error + ERROR_NETWORK_TIMEOUT, //!< Some sort of timeout (eg., we never got the roster) + ERROR_MISSING_USERNAME //!< User has a Google Account but no nickname + }; + + //! States. See GetState(). + enum State { + STATE_NONE = 0, //!< Nonexistent state + STATE_START, //!< Initial state. + STATE_OPENING, //!< Exchanging stream headers, authenticating and so on. + STATE_OPEN, //!< Authenticated and bound. + STATE_CLOSED, //!< Session closed, possibly due to error. + }; + + // SOCKET INPUT AND OUTPUT ------------------------------------------------ + + //! Registers the handler for socket output + virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh) = 0; + + //! Provides socket input to the engine + virtual XmppReturnStatus HandleInput(const char * bytes, size_t len) = 0; + + //! Advises the engine that the socket has closed + virtual XmppReturnStatus ConnectionClosed(int subcode) = 0; + + // SESSION SETUP --------------------------------------------------------- + + //! Indicates the (bare) JID for the user to use. + virtual XmppReturnStatus SetUser(const Jid & jid)= 0; + + //! Get the login (bare) JID. + virtual const Jid & GetUser() = 0; + + //! Provides different methods for credentials for login. + //! Takes ownership of this object; deletes when login is done + virtual XmppReturnStatus SetSaslHandler(SaslHandler * h) = 0; + + //! Sets whether TLS will be used within the connection (default true). + virtual XmppReturnStatus SetTls(TlsOptions useTls) = 0; + + //! Sets an alternate domain from which we allows TLS certificates. + //! This is for use in the case where a we want to allow a proxy to + //! serve up its own certificate rather than one owned by the underlying + //! domain. + virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname, + const std::string & proxy_domain) = 0; + + //! Gets whether TLS will be used within the connection. + virtual TlsOptions GetTls() = 0; + + //! Sets the request resource name, if any (optional). + //! Note that the resource name may be overridden by the server; after + //! binding, the actual resource name is available as part of FullJid(). + virtual XmppReturnStatus SetRequestedResource(const std::string& resource) = 0; + + //! Gets the request resource name. + virtual const std::string & GetRequestedResource() = 0; + + //! Sets language + virtual void SetLanguage(const std::string & lang) = 0; + + // SESSION MANAGEMENT --------------------------------------------------- + + //! Set callback for state changes. + virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler) = 0; + + //! Initiates the XMPP connection. + //! After supplying connection settings, call this once to initiate, + //! (optionally) encrypt, authenticate, and bind the connection. + virtual XmppReturnStatus Connect() = 0; + + //! The current engine state. + virtual State GetState() = 0; + + //! Returns true if the connection is encrypted (under TLS) + virtual bool IsEncrypted() = 0; + + //! The error code. + //! Consult this after XmppOutputHandler.OnClose(). + virtual Error GetError(int *subcode) = 0; + + //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM. + //! Notice the stanza returned is owned by the XmppEngine and + //! is deleted when the engine is destroyed. + virtual const XmlElement * GetStreamError() = 0; + + //! Closes down the connection. + //! Sends CloseConnection to output, and disconnects and registered + //! session handlers. After Disconnect completes, it is guaranteed + //! that no further callbacks will be made. + virtual XmppReturnStatus Disconnect() = 0; + + // APPLICATION USE ------------------------------------------------------- + + enum HandlerLevel { + HL_NONE = 0, + HL_PEEK, //!< Sees messages before all other processing; cannot abort + HL_SINGLE, //!< Watches for a single message, e.g., by id and sender + HL_SENDER, //!< Watches for a type of message from a specific sender + HL_TYPE, //!< Watches a type of message, e.g., all groupchat msgs + HL_ALL, //!< Watches all messages - gets last shot + HL_COUNT, //!< Count of handler levels + }; + + //! Adds a listener for session events. + //! Stanza delivery is chained to session handlers; the first to + //! return 'true' is the last to get each stanza. + virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, HandlerLevel level = HL_PEEK) = 0; + + //! Removes a listener for session events. + virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler) = 0; + + //! Sends a stanza to the server. + virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza) = 0; + + //! Sends raw text to the server + virtual XmppReturnStatus SendRaw(const std::string & text) = 0; + + //! Sends an iq to the server, and registers a callback for the result. + //! Returns the cookie passed to the result handler. + virtual XmppReturnStatus SendIq(const XmlElement* pelStanza, + XmppIqHandler* iq_handler, + XmppIqCookie* cookie) = 0; + + //! Unregisters an iq callback handler given its cookie. + //! No callback will come to this handler after it's unregistered. + virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie, + XmppIqHandler** iq_handler) = 0; + + + //! Forms and sends an error in response to the given stanza. + //! Swaps to and from, sets type to "error", and adds error information + //! based on the passed code. Text is optional and may be STR_EMPTY. + virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal, + XmppStanzaError code, + const std::string & text) = 0; + + //! The fullly bound JID. + //! This JID is only valid after binding has succeeded. If the value + //! is JID_NULL, the binding has not succeeded. + virtual const Jid & FullJid() = 0; + + //! The next unused iq id for this connection. + //! Call this when building iq stanzas, to ensure that each iq + //! gets its own unique id. + virtual std::string NextId() = 0; + +}; + +} + + +// Move these to a better location + +#define XMPP_FAILED(x) \ + ( (x) == buzz::XMPP_RETURN_OK ? false : true) \ + + +#define XMPP_SUCCEEDED(x) \ + ( (x) == buzz::XMPP_RETURN_OK ? true : false) \ + +#define IFR(x) \ + do { \ + xmpp_status = (x); \ + if (XMPP_FAILED(xmpp_status)) { \ + return xmpp_status; \ + } \ + } while (false) \ + + +#define IFC(x) \ + do { \ + xmpp_status = (x); \ + if (XMPP_FAILED(xmpp_status)) { \ + goto Cleanup; \ + } \ + } while (false) \ + + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPENGINE_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc new file mode 100644 index 0000000..93c8189 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc
@@ -0,0 +1,327 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <memory> +#include <sstream> +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h" +#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" +#include "third_party/libjingle_xmpp/xmpp/util_unittest.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::Jid; +using buzz::QName; +using buzz::XmlElement; +using buzz::XmppEngine; +using buzz::XmppIqCookie; +using buzz::XmppIqHandler; +using buzz::XmppTestHandler; +using buzz::QN_ID; +using buzz::QN_IQ; +using buzz::QN_TYPE; +using buzz::QN_ROSTER_QUERY; +using buzz::XMPP_RETURN_OK; +using buzz::XMPP_RETURN_BADARGUMENT; + +// XmppEngineTestIqHandler +// This class grabs the response to an IQ stanza and stores it in a string. +class XmppEngineTestIqHandler : public XmppIqHandler { + public: + virtual void IqResponse(XmppIqCookie, const XmlElement * stanza) { + ss_ << stanza->Str(); + } + + std::string IqResponseActivity() { + std::string result = ss_.str(); + ss_.str(""); + return result; + } + + private: + std::stringstream ss_; +}; + +class XmppEngineTest : public testing::Test { + public: + XmppEngine* engine() { return engine_.get(); } + XmppTestHandler* handler() { return handler_.get(); } + virtual void SetUp() { + engine_.reset(XmppEngine::Create()); + handler_.reset(new XmppTestHandler(engine_.get())); + + Jid jid("david@my-server"); + rtc::InsecureCryptStringImpl pass; + pass.password() = "david"; + engine_->SetSessionHandler(handler_.get()); + engine_->SetOutputHandler(handler_.get()); + engine_->AddStanzaHandler(handler_.get()); + engine_->SetUser(jid); + engine_->SetSaslHandler( + new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true)); + } + virtual void TearDown() { + handler_.reset(); + engine_.reset(); + } + void RunLogin(); + + private: + std::unique_ptr<XmppEngine> engine_; + std::unique_ptr<XmppTestHandler> handler_; +}; + +void XmppEngineTest::RunLogin() { + // Connect + EXPECT_EQ(XmppEngine::STATE_START, engine()->GetState()); + engine()->Connect(); + EXPECT_EQ(XmppEngine::STATE_OPENING, engine()->GetState()); + + EXPECT_EQ("[OPENING]", handler_->SessionActivity()); + + EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + + std::string input = + "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine()->HandleInput(input.c_str(), input.length()); + + input = + "<stream:features>" + "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>" + "<required/>" + "</starttls>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>", + handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("[START-TLS my-server]" + "<stream:stream to=\"my-server\" xml:lang=\"*\" " + "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<stream:stream id=\"01234567\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine()->HandleInput(input.c_str(), input.length()); + + input = + "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" " + "auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", + handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<stream:stream id=\"01234567\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine()->HandleInput(input.c_str(), input.length()); + + input = "<stream:features>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>" + "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<iq type=\"set\" id=\"0\">" + "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>", + handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<iq type='result' id='0'>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>" + "david@my-server/test</jid></bind></iq>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<iq type=\"set\" id=\"1\">" + "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>", + handler_->OutputActivity()); + + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + + input = "<iq type='result' id='1'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[OPEN]", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ(Jid("david@my-server/test"), engine()->FullJid()); +} + +// TestSuccessfulLogin() +// This function simply tests to see if a login works. This includes +// encryption and authentication +TEST_F(XmppEngineTest, TestSuccessfulLoginAndDisconnect) { + RunLogin(); + engine()->Disconnect(); + EXPECT_EQ("</stream:stream>[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppEngineTest, TestSuccessfulLoginAndConnectionClosed) { + RunLogin(); + engine()->ConnectionClosed(0); + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-CONNECTION-CLOSED]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + + +// TestNotXmpp() +// This tests the error case when connecting to a non XMPP service +TEST_F(XmppEngineTest, TestNotXmpp) { + // Connect + engine()->Connect(); + EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler()->OutputActivity()); + + // Send garbage response (courtesy of apache) + std::string input = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[OPENING][CLOSED][ERROR-XML]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +// TestPassthrough() +// This tests that arbitrary stanzas can be passed to the server through +// the engine. +TEST_F(XmppEngineTest, TestPassthrough) { + // Queue up an app stanza + XmlElement application_stanza(QName("test", "app-stanza")); + application_stanza.AddText("this-is-a-test"); + engine()->SendStanza(&application_stanza); + + // Do the whole login handshake + RunLogin(); + + EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test" + "</test:app-stanza>", handler()->OutputActivity()); + + // do another stanza + XmlElement roster_get(QN_IQ); + roster_get.AddAttr(QN_TYPE, "get"); + roster_get.AddAttr(QN_ID, engine()->NextId()); + roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true)); + engine()->SendStanza(&roster_get); + EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>" + "</iq>", handler()->OutputActivity()); + + // now say the server ends the stream + engine()->HandleInput("</stream:stream>", 16); + EXPECT_EQ("[CLOSED][ERROR-DOCUMENT-CLOSED]", handler()->SessionActivity()); + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +// TestIqCallback() +// This tests the routing of Iq stanzas and responses. +TEST_F(XmppEngineTest, TestIqCallback) { + XmppEngineTestIqHandler iq_response; + XmppIqCookie cookie; + + // Do the whole login handshake + RunLogin(); + + // Build an iq request + XmlElement roster_get(QN_IQ); + roster_get.AddAttr(QN_TYPE, "get"); + roster_get.AddAttr(QN_ID, engine()->NextId()); + roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true)); + engine()->SendIq(&roster_get, &iq_response, &cookie); + EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>" + "</iq>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); + EXPECT_EQ("", iq_response.IqResponseActivity()); + + // now say the server responds to the iq + std::string input = "<iq type='result' id='2'>" + "<query xmlns='jabber:iq:roster'><item>foo</item>" + "</query></iq>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); + EXPECT_EQ("<cli:iq type=\"result\" id=\"2\" xmlns:cli=\"jabber:client\">" + "<query xmlns=\"jabber:iq:roster\"><item>foo</item></query>" + "</cli:iq>", iq_response.IqResponseActivity()); + + EXPECT_EQ(XMPP_RETURN_BADARGUMENT, engine()->RemoveIqHandler(cookie, NULL)); + + // Do it again with another id to test cancel + roster_get.SetAttr(QN_ID, engine()->NextId()); + engine()->SendIq(&roster_get, &iq_response, &cookie); + EXPECT_EQ("<iq type=\"get\" id=\"3\"><query xmlns=\"jabber:iq:roster\"/>" + "</iq>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); + EXPECT_EQ("", iq_response.IqResponseActivity()); + + // cancel the handler this time + EXPECT_EQ(XMPP_RETURN_OK, engine()->RemoveIqHandler(cookie, NULL)); + + // now say the server responds to the iq: the iq handler should not get it. + input = "<iq type='result' id='3'><query xmlns='jabber:iq:roster'><item>bar" + "</item></query></iq>"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<cli:iq type=\"result\" id=\"3\" xmlns:cli=\"jabber:client\">" + "<query xmlns=\"jabber:iq:roster\"><item>bar</item></query>" + "</cli:iq>", handler()->StanzaActivity()); + EXPECT_EQ("", iq_response.IqResponseActivity()); + EXPECT_EQ("", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc new file mode 100644 index 0000000..8ba57a64 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.cc
@@ -0,0 +1,446 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h" + +#include <algorithm> +#include <sstream> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmllite/xmlprinter.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/saslhandler.h" +#include "third_party/libjingle_xmpp/xmpp/xmpplogintask.h" +#include "third_party/webrtc/base/common.h" + +namespace buzz { + +XmppEngine* XmppEngine::Create() { + return new XmppEngineImpl(); +} + + +XmppEngineImpl::XmppEngineImpl() + : stanza_parse_handler_(this), + stanza_parser_(&stanza_parse_handler_), + engine_entered_(0), + password_(), + requested_resource_(STR_EMPTY), + tls_option_(buzz::TLS_REQUIRED), + login_task_(new XmppLoginTask(this)), + next_id_(0), + state_(STATE_START), + encrypted_(false), + error_code_(ERROR_NONE), + subcode_(0), + stream_error_(), + raised_reset_(false), + output_handler_(NULL), + session_handler_(NULL), + iq_entries_(new IqEntryVector()), + sasl_handler_(), + output_(new std::stringstream()) { + for (int i = 0; i < HL_COUNT; i+= 1) { + stanza_handlers_[i].reset(new StanzaHandlerVector()); + } + + // Add XMPP namespaces to XML namespaces stack. + xmlns_stack_.AddXmlns("stream", "http://etherx.jabber.org/streams"); + xmlns_stack_.AddXmlns("", "jabber:client"); +} + +XmppEngineImpl::~XmppEngineImpl() { + DeleteIqCookies(); +} + +XmppReturnStatus XmppEngineImpl::SetOutputHandler( + XmppOutputHandler* output_handler) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + output_handler_ = output_handler; + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SetSessionHandler( + XmppSessionHandler* session_handler) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + session_handler_ = session_handler; + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::HandleInput( + const char* bytes, size_t len) { + if (state_ < STATE_OPENING || state_ > STATE_OPEN) + return XMPP_RETURN_BADSTATE; + + EnterExit ee(this); + + // TODO: The return value of the xml parser is not checked. + stanza_parser_.Parse(bytes, len, false); + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::ConnectionClosed(int subcode) { + if (state_ != STATE_CLOSED) { + EnterExit ee(this); + // If told that connection closed and not already closed, + // then connection was unpexectedly dropped. + if (subcode) { + SignalError(ERROR_SOCKET, subcode); + } else { + SignalError(ERROR_CONNECTION_CLOSED, 0); // no subcode + } + } + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SetTls(TlsOptions use_tls) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + tls_option_ = use_tls; + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SetTlsServer( + const std::string& tls_server_hostname, + const std::string& tls_server_domain) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + tls_server_hostname_ = tls_server_hostname; + tls_server_domain_= tls_server_domain; + + return XMPP_RETURN_OK; +} + +TlsOptions XmppEngineImpl::GetTls() { + return tls_option_; +} + +XmppReturnStatus XmppEngineImpl::SetUser(const Jid& jid) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + user_jid_ = jid; + + return XMPP_RETURN_OK; +} + +const Jid& XmppEngineImpl::GetUser() { + return user_jid_; +} + +XmppReturnStatus XmppEngineImpl::SetSaslHandler(SaslHandler* sasl_handler) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + sasl_handler_.reset(sasl_handler); + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SetRequestedResource( + const std::string& resource) { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + requested_resource_ = resource; + + return XMPP_RETURN_OK; +} + +const std::string& XmppEngineImpl::GetRequestedResource() { + return requested_resource_; +} + +XmppReturnStatus XmppEngineImpl::AddStanzaHandler( + XmppStanzaHandler* stanza_handler, + XmppEngine::HandlerLevel level) { + if (state_ == STATE_CLOSED) + return XMPP_RETURN_BADSTATE; + + stanza_handlers_[level]->push_back(stanza_handler); + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::RemoveStanzaHandler( + XmppStanzaHandler* stanza_handler) { + bool found = false; + + for (int level = 0; level < HL_COUNT; level += 1) { + StanzaHandlerVector::iterator new_end = + std::remove(stanza_handlers_[level]->begin(), + stanza_handlers_[level]->end(), + stanza_handler); + + if (new_end != stanza_handlers_[level]->end()) { + stanza_handlers_[level]->erase(new_end, stanza_handlers_[level]->end()); + found = true; + } + } + + if (!found) + return XMPP_RETURN_BADARGUMENT; + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::Connect() { + if (state_ != STATE_START) + return XMPP_RETURN_BADSTATE; + + EnterExit ee(this); + + // get the login task started + state_ = STATE_OPENING; + if (login_task_) { + login_task_->IncomingStanza(NULL, false); + if (login_task_->IsDone()) + login_task_.reset(); + } + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SendStanza(const XmlElement* element) { + if (state_ == STATE_CLOSED) + return XMPP_RETURN_BADSTATE; + + EnterExit ee(this); + + if (login_task_) { + // still handshaking - then outbound stanzas are queued + login_task_->OutgoingStanza(element); + } else { + // handshake done - send straight through + InternalSendStanza(element); + } + + return XMPP_RETURN_OK; +} + +XmppReturnStatus XmppEngineImpl::SendRaw(const std::string& text) { + if (state_ == STATE_CLOSED || login_task_) + return XMPP_RETURN_BADSTATE; + + EnterExit ee(this); + + (*output_) << text; + + return XMPP_RETURN_OK; +} + +std::string XmppEngineImpl::NextId() { + std::stringstream ss; + ss << next_id_++; + return ss.str(); +} + +XmppReturnStatus XmppEngineImpl::Disconnect() { + if (state_ != STATE_CLOSED) { + EnterExit ee(this); + if (state_ == STATE_OPEN) + *output_ << "</stream:stream>"; + state_ = STATE_CLOSED; + } + + return XMPP_RETURN_OK; +} + +void XmppEngineImpl::IncomingStart(const XmlElement* start) { + if (HasError() || raised_reset_) + return; + + if (login_task_) { + // start-stream should go to login task + login_task_->IncomingStanza(start, true); + if (login_task_->IsDone()) + login_task_.reset(); + } + else { + // if not logging in, it's an error to see a start + SignalError(ERROR_XML, 0); + } +} + +void XmppEngineImpl::IncomingStanza(const XmlElement* stanza) { + if (HasError() || raised_reset_) + return; + + if (stanza->Name() == QN_STREAM_ERROR) { + // Explicit XMPP stream error + SignalStreamError(stanza); + } else if (login_task_) { + // Handle login handshake + login_task_->IncomingStanza(stanza, false); + if (login_task_->IsDone()) + login_task_.reset(); + } else if (HandleIqResponse(stanza)) { + // iq is handled by above call + } else { + // give every "peek" handler a shot at all stanzas + for (size_t i = 0; i < stanza_handlers_[HL_PEEK]->size(); i += 1) { + (*stanza_handlers_[HL_PEEK])[i]->HandleStanza(stanza); + } + + // give other handlers a shot in precedence order, stopping after handled + for (int level = HL_SINGLE; level <= HL_ALL; level += 1) { + for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) { + if ((*stanza_handlers_[level])[i]->HandleStanza(stanza)) + return; + } + } + + // If nobody wants to handle a stanza then send back an error. + // Only do this for IQ stanzas as messages should probably just be dropped + // and presence stanzas should certainly be dropped. + std::string type = stanza->Attr(QN_TYPE); + if (stanza->Name() == QN_IQ && + !(type == "error" || type == "result")) { + SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY); + } + } +} + +void XmppEngineImpl::IncomingEnd(bool isError) { + if (HasError() || raised_reset_) + return; + + SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0); +} + +void XmppEngineImpl::InternalSendStart(const std::string& to) { + std::string hostname = tls_server_hostname_; + if (hostname.empty()) + hostname = to; + + // If not language is specified, the spec says use * + std::string lang = lang_; + if (lang.length() == 0) + lang = "*"; + + // send stream-beginning + // note, we put a \r\n at tne end fo the first line to cause non-XMPP + // line-oriented servers (e.g., Apache) to reveal themselves more quickly. + *output_ << "<stream:stream to=\"" << hostname << "\" " + << "xml:lang=\"" << lang << "\" " + << "version=\"1.0\" " + << "xmlns:stream=\"http://etherx.jabber.org/streams\" " + << "xmlns=\"jabber:client\">\r\n"; +} + +void XmppEngineImpl::InternalSendStanza(const XmlElement* element) { + // It should really never be necessary to set a FROM attribute on a stanza. + // It is implied by the bind on the stream and if you get it wrong + // (by flipping from/to on a message?) the server will close the stream. + ASSERT(!element->HasAttr(QN_FROM)); + + XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_); +} + +std::string XmppEngineImpl::ChooseBestSaslMechanism( + const std::vector<std::string>& mechanisms, bool encrypted) { + return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted); +} + +SaslMechanism* XmppEngineImpl::GetSaslMechanism(const std::string& name) { + return sasl_handler_->CreateSaslMechanism(name); +} + +void XmppEngineImpl::SignalBound(const Jid& fullJid) { + if (state_ == STATE_OPENING) { + bound_jid_ = fullJid; + state_ = STATE_OPEN; + } +} + +void XmppEngineImpl::SignalStreamError(const XmlElement* stream_error) { + if (state_ != STATE_CLOSED) { + stream_error_.reset(new XmlElement(*stream_error)); + SignalError(ERROR_STREAM, 0); + } +} + +void XmppEngineImpl::SignalError(Error error_code, int sub_code) { + if (state_ != STATE_CLOSED) { + error_code_ = error_code; + subcode_ = sub_code; + state_ = STATE_CLOSED; + } +} + +bool XmppEngineImpl::HasError() { + return error_code_ != ERROR_NONE; +} + +void XmppEngineImpl::StartTls(const std::string& domain) { + if (output_handler_) { + // As substitute for the real (login jid's) domain, we permit + // verifying a tls_server_domain_ instead, if one was passed. + // This allows us to avoid running a proxy that needs to handle + // valuable certificates. + output_handler_->StartTls( + tls_server_domain_.empty() ? domain : tls_server_domain_); + encrypted_ = true; + } +} + +XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine) + : engine_(engine), + state_(engine->state_) { + engine->engine_entered_ += 1; +} + +XmppEngineImpl::EnterExit::~EnterExit() { + XmppEngineImpl* engine = engine_; + + engine->engine_entered_ -= 1; + + bool closing = (engine->state_ != state_ && + engine->state_ == STATE_CLOSED); + bool flushing = closing || (engine->engine_entered_ == 0); + + if (engine->output_handler_ && flushing) { + std::string output = engine->output_->str(); + if (output.length() > 0) + engine->output_handler_->WriteOutput(output.c_str(), output.length()); + engine->output_->str(""); + + if (closing) { + engine->output_handler_->CloseConnection(); + engine->output_handler_ = 0; + } + } + + if (engine->engine_entered_) + return; + + if (engine->raised_reset_) { + engine->stanza_parser_.Reset(); + engine->raised_reset_ = false; + } + + if (engine->session_handler_) { + if (engine->state_ != state_) + engine->session_handler_->OnStateChange(engine->state_); + // Note: Handling of OnStateChange(CLOSED) should allow for the + // deletion of the engine, so no members should be accessed + // after this line. + } +} + +} // namespace buzz
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h new file mode 100644 index 0000000..2f8f2c6 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppengineimpl.h
@@ -0,0 +1,267 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_ + +#include <memory> +#include <sstream> +#include <vector> + +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h" + +namespace buzz { + +class XmppLoginTask; +class XmppEngine; +class XmppIqEntry; +class SaslHandler; +class SaslMechanism; + +//! The XMPP connection engine. +//! This engine implements the client side of the 'core' XMPP protocol. +//! To use it, register an XmppOutputHandler to handle socket output +//! and pass socket input to HandleInput. Then application code can +//! set up the connection with a user, password, and other settings, +//! and then call Connect() to initiate the connection. +//! An application can listen for events and receive stanzas by +//! registering an XmppStanzaHandler via AddStanzaHandler(). +class XmppEngineImpl : public XmppEngine { + public: + XmppEngineImpl(); + virtual ~XmppEngineImpl(); + + // SOCKET INPUT AND OUTPUT ------------------------------------------------ + + //! Registers the handler for socket output + virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh); + + //! Provides socket input to the engine + virtual XmppReturnStatus HandleInput(const char* bytes, size_t len); + + //! Advises the engine that the socket has closed + virtual XmppReturnStatus ConnectionClosed(int subcode); + + // SESSION SETUP --------------------------------------------------------- + + //! Indicates the (bare) JID for the user to use. + virtual XmppReturnStatus SetUser(const Jid& jid); + + //! Get the login (bare) JID. + virtual const Jid& GetUser(); + + //! Indicates the autentication to use. Takes ownership of the object. + virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler); + + //! Sets whether TLS will be used within the connection (default true). + virtual XmppReturnStatus SetTls(TlsOptions use_tls); + + //! Sets an alternate domain from which we allows TLS certificates. + //! This is for use in the case where a we want to allow a proxy to + //! serve up its own certificate rather than one owned by the underlying + //! domain. + virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname, + const std::string& proxy_domain); + + //! Gets whether TLS will be used within the connection. + virtual TlsOptions GetTls(); + + //! Sets the request resource name, if any (optional). + //! Note that the resource name may be overridden by the server; after + //! binding, the actual resource name is available as part of FullJid(). + virtual XmppReturnStatus SetRequestedResource(const std::string& resource); + + //! Gets the request resource name. + virtual const std::string& GetRequestedResource(); + + //! Sets language + virtual void SetLanguage(const std::string& lang) { + lang_ = lang; + } + + // SESSION MANAGEMENT --------------------------------------------------- + + //! Set callback for state changes. + virtual XmppReturnStatus SetSessionHandler(XmppSessionHandler* handler); + + //! Initiates the XMPP connection. + //! After supplying connection settings, call this once to initiate, + //! (optionally) encrypt, authenticate, and bind the connection. + virtual XmppReturnStatus Connect(); + + //! The current engine state. + virtual State GetState() { return state_; } + + //! Returns true if the connection is encrypted (under TLS) + virtual bool IsEncrypted() { return encrypted_; } + + //! The error code. + //! Consult this after XmppOutputHandler.OnClose(). + virtual Error GetError(int *subcode) { + if (subcode) { + *subcode = subcode_; + } + return error_code_; + } + + //! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM. + //! Notice the stanza returned is owned by the XmppEngine and + //! is deleted when the engine is destroyed. + virtual const XmlElement* GetStreamError() { return stream_error_.get(); } + + //! Closes down the connection. + //! Sends CloseConnection to output, and disconnects and registered + //! session handlers. After Disconnect completes, it is guaranteed + //! that no further callbacks will be made. + virtual XmppReturnStatus Disconnect(); + + // APPLICATION USE ------------------------------------------------------- + + //! Adds a listener for session events. + //! Stanza delivery is chained to session handlers; the first to + //! return 'true' is the last to get each stanza. + virtual XmppReturnStatus AddStanzaHandler(XmppStanzaHandler* handler, + XmppEngine::HandlerLevel level); + + //! Removes a listener for session events. + virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler); + + //! Sends a stanza to the server. + virtual XmppReturnStatus SendStanza(const XmlElement* stanza); + + //! Sends raw text to the server + virtual XmppReturnStatus SendRaw(const std::string& text); + + //! Sends an iq to the server, and registers a callback for the result. + //! Returns the cookie passed to the result handler. + virtual XmppReturnStatus SendIq(const XmlElement* stanza, + XmppIqHandler* iq_handler, + XmppIqCookie* cookie); + + //! Unregisters an iq callback handler given its cookie. + //! No callback will come to this handler after it's unregistered. + virtual XmppReturnStatus RemoveIqHandler(XmppIqCookie cookie, + XmppIqHandler** iq_handler); + + //! Forms and sends an error in response to the given stanza. + //! Swaps to and from, sets type to "error", and adds error information + //! based on the passed code. Text is optional and may be STR_EMPTY. + virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal, + XmppStanzaError code, + const std::string& text); + + //! The fullly bound JID. + //! This JID is only valid after binding has succeeded. If the value + //! is JID_NULL, the binding has not succeeded. + virtual const Jid& FullJid() { return bound_jid_; } + + //! The next unused iq id for this connection. + //! Call this when building iq stanzas, to ensure that each iq + //! gets its own unique id. + virtual std::string NextId(); + + private: + friend class XmppLoginTask; + friend class XmppIqEntry; + + void IncomingStanza(const XmlElement *stanza); + void IncomingStart(const XmlElement *stanza); + void IncomingEnd(bool isError); + + void InternalSendStart(const std::string& domainName); + void InternalSendStanza(const XmlElement* stanza); + std::string ChooseBestSaslMechanism( + const std::vector<std::string>& mechanisms, bool encrypted); + SaslMechanism* GetSaslMechanism(const std::string& name); + void SignalBound(const Jid& fullJid); + void SignalStreamError(const XmlElement* streamError); + void SignalError(Error errorCode, int subCode); + bool HasError(); + void DeleteIqCookies(); + bool HandleIqResponse(const XmlElement* element); + void StartTls(const std::string& domain); + void RaiseReset() { raised_reset_ = true; } + + class StanzaParseHandler : public XmppStanzaParseHandler { + public: + StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {} + virtual ~StanzaParseHandler() {} + + virtual void StartStream(const XmlElement* stream) { + outer_->IncomingStart(stream); + } + virtual void Stanza(const XmlElement* stanza) { + outer_->IncomingStanza(stanza); + } + virtual void EndStream() { + outer_->IncomingEnd(false); + } + virtual void XmlError() { + outer_->IncomingEnd(true); + } + + private: + XmppEngineImpl* const outer_; + }; + + class EnterExit { + public: + EnterExit(XmppEngineImpl* engine); + ~EnterExit(); + private: + XmppEngineImpl* engine_; + State state_; + }; + + friend class StanzaParseHandler; + friend class EnterExit; + + StanzaParseHandler stanza_parse_handler_; + XmppStanzaParser stanza_parser_; + + // state + int engine_entered_; + Jid user_jid_; + std::string password_; + std::string requested_resource_; + TlsOptions tls_option_; + std::string tls_server_hostname_; + std::string tls_server_domain_; + std::unique_ptr<XmppLoginTask> login_task_; + std::string lang_; + + int next_id_; + Jid bound_jid_; + State state_; + bool encrypted_; + Error error_code_; + int subcode_; + std::unique_ptr<XmlElement> stream_error_; + bool raised_reset_; + XmppOutputHandler* output_handler_; + XmppSessionHandler* session_handler_; + + XmlnsStack xmlns_stack_; + + typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector; + std::unique_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT]; + + typedef std::vector<XmppIqEntry*> IqEntryVector; + std::unique_ptr<IqEntryVector> iq_entries_; + + std::unique_ptr<SaslHandler> sasl_handler_; + + std::unique_ptr<std::stringstream> output_; +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPENGINEIMPL_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc b/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc new file mode 100644 index 0000000..a5b5714 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppengineimpl_iq.cc
@@ -0,0 +1,260 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <algorithm> +#include <vector> +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h" +#include "third_party/webrtc/base/common.h" + +namespace buzz { + +class XmppIqEntry { + XmppIqEntry(const std::string & id, const std::string & to, + XmppEngine * pxce, XmppIqHandler * iq_handler) : + id_(id), + to_(to), + engine_(pxce), + iq_handler_(iq_handler) { + } + +private: + friend class XmppEngineImpl; + + const std::string id_; + const std::string to_; + XmppEngine * const engine_; + XmppIqHandler * const iq_handler_; +}; + + +XmppReturnStatus +XmppEngineImpl::SendIq(const XmlElement * element, XmppIqHandler * iq_handler, + XmppIqCookie* cookie) { + if (state_ == STATE_CLOSED) + return XMPP_RETURN_BADSTATE; + if (NULL == iq_handler) + return XMPP_RETURN_BADARGUMENT; + if (!element || element->Name() != QN_IQ) + return XMPP_RETURN_BADARGUMENT; + + const std::string& type = element->Attr(QN_TYPE); + if (type != "get" && type != "set") + return XMPP_RETURN_BADARGUMENT; + + if (!element->HasAttr(QN_ID)) + return XMPP_RETURN_BADARGUMENT; + const std::string& id = element->Attr(QN_ID); + + XmppIqEntry * iq_entry = new XmppIqEntry(id, + element->Attr(QN_TO), + this, iq_handler); + iq_entries_->push_back(iq_entry); + SendStanza(element); + + if (cookie) + *cookie = iq_entry; + + return XMPP_RETURN_OK; +} + + +XmppReturnStatus +XmppEngineImpl::RemoveIqHandler(XmppIqCookie cookie, + XmppIqHandler ** iq_handler) { + + std::vector<XmppIqEntry*, std::allocator<XmppIqEntry*> >::iterator pos; + + pos = std::find(iq_entries_->begin(), + iq_entries_->end(), + reinterpret_cast<XmppIqEntry*>(cookie)); + + if (pos == iq_entries_->end()) + return XMPP_RETURN_BADARGUMENT; + + XmppIqEntry* entry = *pos; + iq_entries_->erase(pos); + if (iq_handler) + *iq_handler = entry->iq_handler_; + delete entry; + + return XMPP_RETURN_OK; +} + +void +XmppEngineImpl::DeleteIqCookies() { + for (size_t i = 0; i < iq_entries_->size(); i += 1) { + XmppIqEntry * iq_entry_ = (*iq_entries_)[i]; + (*iq_entries_)[i] = NULL; + delete iq_entry_; + } + iq_entries_->clear(); +} + +static void +AecImpl(XmlElement * error_element, const QName & name, + const char * type, const char * code) { + error_element->AddElement(new XmlElement(QN_ERROR)); + error_element->AddAttr(QN_CODE, code, 1); + error_element->AddAttr(QN_TYPE, type, 1); + error_element->AddElement(new XmlElement(name, true), 1); +} + + +static void +AddErrorCode(XmlElement * error_element, XmppStanzaError code) { + switch (code) { + case XSE_BAD_REQUEST: + AecImpl(error_element, QN_STANZA_BAD_REQUEST, "modify", "400"); + break; + case XSE_CONFLICT: + AecImpl(error_element, QN_STANZA_CONFLICT, "cancel", "409"); + break; + case XSE_FEATURE_NOT_IMPLEMENTED: + AecImpl(error_element, QN_STANZA_FEATURE_NOT_IMPLEMENTED, + "cancel", "501"); + break; + case XSE_FORBIDDEN: + AecImpl(error_element, QN_STANZA_FORBIDDEN, "auth", "403"); + break; + case XSE_GONE: + AecImpl(error_element, QN_STANZA_GONE, "modify", "302"); + break; + case XSE_INTERNAL_SERVER_ERROR: + AecImpl(error_element, QN_STANZA_INTERNAL_SERVER_ERROR, "wait", "500"); + break; + case XSE_ITEM_NOT_FOUND: + AecImpl(error_element, QN_STANZA_ITEM_NOT_FOUND, "cancel", "404"); + break; + case XSE_JID_MALFORMED: + AecImpl(error_element, QN_STANZA_JID_MALFORMED, "modify", "400"); + break; + case XSE_NOT_ACCEPTABLE: + AecImpl(error_element, QN_STANZA_NOT_ACCEPTABLE, "cancel", "406"); + break; + case XSE_NOT_ALLOWED: + AecImpl(error_element, QN_STANZA_NOT_ALLOWED, "cancel", "405"); + break; + case XSE_PAYMENT_REQUIRED: + AecImpl(error_element, QN_STANZA_PAYMENT_REQUIRED, "auth", "402"); + break; + case XSE_RECIPIENT_UNAVAILABLE: + AecImpl(error_element, QN_STANZA_RECIPIENT_UNAVAILABLE, "wait", "404"); + break; + case XSE_REDIRECT: + AecImpl(error_element, QN_STANZA_REDIRECT, "modify", "302"); + break; + case XSE_REGISTRATION_REQUIRED: + AecImpl(error_element, QN_STANZA_REGISTRATION_REQUIRED, "auth", "407"); + break; + case XSE_SERVER_NOT_FOUND: + AecImpl(error_element, QN_STANZA_REMOTE_SERVER_NOT_FOUND, + "cancel", "404"); + break; + case XSE_SERVER_TIMEOUT: + AecImpl(error_element, QN_STANZA_REMOTE_SERVER_TIMEOUT, "wait", "502"); + break; + case XSE_RESOURCE_CONSTRAINT: + AecImpl(error_element, QN_STANZA_RESOURCE_CONSTRAINT, "wait", "500"); + break; + case XSE_SERVICE_UNAVAILABLE: + AecImpl(error_element, QN_STANZA_SERVICE_UNAVAILABLE, "cancel", "503"); + break; + case XSE_SUBSCRIPTION_REQUIRED: + AecImpl(error_element, QN_STANZA_SUBSCRIPTION_REQUIRED, "auth", "407"); + break; + case XSE_UNDEFINED_CONDITION: + AecImpl(error_element, QN_STANZA_UNDEFINED_CONDITION, "wait", "500"); + break; + case XSE_UNEXPECTED_REQUEST: + AecImpl(error_element, QN_STANZA_UNEXPECTED_REQUEST, "wait", "400"); + break; + } +} + + +XmppReturnStatus +XmppEngineImpl::SendStanzaError(const XmlElement * element_original, + XmppStanzaError code, + const std::string & text) { + + if (state_ == STATE_CLOSED) + return XMPP_RETURN_BADSTATE; + + XmlElement error_element(element_original->Name()); + error_element.AddAttr(QN_TYPE, "error"); + + // copy attrs, copy 'from' to 'to' and strip 'from' + for (const XmlAttr * attribute = element_original->FirstAttr(); + attribute; attribute = attribute->NextAttr()) { + QName name = attribute->Name(); + if (name == QN_TO) + continue; // no need to put a from attr. Server will stamp stanza + else if (name == QN_FROM) + name = QN_TO; + else if (name == QN_TYPE) + continue; + error_element.AddAttr(name, attribute->Value()); + } + + // copy children + for (const XmlChild * child = element_original->FirstChild(); + child; + child = child->NextChild()) { + if (child->IsText()) { + error_element.AddText(child->AsText()->Text()); + } else { + error_element.AddElement(new XmlElement(*(child->AsElement()))); + } + } + + // add error information + AddErrorCode(&error_element, code); + if (text != STR_EMPTY) { + XmlElement * text_element = new XmlElement(QN_STANZA_TEXT, true); + text_element->AddText(text); + error_element.AddElement(text_element); + } + + SendStanza(&error_element); + + return XMPP_RETURN_OK; +} + + +bool +XmppEngineImpl::HandleIqResponse(const XmlElement * element) { + if (iq_entries_->empty()) + return false; + if (element->Name() != QN_IQ) + return false; + std::string type = element->Attr(QN_TYPE); + if (type != "result" && type != "error") + return false; + if (!element->HasAttr(QN_ID)) + return false; + std::string id = element->Attr(QN_ID); + std::string from = element->Attr(QN_FROM); + + for (std::vector<XmppIqEntry *>::iterator it = iq_entries_->begin(); + it != iq_entries_->end(); it += 1) { + XmppIqEntry * iq_entry = *it; + if (iq_entry->id_ == id && iq_entry->to_ == from) { + iq_entries_->erase(it); + iq_entry->iq_handler_->IqResponse(iq_entry, element); + delete iq_entry; + return true; + } + } + + return false; +} + +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc b/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc new file mode 100644 index 0000000..6936b77 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmpplogintask.cc
@@ -0,0 +1,380 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/xmpplogintask.h" + +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/saslmechanism.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengineimpl.h" +#include "third_party/webrtc/base/base64.h" +#include "third_party/webrtc/base/common.h" + +using rtc::ConstantLabel; + +namespace buzz { + +#if !defined(NDEBUG) +const ConstantLabel XmppLoginTask::LOGINTASK_STATES[] = { + KLABEL(LOGINSTATE_INIT), + KLABEL(LOGINSTATE_STREAMSTART_SENT), + KLABEL(LOGINSTATE_STARTED_XMPP), + KLABEL(LOGINSTATE_TLS_INIT), + KLABEL(LOGINSTATE_AUTH_INIT), + KLABEL(LOGINSTATE_BIND_INIT), + KLABEL(LOGINSTATE_TLS_REQUESTED), + KLABEL(LOGINSTATE_SASL_RUNNING), + KLABEL(LOGINSTATE_BIND_REQUESTED), + KLABEL(LOGINSTATE_SESSION_REQUESTED), + KLABEL(LOGINSTATE_DONE), + LASTLABEL +}; +#endif +XmppLoginTask::XmppLoginTask(XmppEngineImpl * pctx) : + pctx_(pctx), + authNeeded_(true), + allowNonGoogleLogin_(true), + state_(LOGINSTATE_INIT), + pelStanza_(NULL), + isStart_(false), + iqId_(STR_EMPTY), + pelFeatures_(), + fullJid_(STR_EMPTY), + streamId_(STR_EMPTY), + pvecQueuedStanzas_(new std::vector<XmlElement *>()), + sasl_mech_() { +} + +XmppLoginTask::~XmppLoginTask() { + for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) + delete (*pvecQueuedStanzas_)[i]; +} + +void +XmppLoginTask::IncomingStanza(const XmlElement *element, bool isStart) { + pelStanza_ = element; + isStart_ = isStart; + Advance(); + pelStanza_ = NULL; + isStart_ = false; +} + +const XmlElement * +XmppLoginTask::NextStanza() { + const XmlElement * result = pelStanza_; + pelStanza_ = NULL; + return result; +} + +bool +XmppLoginTask::Advance() { + + for (;;) { + + const XmlElement * element = NULL; + +#if !defined(NDEBUG) + LOG(LS_VERBOSE) << "XmppLoginTask::Advance - " + << rtc::ErrorName(state_, LOGINTASK_STATES); +#endif + + switch (state_) { + + case LOGINSTATE_INIT: { + pctx_->RaiseReset(); + pelFeatures_.reset(NULL); + + // The proper domain to verify against is the real underlying + // domain - i.e., the domain that owns the JID. Our XmppEngineImpl + // also allows matching against a proxy domain instead, if it is told + // to do so - see the implementation of XmppEngineImpl::StartTls and + // XmppEngine::SetTlsServerDomain to see how you can use that feature + pctx_->InternalSendStart(pctx_->user_jid_.domain()); + state_ = LOGINSTATE_STREAMSTART_SENT; + break; + } + + case LOGINSTATE_STREAMSTART_SENT: { + if (NULL == (element = NextStanza())) + return true; + + if (!isStart_ || !HandleStartStream(element)) + return Failure(XmppEngine::ERROR_VERSION); + + state_ = LOGINSTATE_STARTED_XMPP; + return true; + } + + case LOGINSTATE_STARTED_XMPP: { + if (NULL == (element = NextStanza())) + return true; + + if (!HandleFeatures(element)) + return Failure(XmppEngine::ERROR_VERSION); + + bool tls_present = (GetFeature(QN_TLS_STARTTLS) != NULL); + // Error if TLS required but not present. + if (pctx_->tls_option_ == buzz::TLS_REQUIRED && !tls_present) { + return Failure(XmppEngine::ERROR_TLS); + } + // Use TLS if required or enabled, and also available + if ((pctx_->tls_option_ == buzz::TLS_REQUIRED || + pctx_->tls_option_ == buzz::TLS_ENABLED) && tls_present) { + state_ = LOGINSTATE_TLS_INIT; + continue; + } + + if (authNeeded_) { + state_ = LOGINSTATE_AUTH_INIT; + continue; + } + + state_ = LOGINSTATE_BIND_INIT; + continue; + } + + case LOGINSTATE_TLS_INIT: { + const XmlElement * pelTls = GetFeature(QN_TLS_STARTTLS); + if (!pelTls) + return Failure(XmppEngine::ERROR_TLS); + + XmlElement el(QN_TLS_STARTTLS, true); + pctx_->InternalSendStanza(&el); + state_ = LOGINSTATE_TLS_REQUESTED; + continue; + } + + case LOGINSTATE_TLS_REQUESTED: { + if (NULL == (element = NextStanza())) + return true; + if (element->Name() != QN_TLS_PROCEED) + return Failure(XmppEngine::ERROR_TLS); + + // The proper domain to verify against is the real underlying + // domain - i.e., the domain that owns the JID. Our XmppEngineImpl + // also allows matching against a proxy domain instead, if it is told + // to do so - see the implementation of XmppEngineImpl::StartTls and + // XmppEngine::SetTlsServerDomain to see how you can use that feature + pctx_->StartTls(pctx_->user_jid_.domain()); + pctx_->tls_option_ = buzz::TLS_ENABLED; + state_ = LOGINSTATE_INIT; + continue; + } + + case LOGINSTATE_AUTH_INIT: { + const XmlElement * pelSaslAuth = GetFeature(QN_SASL_MECHANISMS); + if (!pelSaslAuth) { + return Failure(XmppEngine::ERROR_AUTH); + } + + // Collect together the SASL auth mechanisms presented by the server + std::vector<std::string> mechanisms; + for (const XmlElement * pelMech = + pelSaslAuth->FirstNamed(QN_SASL_MECHANISM); + pelMech; + pelMech = pelMech->NextNamed(QN_SASL_MECHANISM)) { + + mechanisms.push_back(pelMech->BodyText()); + } + + // Given all the mechanisms, choose the best + std::string choice(pctx_->ChooseBestSaslMechanism(mechanisms, pctx_->IsEncrypted())); + if (choice.empty()) { + return Failure(XmppEngine::ERROR_AUTH); + } + + // No recognized auth mechanism - that's an error + sasl_mech_.reset(pctx_->GetSaslMechanism(choice)); + if (!sasl_mech_) { + return Failure(XmppEngine::ERROR_AUTH); + } + + // OK, let's start it. + XmlElement * auth = sasl_mech_->StartSaslAuth(); + if (auth == NULL) { + return Failure(XmppEngine::ERROR_AUTH); + } + if (allowNonGoogleLogin_) { + // Setting the following two attributes is required to support + // non-google ids. + + // Allow login with non-google id accounts. + auth->SetAttr(QN_GOOGLE_ALLOW_NON_GOOGLE_ID_XMPP_LOGIN, "true"); + + // Allow login with either the non-google id or the friendly email. + auth->SetAttr(QN_GOOGLE_AUTH_CLIENT_USES_FULL_BIND_RESULT, "true"); + } + + pctx_->InternalSendStanza(auth); + delete auth; + state_ = LOGINSTATE_SASL_RUNNING; + continue; + } + + case LOGINSTATE_SASL_RUNNING: { + if (NULL == (element = NextStanza())) + return true; + if (element->Name().Namespace() != NS_SASL) + return Failure(XmppEngine::ERROR_AUTH); + if (element->Name() == QN_SASL_CHALLENGE) { + XmlElement * response = sasl_mech_->HandleSaslChallenge(element); + if (response == NULL) { + return Failure(XmppEngine::ERROR_AUTH); + } + pctx_->InternalSendStanza(response); + delete response; + state_ = LOGINSTATE_SASL_RUNNING; + continue; + } + if (element->Name() != QN_SASL_SUCCESS) { + return Failure(XmppEngine::ERROR_UNAUTHORIZED); + } + + // Authenticated! + authNeeded_ = false; + state_ = LOGINSTATE_INIT; + continue; + } + + case LOGINSTATE_BIND_INIT: { + const XmlElement * pelBindFeature = GetFeature(QN_BIND_BIND); + const XmlElement * pelSessionFeature = GetFeature(QN_SESSION_SESSION); + if (!pelBindFeature || !pelSessionFeature) + return Failure(XmppEngine::ERROR_BIND); + + XmlElement iq(QN_IQ); + iq.AddAttr(QN_TYPE, "set"); + + iqId_ = pctx_->NextId(); + iq.AddAttr(QN_ID, iqId_); + iq.AddElement(new XmlElement(QN_BIND_BIND, true)); + + if (pctx_->requested_resource_ != STR_EMPTY) { + iq.AddElement(new XmlElement(QN_BIND_RESOURCE), 1); + iq.AddText(pctx_->requested_resource_, 2); + } + pctx_->InternalSendStanza(&iq); + state_ = LOGINSTATE_BIND_REQUESTED; + continue; + } + + case LOGINSTATE_BIND_REQUESTED: { + if (NULL == (element = NextStanza())) + return true; + + if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || + element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") + return true; + + if (element->Attr(QN_TYPE) != "result" || element->FirstElement() == NULL || + element->FirstElement()->Name() != QN_BIND_BIND) + return Failure(XmppEngine::ERROR_BIND); + + fullJid_ = Jid(element->FirstElement()->TextNamed(QN_BIND_JID)); + if (!fullJid_.IsFull()) { + return Failure(XmppEngine::ERROR_BIND); + } + + // now request session + XmlElement iq(QN_IQ); + iq.AddAttr(QN_TYPE, "set"); + + iqId_ = pctx_->NextId(); + iq.AddAttr(QN_ID, iqId_); + iq.AddElement(new XmlElement(QN_SESSION_SESSION, true)); + pctx_->InternalSendStanza(&iq); + + state_ = LOGINSTATE_SESSION_REQUESTED; + continue; + } + + case LOGINSTATE_SESSION_REQUESTED: { + if (NULL == (element = NextStanza())) + return true; + if (element->Name() != QN_IQ || element->Attr(QN_ID) != iqId_ || + element->Attr(QN_TYPE) == "get" || element->Attr(QN_TYPE) == "set") + return false; + + if (element->Attr(QN_TYPE) != "result") + return Failure(XmppEngine::ERROR_BIND); + + pctx_->SignalBound(fullJid_); + FlushQueuedStanzas(); + state_ = LOGINSTATE_DONE; + return true; + } + + case LOGINSTATE_DONE: + return false; + } + } +} + +bool +XmppLoginTask::HandleStartStream(const XmlElement *element) { + + if (element->Name() != QN_STREAM_STREAM) + return false; + + if (element->Attr(QN_XMLNS) != "jabber:client") + return false; + + if (element->Attr(QN_VERSION) != "1.0") + return false; + + if (!element->HasAttr(QN_ID)) + return false; + + streamId_ = element->Attr(QN_ID); + + return true; +} + +bool +XmppLoginTask::HandleFeatures(const XmlElement *element) { + if (element->Name() != QN_STREAM_FEATURES) + return false; + + pelFeatures_.reset(new XmlElement(*element)); + return true; +} + +const XmlElement * +XmppLoginTask::GetFeature(const QName & name) { + return pelFeatures_->FirstNamed(name); +} + +bool +XmppLoginTask::Failure(XmppEngine::Error reason) { + state_ = LOGINSTATE_DONE; + pctx_->SignalError(reason, 0); + return false; +} + +void +XmppLoginTask::OutgoingStanza(const XmlElement * element) { + XmlElement * pelCopy = new XmlElement(*element); + pvecQueuedStanzas_->push_back(pelCopy); +} + +void +XmppLoginTask::FlushQueuedStanzas() { + for (size_t i = 0; i < pvecQueuedStanzas_->size(); i += 1) { + pctx_->InternalSendStanza((*pvecQueuedStanzas_)[i]); + delete (*pvecQueuedStanzas_)[i]; + } + pvecQueuedStanzas_->clear(); +} + +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask.h b/third_party/libjingle_xmpp/xmpp/xmpplogintask.h new file mode 100644 index 0000000..82fa3420 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmpplogintask.h
@@ -0,0 +1,87 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_ +#define WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "third_party/libjingle_xmpp/xmpp/jid.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc_overrides/webrtc/base/logging.h" + +namespace buzz { + +class XmlElement; +class XmppEngineImpl; +class SaslMechanism; + + +// TODO: Rename to LoginTask. +class XmppLoginTask { + +public: + XmppLoginTask(XmppEngineImpl *pctx); + ~XmppLoginTask(); + + bool IsDone() + { return state_ == LOGINSTATE_DONE; } + void IncomingStanza(const XmlElement * element, bool isStart); + void OutgoingStanza(const XmlElement *element); + void set_allow_non_google_login(bool b) + { allowNonGoogleLogin_ = b; } + +private: + enum LoginTaskState { + LOGINSTATE_INIT = 0, + LOGINSTATE_STREAMSTART_SENT, + LOGINSTATE_STARTED_XMPP, + LOGINSTATE_TLS_INIT, + LOGINSTATE_AUTH_INIT, + LOGINSTATE_BIND_INIT, + LOGINSTATE_TLS_REQUESTED, + LOGINSTATE_SASL_RUNNING, + LOGINSTATE_BIND_REQUESTED, + LOGINSTATE_SESSION_REQUESTED, + LOGINSTATE_DONE, + }; + + const XmlElement * NextStanza(); + bool Advance(); + bool HandleStartStream(const XmlElement * element); + bool HandleFeatures(const XmlElement * element); + const XmlElement * GetFeature(const QName & name); + bool Failure(XmppEngine::Error reason); + void FlushQueuedStanzas(); + + XmppEngineImpl * pctx_; + bool authNeeded_; + bool allowNonGoogleLogin_; + LoginTaskState state_; + const XmlElement * pelStanza_; + bool isStart_; + std::string iqId_; + std::unique_ptr<XmlElement> pelFeatures_; + Jid fullJid_; + std::string streamId_; + std::unique_ptr<std::vector<XmlElement *> > pvecQueuedStanzas_; + + std::unique_ptr<SaslMechanism> sasl_mech_; + +#if !defined(NDEBUG) + static const rtc::ConstantLabel LOGINTASK_STATES[]; +#endif +}; + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_LOGINTASK_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc new file mode 100644 index 0000000..2a70faee --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
@@ -0,0 +1,637 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <memory> +#include <sstream> +#include <string> + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h" +#include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h" +#include "third_party/libjingle_xmpp/xmpp/util_unittest.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/cryptstring.h" +#include "third_party/webrtc/base/gunit.h" +#include "third_party/webrtc/typedefs.h" + +using buzz::Jid; +using buzz::QName; +using buzz::XmlElement; +using buzz::XmppEngine; +using buzz::XmppTestHandler; + +enum XlttStage { + XLTT_STAGE_CONNECT = 0, + XLTT_STAGE_STREAMSTART, + XLTT_STAGE_TLS_FEATURES, + XLTT_STAGE_TLS_PROCEED, + XLTT_STAGE_ENCRYPTED_START, + XLTT_STAGE_AUTH_FEATURES, + XLTT_STAGE_AUTH_SUCCESS, + XLTT_STAGE_AUTHENTICATED_START, + XLTT_STAGE_BIND_FEATURES, + XLTT_STAGE_BIND_SUCCESS, + XLTT_STAGE_SESSION_SUCCESS, +}; + +class XmppLoginTaskTest : public testing::Test { + public: + XmppEngine* engine() { return engine_.get(); } + XmppTestHandler* handler() { return handler_.get(); } + virtual void SetUp() { + engine_.reset(XmppEngine::Create()); + handler_.reset(new XmppTestHandler(engine_.get())); + + Jid jid("david@my-server"); + rtc::InsecureCryptStringImpl pass; + pass.password() = "david"; + engine_->SetSessionHandler(handler_.get()); + engine_->SetOutputHandler(handler_.get()); + engine_->AddStanzaHandler(handler_.get()); + engine_->SetUser(jid); + engine_->SetSaslHandler( + new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true)); + } + virtual void TearDown() { + handler_.reset(); + engine_.reset(); + } + void RunPartialLogin(XlttStage startstage, XlttStage endstage); + void SetTlsOptions(buzz::TlsOptions option); + + private: + std::unique_ptr<XmppEngine> engine_; + std::unique_ptr<XmppTestHandler> handler_; +}; + +void XmppLoginTaskTest::SetTlsOptions(buzz::TlsOptions option) { + engine_->SetTls(option); +} +void XmppLoginTaskTest::RunPartialLogin(XlttStage startstage, + XlttStage endstage) { + std::string input; + + switch (startstage) { + case XLTT_STAGE_CONNECT: { + engine_->Connect(); + XmlElement appStanza(QName("test", "app-stanza")); + appStanza.AddText("this-is-a-test"); + engine_->SendStanza(&appStanza); + + EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" " + "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + EXPECT_EQ("[OPENING]", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + if (endstage == XLTT_STAGE_CONNECT) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_STREAMSTART: { + input = "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->OutputActivity()); + if (endstage == XLTT_STAGE_STREAMSTART) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_TLS_FEATURES: { + input = "<stream:features>" + "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" + "</stream:features>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>", + handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_TLS_FEATURES) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_TLS_PROCEED: { + input = std::string("<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("[START-TLS my-server]" + "<stream:stream to=\"my-server\" xml:lang=\"*\" " + "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_TLS_PROCEED) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_ENCRYPTED_START: { + input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"); + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->OutputActivity()); + if (endstage == XLTT_STAGE_ENCRYPTED_START) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_AUTH_FEATURES: { + input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" " + "auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", + handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_AUTH_FEATURES) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_AUTH_SUCCESS: { + input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" " + "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_AUTH_SUCCESS) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_AUTHENTICATED_START: { + input = std::string("<stream:stream id=\"01234567\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"); + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + EXPECT_EQ("", handler_->OutputActivity()); + if (endstage == XLTT_STAGE_AUTHENTICATED_START) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_BIND_FEATURES: { + input = "<stream:features>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>" + "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>" + "</stream:features>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<iq type=\"set\" id=\"0\">" + "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>", + handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_BIND_FEATURES) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_BIND_SUCCESS: { + input = "<iq type='result' id='0'>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>" + "<jid>david@my-server/test</jid></bind></iq>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<iq type=\"set\" id=\"1\">" + "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>", + handler_->OutputActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + EXPECT_EQ("", handler_->SessionActivity()); + if (endstage == XLTT_STAGE_BIND_SUCCESS) + return; + FALLTHROUGH(); + } + + case XLTT_STAGE_SESSION_SUCCESS: { + input = "<iq type='result' id='1'/>"; + engine_->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test" + "</test:app-stanza>", handler_->OutputActivity()); + EXPECT_EQ("[OPEN]", handler_->SessionActivity()); + EXPECT_EQ("", handler_->StanzaActivity()); + if (endstage == XLTT_STAGE_SESSION_SUCCESS) + return; + FALLTHROUGH(); + } + default: + break; + } +} + +TEST_F(XmppLoginTaskTest, TestUtf8Good) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT); + + std::string input = "<?xml version='1.0' encoding='UTF-8'?>" + "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestNonUtf8Bad) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_CONNECT); + + std::string input = "<?xml version='1.0' encoding='ISO-8859-1'?>" + "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" " + "xmlns:stream=\"http://etherx.jabber.org/streams\" " + "xmlns=\"jabber:client\">"; + engine()->HandleInput(input.c_str(), input.length()); + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestNoFeatures) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<iq type='get' id='1'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsRequiredNotPresent) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsRequeiredAndPresent) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>" + "<required/>" + "</starttls>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>X-GOOGLE-TOKEN</mechanism>" + "<mechanism>PLAIN</mechanism>" + "<mechanism>X-OAUTH2</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>", + handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsEnabledNotPresent) { + SetTlsOptions(buzz::TLS_ENABLED); + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsEnabledAndPresent) { + SetTlsOptions(buzz::TLS_ENABLED); + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>X-GOOGLE-TOKEN</mechanism>" + "<mechanism>PLAIN</mechanism>" + "<mechanism>X-OAUTH2</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsDisabledNotPresent) { + SetTlsOptions(buzz::TLS_DISABLED); + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "<mechanism>PLAIN</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsDisabledAndPresent) { + SetTlsOptions(buzz::TLS_DISABLED); + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_STREAMSTART); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>X-GOOGLE-TOKEN</mechanism>" + "<mechanism>PLAIN</mechanism>" + "<mechanism>X-OAUTH2</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" " + "mechanism=\"PLAIN\" auth:allow-non-google-login=\"true\" " + "auth:client-uses-full-bind-result=\"true\" " + "xmlns:auth=\"http://www.google.com/talk/protocol/auth\"" + ">AGRhdmlkAGRhdmlk</auth>", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsFailure) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_FEATURES); + + std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-TLS]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestTlsBadStream) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_TLS_PROCEED); + + std::string input = "<wrongtag>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestMissingSaslPlain) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_ENCRYPTED_START); + + std::string input = "<stream:features>" + "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "<mechanism>DIGEST-MD5</mechanism>" + "</mechanisms>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-AUTH]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestWrongPassword) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_FEATURES); + + std::string input = "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-UNAUTHORIZED]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestAuthBadStream) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTH_SUCCESS); + + std::string input = "<wrongtag>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-VERSION]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestMissingBindFeature) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START); + + std::string input = "<stream:features>" + "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); +} + +TEST_F(XmppLoginTaskTest, TestMissingSessionFeature) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_AUTHENTICATED_START); + + std::string input = "<stream:features>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>" + "</stream:features>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +/* TODO: Handle this case properly inside XmppLoginTask. +TEST_F(XmppLoginTaskTest, TestBindFailure1) { + // check wrong JID + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES); + + std::string input = "<iq type='result' id='0'>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>" + "<jid>davey@my-server/test</jid></bind></iq>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} +*/ + +TEST_F(XmppLoginTaskTest, TestBindFailure2) { + // check missing JID + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES); + + std::string input = "<iq type='result' id='0'>" + "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestBindFailure3) { + // check plain failure + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES); + + std::string input = "<iq type='error' id='0'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); + EXPECT_EQ("", handler()->StanzaActivity()); +} + +TEST_F(XmppLoginTaskTest, TestBindFailure4) { + // check wrong id to ignore + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_FEATURES); + + std::string input = "<iq type='error' id='1'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + // continue after an ignored iq + RunPartialLogin(XLTT_STAGE_BIND_SUCCESS, XLTT_STAGE_SESSION_SUCCESS); +} + +TEST_F(XmppLoginTaskTest, TestSessionFailurePlain1) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS); + + std::string input = "<iq type='error' id='1'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-BIND]", handler()->SessionActivity()); +} + +TEST_F(XmppLoginTaskTest, TestSessionFailurePlain2) { + RunPartialLogin(XLTT_STAGE_CONNECT, XLTT_STAGE_BIND_SUCCESS); + + // check reverse iq to ignore + // TODO: consider queueing or passing through? + std::string input = "<iq type='get' id='1'/>"; + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("", handler()->OutputActivity()); + EXPECT_EQ("", handler()->SessionActivity()); + + // continue after an ignored iq + RunPartialLogin(XLTT_STAGE_SESSION_SUCCESS, XLTT_STAGE_SESSION_SUCCESS); +} + +TEST_F(XmppLoginTaskTest, TestBadXml) { + int errorKind = 0; + for (XlttStage stage = XLTT_STAGE_CONNECT; + stage <= XLTT_STAGE_SESSION_SUCCESS; + stage = static_cast<XlttStage>(stage + 1)) { + RunPartialLogin(XLTT_STAGE_CONNECT, stage); + + std::string input; + switch (errorKind++ % 5) { + case 0: input = "&syntax;"; break; + case 1: input = "<nons:iq/>"; break; + case 2: input = "<iq a='b' a='dupe'/>"; break; + case 3: input = "<>"; break; + case 4: input = "<iq a='<wrong>'>"; break; + } + + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-XML]", handler()->SessionActivity()); + + TearDown(); + SetUp(); + } +} + +TEST_F(XmppLoginTaskTest, TestStreamError) { + for (XlttStage stage = XLTT_STAGE_CONNECT; + stage <= XLTT_STAGE_SESSION_SUCCESS; + stage = static_cast<XlttStage>(stage + 1)) { + switch (stage) { + case XLTT_STAGE_CONNECT: + case XLTT_STAGE_TLS_PROCEED: + case XLTT_STAGE_AUTH_SUCCESS: + continue; + default: + break; + } + + RunPartialLogin(XLTT_STAGE_CONNECT, stage); + + std::string input = "<stream:error>" + "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>" + "<text xml:lang='en' xmlns='urn:ietf:params:xml:ns:xmpp-streams'>" + "Some special application diagnostic information!" + "</text>" + "<escape-your-data xmlns='application-ns'/>" + "</stream:error>"; + + engine()->HandleInput(input.c_str(), input.length()); + + EXPECT_EQ("[CLOSED]", handler()->OutputActivity()); + EXPECT_EQ("[CLOSED][ERROR-STREAM]", handler()->SessionActivity()); + + EXPECT_EQ("<str:error xmlns:str=\"http://etherx.jabber.org/streams\">" + "<xml-not-well-formed xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\"/>" + "<text xml:lang=\"en\" xmlns=\"urn:ietf:params:xml:ns:xmpp-streams\">" + "Some special application diagnostic information!" + "</text>" + "<escape-your-data xmlns=\"application-ns\"/>" + "</str:error>", engine()->GetStreamError()->Str()); + + TearDown(); + SetUp(); + } +} +
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc new file mode 100644 index 0000000..278b988 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.cc
@@ -0,0 +1,89 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h" + +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/webrtc/base/common.h" +#ifdef EXPAT_RELATIVE_PATH +#include "expat.h" +#else +#include "third_party/expat/v2_0_1/Source/lib/expat.h" +#endif + +namespace buzz { + +XmppStanzaParser::XmppStanzaParser(XmppStanzaParseHandler *psph) : + psph_(psph), + innerHandler_(this), + parser_(&innerHandler_), + depth_(0), + builder_() { +} + +void +XmppStanzaParser::Reset() { + parser_.Reset(); + depth_ = 0; + builder_.Reset(); +} + +void +XmppStanzaParser::IncomingStartElement( + XmlParseContext * pctx, const char * name, const char ** atts) { + if (depth_++ == 0) { + XmlElement * pelStream = XmlBuilder::BuildElement(pctx, name, atts); + if (pelStream == NULL) { + pctx->RaiseError(XML_ERROR_SYNTAX); + return; + } + psph_->StartStream(pelStream); + delete pelStream; + return; + } + + builder_.StartElement(pctx, name, atts); +} + +void +XmppStanzaParser::IncomingCharacterData( + XmlParseContext * pctx, const char * text, int len) { + if (depth_ > 1) { + builder_.CharacterData(pctx, text, len); + } +} + +void +XmppStanzaParser::IncomingEndElement( + XmlParseContext * pctx, const char * name) { + if (--depth_ == 0) { + psph_->EndStream(); + return; + } + + builder_.EndElement(pctx, name); + + if (depth_ == 1) { + XmlElement *element = builder_.CreateElement(); + psph_->Stanza(element); + delete element; + } +} + +void +XmppStanzaParser::IncomingError( + XmlParseContext * pctx, XML_Error errCode) { + RTC_UNUSED(pctx); + RTC_UNUSED(errCode); + psph_->XmlError(); +} + +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h new file mode 100644 index 0000000..0c67bf1 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h
@@ -0,0 +1,80 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_ + +#include "third_party/libjingle_xmpp/xmllite/xmlbuilder.h" +#include "third_party/libjingle_xmpp/xmllite/xmlparser.h" + + +namespace buzz { + +class XmlElement; + +class XmppStanzaParseHandler { +public: + virtual ~XmppStanzaParseHandler() {} + virtual void StartStream(const XmlElement * pelStream) = 0; + virtual void Stanza(const XmlElement * pelStanza) = 0; + virtual void EndStream() = 0; + virtual void XmlError() = 0; +}; + +class XmppStanzaParser { +public: + XmppStanzaParser(XmppStanzaParseHandler *psph); + bool Parse(const char * data, size_t len, bool isFinal) + { return parser_.Parse(data, len, isFinal); } + void Reset(); + +private: + class ParseHandler : public XmlParseHandler { + public: + ParseHandler(XmppStanzaParser * outer) : outer_(outer) {} + virtual void StartElement(XmlParseContext * pctx, + const char * name, const char ** atts) + { outer_->IncomingStartElement(pctx, name, atts); } + virtual void EndElement(XmlParseContext * pctx, + const char * name) + { outer_->IncomingEndElement(pctx, name); } + virtual void CharacterData(XmlParseContext * pctx, + const char * text, int len) + { outer_->IncomingCharacterData(pctx, text, len); } + virtual void Error(XmlParseContext * pctx, + XML_Error errCode) + { outer_->IncomingError(pctx, errCode); } + private: + XmppStanzaParser * const outer_; + }; + + friend class ParseHandler; + + void IncomingStartElement(XmlParseContext * pctx, + const char * name, const char ** atts); + void IncomingEndElement(XmlParseContext * pctx, + const char * name); + void IncomingCharacterData(XmlParseContext * pctx, + const char * text, int len); + void IncomingError(XmlParseContext * pctx, + XML_Error errCode); + + XmppStanzaParseHandler * psph_; + ParseHandler innerHandler_; + XmlParser parser_; + int depth_; + XmlBuilder builder_; + + }; + + +} + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPSTANZAPARSER_H_
diff --git a/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc new file mode 100644 index 0000000..109701b3 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmppstanzaparser_unittest.cc
@@ -0,0 +1,175 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <iostream> +#include <sstream> +#include <string> +#include "third_party/libjingle_xmpp/xmllite/xmlelement.h" +#include "third_party/libjingle_xmpp/xmpp/xmppstanzaparser.h" +#include "third_party/webrtc/base/common.h" +#include "third_party/webrtc/base/gunit.h" + +using buzz::QName; +using buzz::XmlElement; +using buzz::XmppStanzaParser; +using buzz::XmppStanzaParseHandler; + +class XmppStanzaParserTestHandler : public XmppStanzaParseHandler { + public: + virtual void StartStream(const XmlElement * element) { + ss_ << "START" << element->Str(); + } + virtual void Stanza(const XmlElement * element) { + ss_ << "STANZA" << element->Str(); + } + virtual void EndStream() { + ss_ << "END"; + } + virtual void XmlError() { + ss_ << "ERROR"; + } + + std::string Str() { + return ss_.str(); + } + + std::string StrClear() { + std::string result = ss_.str(); + ss_.str(""); + return result; + } + + private: + std::stringstream ss_; +}; + + +TEST(XmppStanzaParserTest, TestTrivial) { + XmppStanzaParserTestHandler handler; + XmppStanzaParser parser(&handler); + std::string fragment; + + fragment = "<trivial/>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<trivial/>END", handler.StrClear()); +} + +TEST(XmppStanzaParserTest, TestStanzaAtATime) { + XmppStanzaParserTestHandler handler; + XmppStanzaParser parser(&handler); + std::string fragment; + + fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " + "xmlns:stream=\"str\"/>", handler.StrClear()); + + fragment = "<message type='foo'><body>hello</body></message>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" + "<c:body>hello</c:body></c:message>", handler.StrClear()); + + fragment = " SOME TEXT TO IGNORE "; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = "<iq type='set' id='123'><abc xmlns='def'/></iq>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("STANZA<c:iq type=\"set\" id=\"123\" xmlns:c=\"j:c\">" + "<abc xmlns=\"def\"/></c:iq>", handler.StrClear()); + + fragment = "</stream:stream>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("END", handler.StrClear()); +} + +TEST(XmppStanzaParserTest, TestFragmentedStanzas) { + XmppStanzaParserTestHandler handler; + XmppStanzaParser parser(&handler); + std::string fragment; + + fragment = "<stream:stream id='abc' xmlns='j:c' xml"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = "ns:stream='str'><message type='foo'><body>hel"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " + "xmlns:stream=\"str\"/>", handler.StrClear()); + + fragment = "lo</body></message> IGNORE ME <iq type='set' id='123'>" + "<abc xmlns='def'/></iq></st"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" + "<c:body>hello</c:body></c:message>STANZA<c:iq type=\"set\" id=\"123\" " + "xmlns:c=\"j:c\"><abc xmlns=\"def\"/></c:iq>", handler.StrClear()); + + fragment = "ream:stream>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("END", handler.StrClear()); +} + +TEST(XmppStanzaParserTest, TestReset) { + XmppStanzaParserTestHandler handler; + XmppStanzaParser parser(&handler); + std::string fragment; + + fragment = "<stream:stream id='abc' xmlns='j:c' xml"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + parser.Reset(); + fragment = "<stream:stream id='abc' xmlns='j:c' xml"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("", handler.StrClear()); + + fragment = "ns:stream='str'><message type='foo'><body>hel"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " + "xmlns:stream=\"str\"/>", handler.StrClear()); + parser.Reset(); + + fragment = "<stream:stream id='abc' xmlns='j:c' xmlns:stream='str'>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<stream:stream id=\"abc\" xmlns=\"j:c\" " + "xmlns:stream=\"str\"/>", handler.StrClear()); + + fragment = "<message type='foo'><body>hello</body></message>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("STANZA<c:message type=\"foo\" xmlns:c=\"j:c\">" + "<c:body>hello</c:body></c:message>", handler.StrClear()); +} + +TEST(XmppStanzaParserTest, TestError) { + XmppStanzaParserTestHandler handler; + XmppStanzaParser parser(&handler); + std::string fragment; + + fragment = "<-foobar/>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("ERROR", handler.StrClear()); + + parser.Reset(); + fragment = "<stream:stream/>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("ERROR", handler.StrClear()); + parser.Reset(); + + fragment = "ns:stream='str'><message type='foo'><body>hel"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("ERROR", handler.StrClear()); + parser.Reset(); + + fragment = "<stream:stream xmlns:stream='st' xmlns='jc'>" + "<foo/><bar><st:foobar/></bar>"; + parser.Parse(fragment.c_str(), fragment.length(), false); + EXPECT_EQ("START<stream:stream xmlns:stream=\"st\" xmlns=\"jc\"/>STANZA" + "<jc:foo xmlns:jc=\"jc\"/>ERROR", handler.StrClear()); +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpptask.cc b/third_party/libjingle_xmpp/xmpp/xmpptask.cc new file mode 100644 index 0000000..40b6e53a --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmpptask.cc
@@ -0,0 +1,158 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "third_party/libjingle_xmpp/xmpp/constants.h" +#include "third_party/libjingle_xmpp/xmpp/xmppclient.h" +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/libjingle_xmpp/xmpp/xmpptask.h" + +namespace buzz { + +XmppClientInterface::XmppClientInterface() { +} + +XmppClientInterface::~XmppClientInterface() { +} + +XmppTask::XmppTask(XmppTaskParentInterface* parent, + XmppEngine::HandlerLevel level) + : XmppTaskBase(parent), stopped_(false) { +#if !defined(NDEBUG) + debug_force_timeout_ = false; +#endif + + id_ = GetClient()->NextId(); + GetClient()->AddXmppTask(this, level); + GetClient()->SignalDisconnected.connect(this, &XmppTask::OnDisconnect); +} + +XmppTask::~XmppTask() { + StopImpl(); +} + +void XmppTask::StopImpl() { + while (NextStanza() != NULL) {} + if (!stopped_) { + GetClient()->RemoveXmppTask(this); + GetClient()->SignalDisconnected.disconnect(this); + stopped_ = true; + } +} + +XmppReturnStatus XmppTask::SendStanza(const XmlElement* stanza) { + if (stopped_) + return XMPP_RETURN_BADSTATE; + return GetClient()->SendStanza(stanza); +} + +XmppReturnStatus XmppTask::SendStanzaError(const XmlElement* element_original, + XmppStanzaError code, + const std::string& text) { + if (stopped_) + return XMPP_RETURN_BADSTATE; + return GetClient()->SendStanzaError(element_original, code, text); +} + +void XmppTask::Stop() { + StopImpl(); + Task::Stop(); +} + +void XmppTask::OnDisconnect() { + Error(); +} + +void XmppTask::QueueStanza(const XmlElement* stanza) { +#if !defined(NDEBUG) + if (debug_force_timeout_) + return; +#endif + + stanza_queue_.push_back(new XmlElement(*stanza)); + Wake(); +} + +const XmlElement* XmppTask::NextStanza() { + XmlElement* result = NULL; + if (!stanza_queue_.empty()) { + result = stanza_queue_.front(); + stanza_queue_.pop_front(); + } + next_stanza_.reset(result); + return result; +} + +XmlElement* XmppTask::MakeIq(const std::string& type, + const buzz::Jid& to, + const std::string& id) { + XmlElement* result = new XmlElement(QN_IQ); + if (!type.empty()) + result->AddAttr(QN_TYPE, type); + if (!to.IsEmpty()) + result->AddAttr(QN_TO, to.Str()); + if (!id.empty()) + result->AddAttr(QN_ID, id); + return result; +} + +XmlElement* XmppTask::MakeIqResult(const XmlElement * query) { + XmlElement* result = new XmlElement(QN_IQ); + result->AddAttr(QN_TYPE, STR_RESULT); + if (query->HasAttr(QN_FROM)) { + result->AddAttr(QN_TO, query->Attr(QN_FROM)); + } + result->AddAttr(QN_ID, query->Attr(QN_ID)); + return result; +} + +bool XmppTask::MatchResponseIq(const XmlElement* stanza, + const Jid& to, + const std::string& id) { + if (stanza->Name() != QN_IQ) + return false; + + if (stanza->Attr(QN_ID) != id) + return false; + + return MatchStanzaFrom(stanza, to); +} + +bool XmppTask::MatchStanzaFrom(const XmlElement* stanza, + const Jid& to) { + Jid from(stanza->Attr(QN_FROM)); + if (from == to) + return true; + + // We address the server as "", check if we are doing so here. + if (!to.IsEmpty()) + return false; + + // It is legal for the server to identify itself with "domain" or + // "myself@domain" + Jid me = GetClient()->jid(); + return (from == Jid(me.domain())) || (from == me.BareJid()); +} + +bool XmppTask::MatchRequestIq(const XmlElement* stanza, + const std::string& type, + const QName& qn) { + if (stanza->Name() != QN_IQ) + return false; + + if (stanza->Attr(QN_TYPE) != type) + return false; + + if (stanza->FirstNamed(qn) == NULL) + return false; + + return true; +} + +}
diff --git a/third_party/libjingle_xmpp/xmpp/xmpptask.h b/third_party/libjingle_xmpp/xmpp/xmpptask.h new file mode 100644 index 0000000..e302686 --- /dev/null +++ b/third_party/libjingle_xmpp/xmpp/xmpptask.h
@@ -0,0 +1,175 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ +#define WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_ + +#include <deque> +#include <memory> +#include <string> + +#include "third_party/libjingle_xmpp/xmpp/xmppengine.h" +#include "third_party/webrtc/base/constructormagic.h" +#include "third_party/webrtc/base/sigslot.h" +#include "third_party/webrtc/base/task.h" +#include "third_party/webrtc/base/taskparent.h" + +namespace buzz { + +///////////////////////////////////////////////////////////////////// +// +// XMPPTASK +// +///////////////////////////////////////////////////////////////////// +// +// See Task and XmppClient first. +// +// XmppTask is a task that is designed to go underneath XmppClient and be +// useful there. It has a way of finding its XmppClient parent so you +// can have it nested arbitrarily deep under an XmppClient and it can +// still find the XMPP services. +// +// Tasks register themselves to listen to particular kinds of stanzas +// that are sent out by the client. Rather than processing stanzas +// right away, they should decide if they own the sent stanza, +// and if so, queue it and Wake() the task, or if a stanza does not belong +// to you, return false right away so the next XmppTask can take a crack. +// This technique (synchronous recognize, but asynchronous processing) +// allows you to have arbitrary logic for recognizing stanzas yet still, +// for example, disconnect a client while processing a stanza - +// without reentrancy problems. +// +///////////////////////////////////////////////////////////////////// + +class XmppTask; + +// XmppClientInterface is an abstract interface for sending and +// handling stanzas. It can be implemented for unit tests or +// different network environments. It will usually be implemented by +// XmppClient. +class XmppClientInterface { + public: + XmppClientInterface(); + virtual ~XmppClientInterface(); + + virtual XmppEngine::State GetState() const = 0; + virtual const Jid& jid() const = 0; + virtual std::string NextId() = 0; + virtual XmppReturnStatus SendStanza(const XmlElement* stanza) = 0; + virtual XmppReturnStatus SendStanzaError(const XmlElement* original_stanza, + XmppStanzaError error_code, + const std::string& message) = 0; + virtual void AddXmppTask(XmppTask* task, XmppEngine::HandlerLevel level) = 0; + virtual void RemoveXmppTask(XmppTask* task) = 0; + sigslot::signal0<> SignalDisconnected; + + RTC_DISALLOW_COPY_AND_ASSIGN(XmppClientInterface); +}; + +// XmppTaskParentInterface is the interface require for any parent of +// an XmppTask. It needs, for example, a way to get an +// XmppClientInterface. + +// We really ought to inherit from a TaskParentInterface, but we tried +// that and it's way too complicated to change +// Task/TaskParent/TaskRunner. For now, this works. +class XmppTaskParentInterface : public rtc::Task { + public: + explicit XmppTaskParentInterface(rtc::TaskParent* parent) + : Task(parent) { + } + virtual ~XmppTaskParentInterface() {} + + virtual XmppClientInterface* GetClient() = 0; + + RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskParentInterface); +}; + +class XmppTaskBase : public XmppTaskParentInterface { + public: + explicit XmppTaskBase(XmppTaskParentInterface* parent) + : XmppTaskParentInterface(parent), + parent_(parent) { + } + virtual ~XmppTaskBase() {} + + virtual XmppClientInterface* GetClient() { + return parent_->GetClient(); + } + + protected: + XmppTaskParentInterface* parent_; + + RTC_DISALLOW_COPY_AND_ASSIGN(XmppTaskBase); +}; + +class XmppTask : public XmppTaskBase, + public XmppStanzaHandler, + public sigslot::has_slots<> +{ + public: + XmppTask(XmppTaskParentInterface* parent, + XmppEngine::HandlerLevel level = XmppEngine::HL_NONE); + virtual ~XmppTask(); + + std::string task_id() const { return id_; } + void set_task_id(std::string id) { id_ = id; } + +#if !defined(NDEBUG) + void set_debug_force_timeout(const bool f) { debug_force_timeout_ = f; } +#endif + + virtual bool HandleStanza(const XmlElement* stanza) { return false; } + + protected: + XmppReturnStatus SendStanza(const XmlElement* stanza); + XmppReturnStatus SetResult(const std::string& code); + XmppReturnStatus SendStanzaError(const XmlElement* element_original, + XmppStanzaError code, + const std::string& text); + + virtual void Stop(); + virtual void OnDisconnect(); + + virtual void QueueStanza(const XmlElement* stanza); + const XmlElement* NextStanza(); + + bool MatchStanzaFrom(const XmlElement* stanza, const Jid& match_jid); + + bool MatchResponseIq(const XmlElement* stanza, const Jid& to, + const std::string& task_id); + + static bool MatchRequestIq(const XmlElement* stanza, const std::string& type, + const QName& qn); + static XmlElement *MakeIqResult(const XmlElement* query); + static XmlElement *MakeIq(const std::string& type, + const Jid& to, const std::string& task_id); + + // Returns true if the task is under the specified rate limit and updates the + // rate limit accordingly + bool VerifyTaskRateLimit(const std::string task_name, int max_count, + int per_x_seconds); + +private: + void StopImpl(); + + bool stopped_; + std::deque<XmlElement*> stanza_queue_; + std::unique_ptr<XmlElement> next_stanza_; + std::string id_; + +#if !defined(NDEBUG) + bool debug_force_timeout_; +#endif +}; + +} // namespace buzz + +#endif // WEBRTC_LIBJINGLE_XMPP_XMPPTASK_H_
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py index dc2629f..d4c691c7 100644 --- a/tools/perf/page_sets/system_health/browsing_stories.py +++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -89,7 +89,6 @@ repeat_count=self.MAIN_PAGE_SCROLL_REPEAT) -@decorators.Disabled('android') # crbug.com/676338 class CnnStory(_NewsBrowsingStory): """The second top website in http://www.alexa.com/topsites/category/News""" NAME = 'browse:news:cnn'
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc index 76ecba7..344951e 100644 --- a/ui/base/clipboard/clipboard_win.cc +++ b/ui/base/clipboard/clipboard_win.cc
@@ -616,8 +616,7 @@ 1.0f, false); { - skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas()); - HDC dc = scoped_platform_paint.GetNativeDrawingContext(); + HDC dc = skia::GetNativeDrawingContext(canvas.sk_canvas()); ::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, 0, 0, 0, bitmap->bmiHeader.biHeight, bitmap_bits, bitmap,
diff --git a/ui/gfx/canvas_paint_mac.mm b/ui/gfx/canvas_paint_mac.mm index f29a6af..9d2bbb3 100644 --- a/ui/gfx/canvas_paint_mac.mm +++ b/ui/gfx/canvas_paint_mac.mm
@@ -25,9 +25,8 @@ canvas->restoreToCount(1); // Blit the dirty rect to the current context. - skia::ScopedPlatformPaint spp(canvas); CGImageRef image = - CGBitmapContextCreateImage(spp.GetNativeDrawingContext()); + CGBitmapContextCreateImage(skia::GetNativeDrawingContext(canvas)); CGRect dest_rect = NSRectToCGRect(rectangle_); CGContextRef destination_context =
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc index e811036b..46108aad 100644 --- a/ui/native_theme/native_theme_win.cc +++ b/ui/native_theme/native_theme_win.cc
@@ -278,8 +278,7 @@ break; } - skia::ScopedPlatformPaint paint(canvas); - HDC surface = paint.GetNativeDrawingContext(); + HDC surface = skia::GetNativeDrawingContext(canvas); // When drawing the task manager or the bookmark editor, we draw into an // offscreen buffer, where we can use OS-specific drawing routines for