Skip to content

Commit e9e2a11

Browse files
Merge pull request #427 from THEOplayer/feature/new_arch
Feature/new arch
2 parents 18a79c0 + c369a73 commit e9e2a11

File tree

33 files changed

+281
-401
lines changed

33 files changed

+281
-401
lines changed

.bundle/config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
BUNDLE_PATH: "vendor/bundle"
2+
BUNDLE_FORCE_RUBY_PLATFORM: 1

.github/workflows/pr_android.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ jobs:
1717
strategy:
1818
matrix:
1919
api-level: [ 34 ]
20-
name: Build for API Level ${{ matrix.api-level }}
20+
newArchEnabled: [ false, true ]
21+
name: Build for API Level ${{ matrix.api-level }} using ${{matrix.newArchEnabled == true && 'New' || 'Old' }} Architecture
2122
steps:
2223
- name: Checkout repository
2324
uses: actions/checkout@v4
@@ -77,6 +78,13 @@ jobs:
7778
disable-animations: true
7879
script: echo "Generated AVD snapshot for caching."
7980

81+
- name: Modify gradle.properties for newArchEnabled
82+
working-directory: e2e/android
83+
run: |
84+
# Modify or add the newArchEnabled property in gradle.properties
85+
echo "newArchEnabled=${{ matrix.newArchEnabled }}" >> ./gradle.properties
86+
cat ./gradle.properties
87+
8088
- name: Run e2e tests
8189
uses: reactivecircus/android-emulator-runner@v2
8290
with:

.github/workflows/pr_ios.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ on:
1313

1414
jobs:
1515
build:
16+
runs-on: macos-latest
1617
strategy:
1718
matrix:
1819
xcode_version: [ '15.4.0' ]
20+
newArchEnabled: [ 0, 1 ]
1921
platform: [iOS, tvOS]
20-
runs-on: macos-latest
21-
name: Build for ${{ matrix.platform }} using XCode version ${{ matrix.xcode_version }}
22+
name: Build for ${{ matrix.platform }} using XCode version ${{ matrix.xcode_version }} and ${{matrix.newArchEnabled == 1 && 'New' || 'Old' }} Architecture
23+
2224
steps:
2325
- name: Checkout repository
2426
uses: actions/checkout@v4
@@ -34,11 +36,19 @@ jobs:
3436
node-version: '18'
3537
cache: 'npm'
3638

39+
- name: Cache Ruby Gems
40+
uses: actions/cache@v4
41+
with:
42+
path: vendor/bundle
43+
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
44+
restore-keys: |
45+
${{ runner.os }}-gems-
46+
3747
- name: Cache CocoaPods
3848
uses: actions/cache@v4
3949
with:
4050
path: e2e/ios/Pods
41-
key: pods-${{ runner.os }}-${{ hashFiles('Podfile.lock') }}
51+
key: pods-${{ runner.os }}-${{ hashFiles('Podfile.lock') }}-${{ matrix.newArchEnabled }}
4252
restore-keys: |
4353
pods-${{ runner.os }}-
4454
@@ -53,10 +63,13 @@ jobs:
5363
cd e2e
5464
npm ci
5565
66+
- name: Install Ruby dependencies
67+
run: bundle install
68+
5669
- name: Run pod install & update dependencies
5770
working-directory: e2e/ios
5871
run: |
59-
pod update
72+
RCT_NEW_ARCH_ENABLED=${{ matrix.newArchEnabled }} bundle exec pod update
6073
6174
- name: Start iOS simulator
6275
uses: futureware-tech/simulator-action@v4
@@ -71,4 +84,5 @@ jobs:
7184

7285
- name: Summarize results
7386
working-directory: e2e
87+
if: always()
7488
run: cat cavy_results.md >> $GITHUB_STEP_SUMMARY

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
3434

3535
# Needed for `jekyll serve`
3636
gem "webrick", "~> 1.8"
37+
38+
# Cocoapods 1.15 introduced a bug which breaks the build.
39+
gem 'cocoapods', '>= 1.13', '< 1.15'
40+
gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'

android/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ static def versionString(version) {
2525
return "${version == '+' ? 'latest' : version}"
2626
}
2727

