Skip to content

Commit

Permalink
Merge branch 'main' into h5vcc_system_review
Browse files Browse the repository at this point in the history
  • Loading branch information
Colin Liang committed Jan 27, 2025
2 parents 5fd56a8 + 252b810 commit 8ad6dcd
Show file tree
Hide file tree
Showing 9,700 changed files with 1,219 additions and 1,225,353 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
173 changes: 173 additions & 0 deletions base/message_loop/message_pump_ui_starboard.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "base/message_loop/message_pump_ui_starboard.h"

#include "base/logging.h"
#include "base/time/time.h"
#include "starboard/event.h"
#include "starboard/system.h"

namespace base {

namespace {

void CallMessagePumpImmediate(void* context) {
DCHECK(context);
MessagePumpUIStarboard* pump =
reinterpret_cast<MessagePumpUIStarboard*>(context);
pump->CancelImmediate();
pump->RunUntilIdle();
}

void CallMessagePumpDelayed(void* context) {
DCHECK(context);
MessagePumpUIStarboard* pump =
reinterpret_cast<MessagePumpUIStarboard*>(context);
pump->CancelDelayed();
pump->RunUntilIdle();
}

} // namespace

MessagePumpUIStarboard::MessagePumpUIStarboard() : delegate_(nullptr) {}

void MessagePumpUIStarboard::CancelDelayed() {
base::AutoLock auto_lock(outstanding_events_lock_);
CancelDelayedLocked();
}

void MessagePumpUIStarboard::CancelImmediate() {
base::AutoLock auto_lock(outstanding_events_lock_);
CancelImmediateLocked();
}

void MessagePumpUIStarboard::RunUntilIdle() {
DCHECK(delegate_);
#if !defined(COBALT_BUILD_TYPE_GOLD)
// Abort if this is a QA build to signal that this is unexpected.
CHECK(delegate_);
#endif

if (should_quit())
return;

for (;;) {
// Do some work and see if the next task is ready right away.
Delegate::NextWorkInfo next_work_info = delegate_->DoWork();
bool attempt_more_work = next_work_info.is_immediate();

if (should_quit())
break;

if (attempt_more_work)
continue;

attempt_more_work = delegate_->DoIdleWork();

if (should_quit())
break;

if (attempt_more_work)
continue;

// If there is delayed work.
if (!next_work_info.delayed_run_time.is_max()) {
ScheduleDelayedWork(next_work_info);
}

// Idle.
break;
}
}

void MessagePumpUIStarboard::Run(Delegate* delegate) {
// This should never be called because we are not like a normal message pump
// where we loop until told to quit. We are providing a MessagePump interface
// on top of an externally-owned message pump. We want to exist and be able to
// schedule work, but the actual for(;;) loop is owned by Starboard.
NOTREACHED();
}

void MessagePumpUIStarboard::Attach(Delegate* delegate) {
// Since the Looper is controlled by the UI thread or JavaHandlerThread, we
// can't use Run() like we do on other platforms or we would prevent Java
// tasks from running. Instead we create and initialize a run loop here, then
// return control back to the Looper.

SetDelegate(delegate);
}

void MessagePumpUIStarboard::Quit() {
delegate_ = nullptr;
CancelAll();
}

void MessagePumpUIStarboard::ScheduleWork() {
// Check if outstanding event already exists.
if (outstanding_event_)
return;

base::AutoLock auto_lock(outstanding_events_lock_);
outstanding_event_ =
SbEventSchedule(&CallMessagePumpImmediate, this, 0);
}

void MessagePumpUIStarboard::ScheduleDelayedWork(
const Delegate::NextWorkInfo& next_work_info) {
if (next_work_info.is_immediate() || next_work_info.delayed_run_time.is_max()) {
return;
}

TimeDelta delay = next_work_info.remaining_delay();
if (delay.is_negative()) {
delay = base::TimeDelta();
}

base::AutoLock auto_lock(outstanding_events_lock_);
// Make sure any outstanding delayed event is canceled.
CancelDelayedLocked();
outstanding_delayed_event_ =
SbEventSchedule(&CallMessagePumpDelayed, this, delay.InMicroseconds());
}

void MessagePumpUIStarboard::CancelAll() {
base::AutoLock auto_lock(outstanding_events_lock_);
CancelImmediateLocked();
CancelDelayedLocked();
}

void MessagePumpUIStarboard::CancelImmediateLocked() {
outstanding_events_lock_.AssertAcquired();
if (!outstanding_event_)
return;

SbEventCancel(*outstanding_event_);
outstanding_event_.reset();
}

void MessagePumpUIStarboard::CancelDelayedLocked() {
outstanding_events_lock_.AssertAcquired();
if (!outstanding_delayed_event_)
return;

SbEventCancel(*outstanding_delayed_event_);
outstanding_delayed_event_.reset();
}

MessagePump::Delegate* MessagePumpForUI::SetDelegate(Delegate* delegate) {
return std::exchange(delegate_, delegate);
}

} // namespace base
103 changes: 103 additions & 0 deletions base/message_loop/message_pump_ui_starboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef BASE_MESSAGE_PUMP_UI_STARBOARD_H_
#define BASE_MESSAGE_PUMP_UI_STARBOARD_H_

#include <set>

#include "base/base_export.h"
#include "base/message_loop/message_pump.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "starboard/event.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace base {

