Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/new arch #427

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
78bbe2c
Add newArch enabled build property
tvanlaerhoven Sep 3, 2024
9010f73
Add support for Fabric
tvanlaerhoven Sep 3, 2024
670646a
Add support for Fabric events
tvanlaerhoven Sep 3, 2024
cf4ecbc
Initialize after view is attached
tvanlaerhoven Sep 3, 2024
96d9d89
Upgrade dependency
tvanlaerhoven Sep 3, 2024
9e0b762
Enable newArch by default
tvanlaerhoven Sep 3, 2024
65ff511
Enabled bridgeless by default
tvanlaerhoven Sep 3, 2024
19401cb
Add missing implementation for daiSetSnapback for setup without ad fe…
wvanhaevre Sep 3, 2024
4a0e841
Update bundle setup
wvanhaevre Sep 4, 2024
b2a55b8
Apply newer native app setup
wvanhaevre Sep 4, 2024
3296f25
Update podfile
wvanhaevre Sep 4, 2024
8c4c61a
Update iOS project
wvanhaevre Sep 4, 2024
93d97e0
add ios pod scripts to package.json
wvanhaevre Sep 11, 2024
0bec3db
Bump slider version and prevent it from autolinking for tvOS.
wvanhaevre Sep 11, 2024
6d486fb
Fix fullscreen on Android
tvanlaerhoven Sep 16, 2024
328d04b
Drop local file
tvanlaerhoven Oct 24, 2024
f2e6eff
Simplify viewResolver
tvanlaerhoven Oct 24, 2024
820737e
Update iOS e2e project
tvanlaerhoven Oct 24, 2024
f5aeb42
Modify e2e project
tvanlaerhoven Oct 24, 2024
1c6fb9a
Enable e2e pipeline for newArch
tvanlaerhoven Nov 18, 2024
7a16c5c
Add pipeline description
tvanlaerhoven Nov 19, 2024
2b2d493
Add slider pod dependency for iOS only
wvanhaevre Nov 21, 2024
1abfce4
Add useful pod install/update scripts to package
wvanhaevre Nov 21, 2024
53490e5
Increase time-out
tvanlaerhoven Nov 25, 2024
c288060
Add extra logging during error
tvanlaerhoven Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
10 changes: 9 additions & 1 deletion .github/workflows/pr_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ jobs:
strategy:
matrix:
api-level: [ 34 ]
name: Build for API Level ${{ matrix.api-level }}
newArchEnabled: [ false, true ]
name: Build for API Level ${{ matrix.api-level }} using ${{matrix.newArchEnabled == true && 'New' || 'Old' }} Architecture
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -77,6 +78,13 @@ jobs:
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Modify gradle.properties for newArchEnabled
working-directory: e2e/android
run: |
# Modify or add the newArchEnabled property in gradle.properties
echo "newArchEnabled=${{ matrix.newArchEnabled }}" >> ./gradle.properties
cat ./gradle.properties

- name: Run e2e tests
uses: reactivecircus/android-emulator-runner@v2
with:
Expand Down
22 changes: 18 additions & 4 deletions .github/workflows/pr_ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ on:

jobs:
build:
runs-on: macos-latest
strategy:
matrix:
xcode_version: [ '15.4.0' ]
newArchEnabled: [ 0, 1 ]
platform: [iOS, tvOS]
runs-on: macos-latest
name: Build for ${{ matrix.platform }} using XCode version ${{ matrix.xcode_version }}
name: Build for ${{ matrix.platform }} using XCode version ${{ matrix.xcode_version }} and ${{matrix.newArchEnabled == 1 && 'New' || 'Old' }} Architecture

steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -34,11 +36,19 @@ jobs:
node-version: '18'
cache: 'npm'

- name: Cache Ruby Gems
uses: actions/cache@v4
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-

- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: e2e/ios/Pods
key: pods-${{ runner.os }}-${{ hashFiles('Podfile.lock') }}
key: pods-${{ runner.os }}-${{ hashFiles('Podfile.lock') }}-${{ matrix.newArchEnabled }}
restore-keys: |
pods-${{ runner.os }}-

Expand All @@ -53,10 +63,13 @@ jobs:
cd e2e
npm ci

- name: Install Ruby dependencies
run: bundle install

- name: Run pod install & update dependencies
working-directory: e2e/ios
run: |
pod update
RCT_NEW_ARCH_ENABLED=${{ matrix.newArchEnabled }} bundle exec pod update

- name: Start iOS simulator
uses: futureware-tech/simulator-action@v4
Expand All @@ -71,4 +84,5 @@ jobs:

- name: Summarize results
working-directory: e2e
if: always()
run: cat cavy_results.md >> $GITHUB_STEP_SUMMARY
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]