28+
def isNewArchitectureEnabled() {
29+
// To opt-in for the New Architecture, you can either:
30+
// - Set `newArchEnabled` to true inside the `gradle.properties` file
31+
// - Invoke gradle with `-newArchEnabled=true`
32+
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
33+
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
34+
}
35+
2836
// Extensions
2937
def enabledGoogleIMA = safeExtGet("THEOplayer_extensionGoogleIMA", 'false').toBoolean()
3038
def enabledGoogleDAI = safeExtGet("THEOplayer_extensionGoogleDAI", 'false').toBoolean()
@@ -69,6 +77,8 @@ android {
6977
buildConfigField "boolean", "EXTENSION_MEDIASESSION", "${enabledMediaSession}"
7078
buildConfigField "boolean", "EXTENSION_MEDIA3", "${enabledMedia3}"
7179

80+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
81+
7282
consumerProguardFiles 'proguard-rules.pro'
7383
}
7484

android/src/main/java/com/theoplayer/PlayerEventEmitter.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.facebook.react.bridge.ReactApplicationContext
88
import com.facebook.react.bridge.WritableMap
99
import com.facebook.react.bridge.WritableNativeMap
1010
import com.facebook.react.uimanager.UIManagerHelper
11-
import com.facebook.react.uimanager.common.ViewUtil
11+
import com.facebook.react.uimanager.common.UIManagerType
1212
import com.theoplayer.ads.AdEventAdapter
1313
import com.theoplayer.ads.AdEventAdapter.AdEventEmitter
1414
import com.theoplayer.android.api.THEOplayerGlobal
@@ -47,7 +47,6 @@ import com.theoplayer.track.*
4747
import com.theoplayer.util.PayloadBuilder
4848
import kotlin.math.floor
4949

50-
5150
private val TAG = PlayerEventEmitter::class.java.name
5251

5352
private const val EVENT_PLAYER_READY = "onNativePlayerReady"
@@ -613,8 +612,13 @@ class PlayerEventEmitter internal constructor(
613612
} catch (ignore: RuntimeException) {
614613
}
615614
}
616-
val uiManager = UIManagerHelper.getUIManager(reactContext, ViewUtil.getUIManagerType(viewId))
617-
uiManager?.receiveEvent(UIManagerHelper.getSurfaceId(reactContext), viewId, type, event)
615+
UIManagerHelper.getUIManager(
616+
reactContext,
617+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
618+
UIManagerType.FABRIC
619+
} else {
620+
UIManagerType.DEFAULT
621+
})?.receiveEvent(UIManagerHelper.getSurfaceId(playerView), viewId, type, event)
618622
}
619623