// MessagePump that integrates with the Starboard message pump. Starboard has
// its own main loop, so the MessagePumpUIStarboard just piggybacks on that
// rather than implementing its own pump.
//
// To adopt Starboard's message pump, one simply has to create a MessageLoop of
// TYPE_UI from the Starboard message pump thread. A traditional place to do
// this would be in the kSbEventStart event handler. One has to be sure to keep
// the MessageLoop alive for as long as the application wants to use the
// Starboard message pump as a MessageLoop. That would typically be for the
// entire lifetime of the application, and in that case, the MessageLoop would
// traditionally be deleted in the kSbEventStop handler.
class BASE_EXPORT MessagePumpUIStarboard : public MessagePump {
public:
MessagePumpUIStarboard();
virtual ~MessagePumpUIStarboard() { Quit(); }

MessagePumpUIStarboard(const MessagePumpUIStarboard&) = delete;
MessagePumpUIStarboard& operator=(const MessagePumpUIStarboard&) = delete;

// Cancels delayed schedule callback events.
void CancelDelayed();

// Cancels immediate schedule callback events.
void CancelImmediate();

// Runs one iteration of the run loop, and schedules another iteration if
// necessary.
void RunUntilIdle();

// --- MessagePump Implementation ---

virtual void Run(Delegate* delegate) override;
virtual void Quit() override;
virtual void ScheduleWork() override;
virtual void ScheduleDelayedWork(
const Delegate::NextWorkInfo& next_work_info) override;

// Attaches |delegate| to this native MessagePump. |delegate| will from then
// on be invoked by the native loop to process application tasks.
virtual void Attach(Delegate* delegate);

protected:
Delegate* SetDelegate(Delegate* delegate);

private:
// Cancels all outstanding scheduled callback events, if any.
void CancelAll();

// Cancel workhorse that assumes |outstanding_events_lock_| is locked.
void CancelImmediateLocked();

// Cancel delayed workhorse that assumes |outstanding_events_lock_| is locked.
void CancelDelayedLocked();

// If the delegate has been removed, Quit() has been called.
bool should_quit() const { return delegate_ == nullptr; }

// The MessagePump::Delegate configured in Start().
Delegate* delegate_;

// Lock protecting outstanding scheduled callback events.
base::Lock outstanding_events_lock_;

// The set of outstanding scheduled callback events for immediate work.
absl::optional<SbEventId> outstanding_event_;

// The set of outstanding scheduled callback events for delayed work.
absl::optional<SbEventId> outstanding_delayed_event_;
};

using MessagePumpForUI = MessagePumpUIStarboard;

} // namespace base

#endif // BASE_MESSAGE_PUMP_UI_STARBOARD_H_
6 changes: 5 additions & 1 deletion cobalt/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ jinja_template("cobalt_manifest") {
}

generate_jni("jni_headers") {
sources = [ "apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java" ]
sources = [
"apk/app/src/main/java/dev/cobalt/coat/CobaltTextToSpeechHelper.java",
"apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java",
]
}

generate_jni("content_shell_jni_headers") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
import android.speech.tts.TextToSpeech;
import android.view.accessibility.AccessibilityManager;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
import java.util.ArrayList;
import java.util.List;
import org.chromium.base.annotations.CalledByNative;
// import org.chromium.base.annotations.NativeMethods;

/**
* Helper class to implement the SbSpeechSynthesis* Starboard API for Audio accessibility.
Expand Down Expand Up @@ -92,7 +93,7 @@ public void run() {

/** Returns whether a screen reader is currently enabled */
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
public boolean isScreenReaderEnabled() {
AccessibilityManager am =
(AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
Expand Down Expand Up @@ -127,9 +128,8 @@ public void run() {
* of Starboard's SbSpeechSynthesisSpeak.
*/
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
void speak(final String text) {

handler.post(
new Runnable() {
@Override
Expand Down Expand Up @@ -162,7 +162,7 @@ public void run() {

/** Cancels all speaking. Java-layer implementation of Starboard's SbSpeechSynthesisCancel. */
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
void cancel() {
handler.post(
new Runnable() {
Expand Down Expand Up @@ -199,9 +199,14 @@ public void onTouchExplorationStateChanged(boolean enabled) {
private void finishIfScreenReaderChanged() {
if (wasScreenReaderEnabled != isScreenReaderEnabled()) {
wasScreenReaderEnabled = isScreenReaderEnabled();
nativeSendTTSChangedEvent();
// TODO: (cobalt b/392178584) clean up speech synthesis code, investigate if this is still needed.
// CobaltTextToSpeechHelperJni.get().sendTTSChangedEvent();
}
}

private native void nativeSendTTSChangedEvent();
// TODO: (cobalt b/392178584) clean up speech synthesis code, investigate if this is still needed.
// @NativeMethods
// interface Natives {
// void sendTTSChangedEvent();
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ protected String getCacheAbsolutePath() {
// TODO: (cobalt b/372559388) remove or migrate JNI?
// Used in starboard/android/shared/speech_synthesis_speak.cc
@SuppressWarnings("unused")
@UsedByNative
@CalledByNative
CobaltTextToSpeechHelper getTextToSpeechHelper() {
if (ttsHelper == null) {
throw new IllegalArgumentException("ttsHelper cannot be null for native code");
Expand Down
Loading

0 comments on commit 8ad6dcd

Please sign in to comment.