From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../rtc_base/java/src/org/webrtc/ContextUtils.java | 45 +++++ .../rtc_base/java/src/org/webrtc/Loggable.java | 22 +++ .../rtc_base/java/src/org/webrtc/Logging.java | 201 +++++++++++++++++++ .../libwebrtc/rtc_base/java/src/org/webrtc/OWNERS | 2 + .../rtc_base/java/src/org/webrtc/Size.java | 45 +++++ .../rtc_base/java/src/org/webrtc/ThreadUtils.java | 212 +++++++++++++++++++++ 6 files changed, 527 insertions(+) create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/ContextUtils.java create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/Loggable.java create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/Logging.java create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/OWNERS create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/Size.java create mode 100644 third_party/libwebrtc/rtc_base/java/src/org/webrtc/ThreadUtils.java (limited to 'third_party/libwebrtc/rtc_base/java') diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ContextUtils.java b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ContextUtils.java new file mode 100644 index 0000000000..e36ab72878 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ContextUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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. + */ + +package org.webrtc; + +import android.content.Context; + +/** + * Class for storing the application context and retrieving it in a static context. Similar to + * org.chromium.base.ContextUtils. + */ +public class ContextUtils { + private static final String TAG = "ContextUtils"; + private static Context applicationContext; + + /** + * Stores the application context that will be returned by getApplicationContext. This is called + * by PeerConnectionFactory.initialize. The application context must be set before creating + * a PeerConnectionFactory and must not be modified while it is alive. + */ + public static void initialize(Context applicationContext) { + if (applicationContext == null) { + throw new IllegalArgumentException( + "Application context cannot be null for ContextUtils.initialize."); + } + ContextUtils.applicationContext = applicationContext; + } + + /** + * Returns the stored application context. + * + * @deprecated crbug.com/webrtc/8937 + */ + @Deprecated + public static Context getApplicationContext() { + return applicationContext; + } +} diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Loggable.java b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Loggable.java new file mode 100644 index 0000000000..cd66aa1214 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Loggable.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2018 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. + */ + +package org.webrtc; + +import org.webrtc.Logging.Severity; + +/** + * Java interface for WebRTC logging. The default implementation uses webrtc.Logging. + * + * When injected, the Loggable will receive logging from both Java and native. + */ +public interface Loggable { + public void onLogMessage(String message, Severity severity, String tag); +} diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Logging.java b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Logging.java new file mode 100644 index 0000000000..e7a9921f4d --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Logging.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2015 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. + */ + +package org.webrtc; + +import androidx.annotation.Nullable; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.EnumSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.webrtc.Loggable; + +/** + * Java wrapper for WebRTC logging. Logging defaults to java.util.logging.Logger, but a custom + * logger implementing the Loggable interface can be injected along with a Severity. All subsequent + * log messages will then be redirected to the injected Loggable, except those with a severity lower + * than the specified severity, which will be discarded. + * + * It is also possible to switch to native logging (rtc::LogMessage) if one of the following static + * functions are called from the app: + * - Logging.enableLogThreads + * - Logging.enableLogTimeStamps + * - Logging.enableLogToDebugOutput + * + * The priority goes: + * 1. Injected loggable + * 2. Native logging + * 3. Fallback logging. + * Only one method will be used at a time. + * + * Injecting a Loggable or using any of the enable... methods requires that the native library is + * loaded, using PeerConnectionFactory.initialize. + */ +public class Logging { + private static final Logger fallbackLogger = createFallbackLogger(); + private static volatile boolean loggingEnabled; + @Nullable private static Loggable loggable; + private static Severity loggableSeverity; + + private static Logger createFallbackLogger() { + final Logger fallbackLogger = Logger.getLogger("org.webrtc.Logging"); + fallbackLogger.setLevel(Level.ALL); + return fallbackLogger; + } + + static void injectLoggable(Loggable injectedLoggable, Severity severity) { + if (injectedLoggable != null) { + loggable = injectedLoggable; + loggableSeverity = severity; + } + } + + static void deleteInjectedLoggable() { + loggable = null; + } + + // TODO(solenberg): Remove once dependent projects updated. + @Deprecated + public enum TraceLevel { + TRACE_NONE(0x0000), + TRACE_STATEINFO(0x0001), + TRACE_WARNING(0x0002), + TRACE_ERROR(0x0004), + TRACE_CRITICAL(0x0008), + TRACE_APICALL(0x0010), + TRACE_DEFAULT(0x00ff), + TRACE_MODULECALL(0x0020), + TRACE_MEMORY(0x0100), + TRACE_TIMER(0x0200), + TRACE_STREAM(0x0400), + TRACE_DEBUG(0x0800), + TRACE_INFO(0x1000), + TRACE_TERSEINFO(0x2000), + TRACE_ALL(0xffff); + + public final int level; + TraceLevel(int level) { + this.level = level; + } + } + + // Keep in sync with webrtc/rtc_base/logging.h:LoggingSeverity. + public enum Severity { LS_VERBOSE, LS_INFO, LS_WARNING, LS_ERROR, LS_NONE } + + public static void enableLogThreads() { + nativeEnableLogThreads(); + } + + public static void enableLogTimeStamps() { + nativeEnableLogTimeStamps(); + } + + // TODO(solenberg): Remove once dependent projects updated. + @Deprecated + public static void enableTracing(String path, EnumSet levels) {} + + // Enable diagnostic logging for messages of `severity` to the platform debug + // output. On Android, the output will be directed to Logcat. + // Note: this function starts collecting the output of the RTC_LOG() macros. + // TODO(bugs.webrtc.org/8491): Remove NoSynchronizedMethodCheck suppression. + @SuppressWarnings("NoSynchronizedMethodCheck") + public static synchronized void enableLogToDebugOutput(Severity severity) { + if (loggable != null) { + throw new IllegalStateException( + "Logging to native debug output not supported while Loggable is injected. " + + "Delete the Loggable before calling this method."); + } + nativeEnableLogToDebugOutput(severity.ordinal()); + loggingEnabled = true; + } + + public static void log(Severity severity, String tag, String message) { + if (tag == null || message == null) { + throw new IllegalArgumentException("Logging tag or message may not be null."); + } + if (loggable != null) { + // Filter log messages below loggableSeverity. + if (severity.ordinal() < loggableSeverity.ordinal()) { + return; + } + loggable.onLogMessage(message, severity, tag); + return; + } + + // Try native logging if no loggable is injected. + if (loggingEnabled) { + nativeLog(severity.ordinal(), tag, message); + return; + } + + // Fallback to system log. + Level level; + switch (severity) { + case LS_ERROR: + level = Level.SEVERE; + break; + case LS_WARNING: + level = Level.WARNING; + break; + case LS_INFO: + level = Level.INFO; + break; + default: + level = Level.FINE; + break; + } + fallbackLogger.log(level, tag + ": " + message); + } + + public static void d(String tag, String message) { + log(Severity.LS_INFO, tag, message); + } + + public static void e(String tag, String message) { + log(Severity.LS_ERROR, tag, message); + } + + public static void w(String tag, String message) { + log(Severity.LS_WARNING, tag, message); + } + + public static void e(String tag, String message, Throwable e) { + log(Severity.LS_ERROR, tag, message); + log(Severity.LS_ERROR, tag, e.toString()); + log(Severity.LS_ERROR, tag, getStackTraceString(e)); + } + + public static void w(String tag, String message, Throwable e) { + log(Severity.LS_WARNING, tag, message); + log(Severity.LS_WARNING, tag, e.toString()); + log(Severity.LS_WARNING, tag, getStackTraceString(e)); + } + + public static void v(String tag, String message) { + log(Severity.LS_VERBOSE, tag, message); + } + + private static String getStackTraceString(Throwable e) { + if (e == null) { + return ""; + } + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + return sw.toString(); + } + + private static native void nativeEnableLogToDebugOutput(int nativeSeverity); + private static native void nativeEnableLogThreads(); + private static native void nativeEnableLogTimeStamps(); + private static native void nativeLog(int severity, String tag, String message); +} diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/OWNERS b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/OWNERS new file mode 100644 index 0000000000..109bea2725 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/OWNERS @@ -0,0 +1,2 @@ +magjed@webrtc.org +xalep@webrtc.org diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Size.java b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Size.java new file mode 100644 index 0000000000..a711b5d2ca --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/Size.java @@ -0,0 +1,45 @@ +/* + * Copyright 2016 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. + */ + +package org.webrtc; + +/** + * Class for representing size of an object. Very similar to android.util.Size but available on all + * devices. + */ +public class Size { + public int width; + public int height; + + public Size(int width, int height) { + this.width = width; + this.height = height; + } + + @Override + public String toString() { + return width + "x" + height; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Size)) { + return false; + } + final Size otherSize = (Size) other; + return width == otherSize.width && height == otherSize.height; + } + + @Override + public int hashCode() { + // Use prime close to 2^16 to avoid collisions for normal values less than 2^16. + return 1 + 65537 * width + height; + } +} diff --git a/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ThreadUtils.java b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ThreadUtils.java new file mode 100644 index 0000000000..0c502b1bc3 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/java/src/org/webrtc/ThreadUtils.java @@ -0,0 +1,212 @@ +/* + * Copyright 2015 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. + */ + +package org.webrtc; + +import android.os.Handler; +import android.os.Looper; +import android.os.SystemClock; +import androidx.annotation.Nullable; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ThreadUtils { + /** + * Utility class to be used for checking that a method is called on the correct thread. + */ + public static class ThreadChecker { + @Nullable private Thread thread = Thread.currentThread(); + + public void checkIsOnValidThread() { + if (thread == null) { + thread = Thread.currentThread(); + } + if (Thread.currentThread() != thread) { + throw new IllegalStateException("Wrong thread"); + } + } + + public void detachThread() { + thread = null; + } + } + + /** + * Throws exception if called from other than main thread. + */ + public static void checkIsOnMainThread() { + if (Thread.currentThread() != Looper.getMainLooper().getThread()) { + throw new IllegalStateException("Not on main thread!"); + } + } + + /** + * Utility interface to be used with executeUninterruptibly() to wait for blocking operations + * to complete without getting interrupted.. + */ + public interface BlockingOperation { void run() throws InterruptedException; } + + /** + * Utility method to make sure a blocking operation is executed to completion without getting + * interrupted. This should be used in cases where the operation is waiting for some critical + * work, e.g. cleanup, that must complete before returning. If the thread is interrupted during + * the blocking operation, this function will re-run the operation until completion, and only then + * re-interrupt the thread. + */ + public static void executeUninterruptibly(BlockingOperation operation) { + boolean wasInterrupted = false; + while (true) { + try { + operation.run(); + break; + } catch (InterruptedException e) { + // Someone is asking us to return early at our convenience. We can't cancel this operation, + // but we should preserve the information and pass it along. + wasInterrupted = true; + } + } + // Pass interruption information along. + if (wasInterrupted) { + Thread.currentThread().interrupt(); + } + } + + public static boolean joinUninterruptibly(final Thread thread, long timeoutMs) { + final long startTimeMs = SystemClock.elapsedRealtime(); + long timeRemainingMs = timeoutMs; + boolean wasInterrupted = false; + while (timeRemainingMs > 0) { + try { + thread.join(timeRemainingMs); + break; + } catch (InterruptedException e) { + // Someone is asking us to return early at our convenience. We can't cancel this operation, + // but we should preserve the information and pass it along. + wasInterrupted = true; + final long elapsedTimeMs = SystemClock.elapsedRealtime() - startTimeMs; + timeRemainingMs = timeoutMs - elapsedTimeMs; + } + } + // Pass interruption information along. + if (wasInterrupted) { + Thread.currentThread().interrupt(); + } + return !thread.isAlive(); + } + + public static void joinUninterruptibly(final Thread thread) { + executeUninterruptibly(new BlockingOperation() { + @Override + public void run() throws InterruptedException { + thread.join(); + } + }); + } + + public static void awaitUninterruptibly(final CountDownLatch latch) { + executeUninterruptibly(new BlockingOperation() { + @Override + public void run() throws InterruptedException { + latch.await(); + } + }); + } + + public static boolean awaitUninterruptibly(CountDownLatch barrier, long timeoutMs) { + final long startTimeMs = SystemClock.elapsedRealtime(); + long timeRemainingMs = timeoutMs; + boolean wasInterrupted = false; + boolean result = false; + do { + try { + result = barrier.await(timeRemainingMs, TimeUnit.MILLISECONDS); + break; + } catch (InterruptedException e) { + // Someone is asking us to return early at our convenience. We can't cancel this operation, + // but we should preserve the information and pass it along. + wasInterrupted = true; + final long elapsedTimeMs = SystemClock.elapsedRealtime() - startTimeMs; + timeRemainingMs = timeoutMs - elapsedTimeMs; + } + } while (timeRemainingMs > 0); + // Pass interruption information along. + if (wasInterrupted) { + Thread.currentThread().interrupt(); + } + return result; + } + + /** + * Post `callable` to `handler` and wait for the result. + */ + public static V invokeAtFrontUninterruptibly( + final Handler handler, final Callable callable) { + if (handler.getLooper().getThread() == Thread.currentThread()) { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + // Place-holder classes that are assignable inside nested class. + class CaughtException { + Exception e; + } + class Result { + public V value; + } + final Result result = new Result(); + final CaughtException caughtException = new CaughtException(); + final CountDownLatch barrier = new CountDownLatch(1); + handler.post(new Runnable() { + @Override + public void run() { + try { + result.value = callable.call(); + } catch (Exception e) { + caughtException.e = e; + } + barrier.countDown(); + } + }); + awaitUninterruptibly(barrier); + // Re-throw any runtime exception caught inside the other thread. Since this is an invoke, add + // stack trace for the waiting thread as well. + if (caughtException.e != null) { + final RuntimeException runtimeException = new RuntimeException(caughtException.e); + runtimeException.setStackTrace( + concatStackTraces(caughtException.e.getStackTrace(), runtimeException.getStackTrace())); + throw runtimeException; + } + return result.value; + } + + /** + * Post `runner` to `handler`, at the front, and wait for completion. + */ + public static void invokeAtFrontUninterruptibly(final Handler handler, final Runnable runner) { + invokeAtFrontUninterruptibly(handler, new Callable() { + @Override + public Void call() { + runner.run(); + return null; + } + }); + } + + static StackTraceElement[] concatStackTraces( + StackTraceElement[] inner, StackTraceElement[] outer) { + final StackTraceElement[] combined = new StackTraceElement[inner.length + outer.length]; + System.arraycopy(inner, 0, combined, 0, inner.length); + System.arraycopy(outer, 0, combined, inner.length, outer.length); + return combined; + } +} -- cgit v1.2.3