# Needed for `jekyll serve`
gem "webrick", "~> 1.8"

# Cocoapods 1.15 introduced a bug which breaks the build.
gem 'cocoapods', '>= 1.13', '< 1.15'
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
10 changes: 10 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ static def versionString(version) {
return "${version == '+' ? 'latest' : version}"
}

def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

// Extensions
def enabledGoogleIMA = safeExtGet("THEOplayer_extensionGoogleIMA", 'false').toBoolean()
def enabledGoogleDAI = safeExtGet("THEOplayer_extensionGoogleDAI", 'false').toBoolean()
Expand Down Expand Up @@ -69,6 +77,8 @@ android {
buildConfigField "boolean", "EXTENSION_MEDIASESSION", "${enabledMediaSession}"
buildConfigField "boolean", "EXTENSION_MEDIA3", "${enabledMedia3}"

buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()

consumerProguardFiles 'proguard-rules.pro'
}

Expand Down
12 changes: 8 additions & 4 deletions android/src/main/java/com/theoplayer/PlayerEventEmitter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.bridge.WritableNativeMap
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.common.ViewUtil
import com.facebook.react.uimanager.common.UIManagerType
import com.theoplayer.ads.AdEventAdapter
import com.theoplayer.ads.AdEventAdapter.AdEventEmitter
import com.theoplayer.android.api.THEOplayerGlobal
Expand Down Expand Up @@ -47,7 +47,6 @@ import com.theoplayer.track.*
import com.theoplayer.util.PayloadBuilder
import kotlin.math.floor


private val TAG = PlayerEventEmitter::class.java.name

private const val EVENT_PLAYER_READY = "onNativePlayerReady"
Expand Down Expand Up @@ -613,8 +612,13 @@ class PlayerEventEmitter internal constructor(
} catch (ignore: RuntimeException) {
}
}
val uiManager = UIManagerHelper.getUIManager(reactContext, ViewUtil.getUIManagerType(viewId))
uiManager?.receiveEvent(UIManagerHelper.getSurfaceId(reactContext), viewId, type, event)
UIManagerHelper.getUIManager(
reactContext,
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
UIManagerType.FABRIC
} else {
UIManagerType.DEFAULT
})?.receiveEvent(UIManagerHelper.getSurfaceId(playerView), viewId, type, event)
}

private fun attachListeners(player: Player) {
Expand Down
19 changes: 15 additions & 4 deletions android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ReactTHEOplayerView(private val reactContext: ThemedReactContext) :
var presentationManager: PresentationManager? = null
var playerContext: ReactTHEOplayerContext? = null
private var isInitialized: Boolean = false
private var config: PlayerConfigAdapter? = null

val adsApi: AdsApiWrapper

Expand All @@ -40,36 +41,46 @@ class ReactTHEOplayerView(private val reactContext: ThemedReactContext) :
adsApi = AdsApiWrapper()
}

fun initialize(configProps: ReadableMap?) {
fun initialize(config: PlayerConfigAdapter) {
if (BuildConfig.LOG_VIEW_EVENTS) {
Log.d(TAG, "Initialize view")
}
if (isInitialized) {
Log.w(TAG, "Already initialized view")
return
}
this.config = config
if (!isAttachedToWindow) {
// The view is not attached to the window yet, postpone the initialization.
return
}
isInitialized = true
playerContext = ReactTHEOplayerContext.create(
reactContext,
PlayerConfigAdapter(configProps)
config
)
playerContext?.apply {
adsApi.initialize(player, imaIntegration, daiIntegration)
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
playerView.layoutParams = layoutParams
(playerView.parent as? ViewGroup)?.removeView(playerView)
addView(playerView, 0, layoutParams)

presentationManager = PresentationManager(
this,
reactContext,
eventEmitter
)

eventEmitter.preparePlayer(player)
}
}

override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (!isInitialized) {
config?.let { initialize(it) }
}
}