620624
private fun attachListeners(player: Player) {

android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class ReactTHEOplayerView(private val reactContext: ThemedReactContext) :
2626
var presentationManager: PresentationManager? = null
2727
var playerContext: ReactTHEOplayerContext? = null
2828
private var isInitialized: Boolean = false
29+
private var config: PlayerConfigAdapter? = null
2930

3031
val adsApi: AdsApiWrapper
3132

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

43-
fun initialize(configProps: ReadableMap?) {
44+
fun initialize(config: PlayerConfigAdapter) {
4445
if (BuildConfig.LOG_VIEW_EVENTS) {
4546
Log.d(TAG, "Initialize view")
4647
}
4748
if (isInitialized) {
4849
Log.w(TAG, "Already initialized view")
4950
return
5051
}
52+
this.config = config
53+
if (!isAttachedToWindow) {
54+
// The view is not attached to the window yet, postpone the initialization.
55+
return
56+
}
5157
isInitialized = true
5258
playerContext = ReactTHEOplayerContext.create(
5359
reactContext,
54-
PlayerConfigAdapter(configProps)
60+
config
5561
)
5662
playerContext?.apply {
5763
adsApi.initialize(player, imaIntegration, daiIntegration)
5864
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
5965
playerView.layoutParams = layoutParams
6066
(playerView.parent as? ViewGroup)?.removeView(playerView)
6167
addView(playerView, 0, layoutParams)
62-
6368
presentationManager = PresentationManager(
6469
this,
6570
reactContext,
6671
eventEmitter
6772
)
68-
6973
eventEmitter.preparePlayer(player)
7074
}
7175
}
7276

77+
override fun onAttachedToWindow() {
78+
super.onAttachedToWindow()
79+
if (!isInitialized) {
80+
config?.let { initialize(it) }
81+
}
82+
}
83+
7384
override fun setId(id: Int) {
7485
super.setId(id)
7586
eventEmitter.setViewId(id)

android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ReactTHEOplayerViewManager : ViewGroupManager<ReactTHEOplayerView>() {
3131

3232
@ReactProp(name = PROP_CONFIG)
3333
fun setConfig(videoView: ReactTHEOplayerView, config: ReadableMap?) {
34-
videoView.initialize(config)
34+
videoView.initialize(PlayerConfigAdapter(config))
3535
}
3636

3737
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {

android/src/main/java/com/theoplayer/presentation/PresentationManager.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.core.view.WindowInsetsCompat
1616
import androidx.core.view.WindowInsetsControllerCompat
1717
import androidx.lifecycle.Lifecycle
1818
import com.facebook.react.ReactRootView
19+
import com.facebook.react.runtime.ReactSurfaceView
1920
import com.facebook.react.uimanager.ThemedReactContext
2021
import com.facebook.react.views.view.ReactViewGroup
2122
import com.theoplayer.BuildConfig
@@ -211,7 +212,7 @@ class PresentationManager(
211212
// Get the player's ReactViewGroup parent, which contains THEOplayerView and its children (typically the UI).
212213
val reactPlayerGroup: ReactViewGroup? = getClosestParentOfType(this.viewCtx.playerView)
213214

214-
// Get ReactNative's root node or the render hiearchy
215+
// Get ReactNative's root node or the render hierarchy
215216
val root: ReactRootView? = getClosestParentOfType(reactPlayerGroup)
216217

217218
if (fullscreen) {
@@ -223,7 +224,11 @@ class PresentationManager(
223224
if (!BuildConfig.REPARENT_ON_FULLSCREEN) {
224225
return
225226
}
226-
playerGroupParentNode = (reactPlayerGroup?.parent as ReactViewGroup?)?.also { parent ->
227+
playerGroupParentNode = if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
228+
reactPlayerGroup?.parent as? ReactSurfaceView?
229+
} else {
230+
reactPlayerGroup?.parent as? ReactViewGroup?
231+
}?.also { parent ->
227232
playerGroupChildIndex = parent.indexOfChild(reactPlayerGroup)
228233
// Re-parent the playerViewGroup to the root node
229234
parent.removeView(reactPlayerGroup)

android/src/main/java/com/theoplayer/util/ViewResolver.kt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,28 @@ package com.theoplayer.util
33
import android.util.Log
44
import android.view.View
55
import com.facebook.react.bridge.ReactApplicationContext
6-
import com.facebook.react.uimanager.UIManagerModule
6+
import com.facebook.react.uimanager.UIManagerHelper
77

88
private const val TAG = "ViewResolver"
99
private const val INVALID_TAG = -1
1010

1111
@Suppress("UNCHECKED_CAST")
1212
class ViewResolver(private val reactContext: ReactApplicationContext) {
13-
private var uiManager: UIManagerModule? = null
14-
1513
fun <T: View> resolveViewByTag(tag: Int, onResolved: (view: T?) -> Unit) {
1614
if (tag == INVALID_TAG) {
1715
// Don't bother trying to resolve an invalid tag.
1816
onResolved(null)
1917
}
20-
if (uiManager == null) {
21-
uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
22-
}
23-
uiManager?.addUIBlock {
24-
try {
25-
onResolved(it.resolveView(tag) as? T?)
26-
} catch (e: Exception) {
27-
// The View instance could not be resolved: log but do not forward exception.
28-
Log.e(TAG, "Failed to resolve View tag $tag: $e")
29-
onResolved(null)
18+
try {
19+
reactContext.runOnUiQueueThread {
20+
UIManagerHelper.getUIManagerForReactTag(reactContext, tag)?.let {
21+
onResolved(it.resolveView(tag) as? T?)
22+
}
3023
}
24+
} catch (e: Exception) {
25+
// The ReactTHEOplayerView instance could not be resolved: log but do not forward exception.
26+
Log.e(TAG, "Failed to resolve ReactTHEOplayerView tag $tag: $e")
27+
onResolved(null)
3128
}
3229
}
3330
}

0 commit comments

Comments
 (0)