override fun setId(id: Int) {
super.setId(id)
eventEmitter.setViewId(id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ReactTHEOplayerViewManager : ViewGroupManager<ReactTHEOplayerView>() {

@ReactProp(name = PROP_CONFIG)
fun setConfig(videoView: ReactTHEOplayerView, config: ReadableMap?) {
videoView.initialize(config)
videoView.initialize(PlayerConfigAdapter(config))
}

override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.Lifecycle
import com.facebook.react.ReactRootView
import com.facebook.react.runtime.ReactSurfaceView
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.views.view.ReactViewGroup
import com.theoplayer.BuildConfig
Expand Down Expand Up @@ -211,7 +212,7 @@ class PresentationManager(
// Get the player's ReactViewGroup parent, which contains THEOplayerView and its children (typically the UI).
val reactPlayerGroup: ReactViewGroup? = getClosestParentOfType(this.viewCtx.playerView)

// Get ReactNative's root node or the render hiearchy
// Get ReactNative's root node or the render hierarchy
val root: ReactRootView? = getClosestParentOfType(reactPlayerGroup)

if (fullscreen) {
Expand All @@ -223,7 +224,11 @@ class PresentationManager(
if (!BuildConfig.REPARENT_ON_FULLSCREEN) {
return
}
playerGroupParentNode = (reactPlayerGroup?.parent as ReactViewGroup?)?.also { parent ->
playerGroupParentNode = if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
reactPlayerGroup?.parent as? ReactSurfaceView?
} else {
reactPlayerGroup?.parent as? ReactViewGroup?
}?.also { parent ->
playerGroupChildIndex = parent.indexOfChild(reactPlayerGroup)
// Re-parent the playerViewGroup to the root node
parent.removeView(reactPlayerGroup)
Expand Down
23 changes: 10 additions & 13 deletions android/src/main/java/com/theoplayer/util/ViewResolver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,28 @@ package com.theoplayer.util
import android.util.Log
import android.view.View
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.UIManagerHelper

private const val TAG = "ViewResolver"
private const val INVALID_TAG = -1

@Suppress("UNCHECKED_CAST")
class ViewResolver(private val reactContext: ReactApplicationContext) {
private var uiManager: UIManagerModule? = null

fun <T: View> resolveViewByTag(tag: Int, onResolved: (view: T?) -> Unit) {
if (tag == INVALID_TAG) {
// Don't bother trying to resolve an invalid tag.
onResolved(null)
}
if (uiManager == null) {
uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
}
uiManager?.addUIBlock {
try {
onResolved(it.resolveView(tag) as? T?)
} catch (e: Exception) {
// The View instance could not be resolved: log but do not forward exception.
Log.e(TAG, "Failed to resolve View tag $tag: $e")
onResolved(null)
try {
reactContext.runOnUiQueueThread {
UIManagerHelper.getUIManagerForReactTag(reactContext, tag)?.let {
onResolved(it.resolveView(tag) as? T?)
}
}
} catch (e: Exception) {
// The ReactTHEOplayerView instance could not be resolved: log but do not forward exception.
Log.e(TAG, "Failed to resolve ReactTHEOplayerView tag $tag: $e")
onResolved(null)
}
}
}
2 changes: 1 addition & 1 deletion e2e/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
#newArchEnabled=false

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
Expand Down
1 change: 1 addition & 0 deletions e2e/ios/.xcode.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export NODE_BINARY=$(command -v node)
4 changes: 4 additions & 0 deletions e2e/ios/PodConfig.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ def google_cast_redirect
pod 'react-native-google-cast', :git => 'https://github.com/Danesz/react-native-google-cast.git', branch: 'feature/guestmode_apple_silicon'
end

def include_slider
pod 'react-native-slider', :path => '../node_modules/@react-native-community/slider'
end

def nielsen_post_install(installer, targetName)
# modify XCFramework configuration files to update NielsenAppApi.framework -> NielsenTVAppApi.framework
installer.pods_project.targets.each do |target|
Expand Down
27 changes: 19 additions & 8 deletions e2e/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
"react-native/scripts/react_native_pods.rb",
{paths: [process.argv[1]]},
)', __dir__]).strip
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative './PodConfig'
Expand All @@ -6,6 +11,9 @@ source 'https://github.com/react-native-tvos/react-native-tvos-podspecs.git'
source 'https://cdn.cocoapods.org/'
nielsen_source

prepare_react_native_project!
config = use_native_modules!

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
Expand All @@ -18,15 +26,15 @@ target 'ReactNativeTHEOplayer' do

platform :ios, '13.4'

config = use_native_modules!

use_react_native!(
:path => config[:reactNativePath]
:path => config[:reactNativePath],
:app_path => "#{Pod::Config.instance.installation_root}/.."
)

pod 'react-native-theoplayer', :path => '../..'
google_cast_redirect

include_slider

target 'ReactNativeTHEOplayerTests' do
inherit! :complete
# Pods for testing
Expand All @@ -38,10 +46,9 @@ target 'ReactNativeTHEOplayer-tvOS' do

platform :tvos, '13.4'

config = use_native_modules!

use_react_native!(
:path => config[:reactNativePath]
:path => config[:reactNativePath],
:app_path => "#{Pod::Config.instance.installation_root}/.."
)

pod 'react-native-theoplayer', :path => '../..'
Expand All @@ -54,6 +61,10 @@ target 'ReactNativeTHEOplayer-tvOS' do
end

post_install do |installer|
react_native_post_install(installer)
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false
)
nielsen_post_install(installer, "Pods-ReactNativeTHEOplayer-tvOS")
end
Loading
Loading