Skip to content

Commit

Permalink
Merge branch 'main' into inspector-page
Browse files Browse the repository at this point in the history
  • Loading branch information
myandrienko authored Jan 23, 2025
2 parents 98f501d + 28a7e95 commit 55024a3
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 48 deletions.
14 changes: 14 additions & 0 deletions packages/react-native-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).

## [1.9.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.9.6...@stream-io/video-react-native-sdk-1.9.7) (2025-01-22)


### Bug Fixes

* do not reject from callkit if call is accepted already ([#1651](https://github.com/GetStream/stream-video-js/issues/1651)) ([87b76ba](https://github.com/GetStream/stream-video-js/commit/87b76ba54defc287a259c6d83bfde252b503f199))

## [1.9.6](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.9.5...@stream-io/video-react-native-sdk-1.9.6) (2025-01-22)


### Bug Fixes

* pip android crash on activity not enabled ([#1650](https://github.com/GetStream/stream-video-js/issues/1650)) ([013853b](https://github.com/GetStream/stream-video-js/commit/013853b11d83c9959dfc6805e1be492d0b1d36f5))

## [1.9.5](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-native-sdk-1.9.4...@stream-io/video-react-native-sdk-1.9.5) (2025-01-21)

### Dependency Updates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.os.Process
import android.util.Log
import android.util.Rational
import androidx.annotation.RequiresApi
import com.facebook.react.ReactActivity
Expand All @@ -23,10 +24,11 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEm
import com.streamvideo.reactnative.util.RingtoneUtil


class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

override fun getName(): String {
return NAME;
return NAME
}

private var thermalStatusListener: PowerManager.OnThermalStatusChangedListener? = null
Expand All @@ -39,42 +41,52 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
RCTDeviceEventEmitter::class.java
).emit(PIP_CHANGE_EVENT, isInPictureInPictureMode)
// inform the activity
if (isInPictureInPictureMode && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (isInPictureInPictureMode && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasPiPSupport()) {
(reactApplicationContext.currentActivity as? ReactActivity)?.let { activity ->
val params = getPiPParams()
val aspect =
if (newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
Rational(9, 16)
try {
val params = getPiPParams()
val aspect =
if (newConfig.orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
Rational(9, 16)
} else {
Rational(16, 9)
}
params.setAspectRatio(aspect)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
// this platform doesn't support autoEnterEnabled
// so we manually enter here
activity.enterPictureInPictureMode(params.build())
} else {
Rational(16, 9)
activity.setPictureInPictureParams(params.build())
}
params.setAspectRatio(aspect)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
// this platform doesn't support autoEnterEnabled
// so we manually enter here
activity.enterPictureInPictureMode(params.build())
} else {
activity.setPictureInPictureParams(params.build())
// NOTE: workaround - on PiP mode, android goes to "paused but can render" state
// RN pauses rendering in paused mode, so we instruct it to resume here
reactApplicationContext?.onHostResume(activity)
} catch (e: IllegalStateException) {
Log.d(
NAME,
"Skipping Picture-in-Picture mode. Its not enabled for activity"
)
}
// NOTE: workaround - on PiP mode, android goes to "paused but can render" state
// RN pauses rendering in paused mode, so we instruct it to resume here
reactApplicationContext?.onHostResume(activity)
}
}
}

val filter = IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
reactApplicationContext.registerReceiver(powerReceiver, filter)
}

@ReactMethod
fun getDefaultRingtoneUrl(promise: Promise) {
val defaultRingtoneUri: Uri? =
RingtoneUtil.getActualDefaultRingtoneUri(reactApplicationContext);
RingtoneUtil.getActualDefaultRingtoneUri(reactApplicationContext)
if (defaultRingtoneUri != null) {
promise.resolve(defaultRingtoneUri.toString());
promise.resolve(defaultRingtoneUri.toString())
} else {
promise.reject(NAME, "Cannot get default ringtone in Android - check native logs for more info");
promise.reject(
NAME,
"Cannot get default ringtone in Android - check native logs for more info"
)
}
}

Expand Down Expand Up @@ -105,26 +117,31 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
@ReactMethod
fun canAutoEnterPipMode(value: Boolean) {
StreamVideoReactNative.canAutoEnterPictureInPictureMode = value
if (!hasPermission() || Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return
if (!hasPiPSupport() || Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return
val activity = reactApplicationContext!!.currentActivity!!
if (value) {
activity.setPictureInPictureParams(getPiPParams().build())
// NOTE: for SDK_INT < Build.VERSION_CODES.S
// onUserLeaveHint from Activity is used, SDK cant directly use it
// onUserLeaveHint will call the PiP listener and we call enterPictureInPictureMode there
} else {
val params = PictureInPictureParams.Builder()
params.setAutoEnterEnabled(false)
activity.setPictureInPictureParams(params.build())
try {
if (value) {
activity.setPictureInPictureParams(getPiPParams().build())
// NOTE: for SDK_INT < Build.VERSION_CODES.S
// onUserLeaveHint from Activity is used, SDK cant directly use it
// onUserLeaveHint will call the PiP listener and we call enterPictureInPictureMode there
} else {
val params = PictureInPictureParams.Builder()
params.setAutoEnterEnabled(false)
activity.setPictureInPictureParams(params.build())
}
} catch (e: IllegalStateException) {
Log.d(NAME, "Skipping Picture-in-Picture mode. Its not enabled for activity")
}
}

@ReactMethod
fun startThermalStatusUpdates(promise: Promise) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val powerManager = reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager

val powerManager =
reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager

val listener = PowerManager.OnThermalStatusChangedListener { status ->
val thermalStatus = when (status) {
PowerManager.THERMAL_STATUS_NONE -> "NONE"
Expand All @@ -136,12 +153,12 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
PowerManager.THERMAL_STATUS_SHUTDOWN -> "SHUTDOWN"
else -> "UNKNOWN"
}

reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
.emit("thermalStateDidChange", thermalStatus)
}

thermalStatusListener = listener
powerManager.addThermalStatusListener(listener)
// Get initial status
Expand All @@ -157,7 +174,8 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
@ReactMethod
fun stopThermalStatusUpdates() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val powerManager = reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager
val powerManager =
reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager
// Store the current listener in a local val for safe null checking
val currentListener = thermalStatusListener
if (currentListener != null) {
Expand All @@ -171,7 +189,8 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
fun currentThermalState(promise: Promise) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val powerManager = reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager
val powerManager =
reactApplicationContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager
val status = powerManager.currentThermalStatus
val thermalStatus = when (status) {
PowerManager.THERMAL_STATUS_NONE -> "NONE"
Expand Down Expand Up @@ -201,7 +220,8 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
}

private fun sendPowerModeEvent() {
val powerManager = reactApplicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
val powerManager =
reactApplicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
val isLowPowerMode = powerManager.isPowerSaveMode
reactApplicationContext
.getJSModule(RCTDeviceEventEmitter::class.java)
Expand All @@ -211,22 +231,34 @@ class StreamVideoReactNativeModule(reactContext: ReactApplicationContext) : Reac
@ReactMethod
fun isLowPowerModeEnabled(promise: Promise) {
try {
val powerManager = reactApplicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
val powerManager =
reactApplicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
promise.resolve(powerManager.isPowerSaveMode)
} catch (e: Exception) {
promise.reject("ERROR", e.message)
}
}

private fun hasPermission(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && reactApplicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
private fun hasPiPSupport(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && reactApplicationContext.packageManager.hasSystemFeature(
PackageManager.FEATURE_PICTURE_IN_PICTURE
)
) {
val appOps =
reactApplicationContext.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
val packageName = reactApplicationContext.packageName
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
appOps.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
appOps.unsafeCheckOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
Process.myUid(),
packageName
) == AppOpsManager.MODE_ALLOWED
} else {
appOps.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
appOps.checkOpNoThrow(
AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
Process.myUid(),
packageName
) == AppOpsManager.MODE_ALLOWED
}
} else {
false
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stream-io/video-react-native-sdk",
"version": "1.9.5",
"version": "1.9.7",
"packageManager": "[email protected]",
"main": "dist/commonjs/index.js",
"module": "dist/module/index.js",
Expand Down
5 changes: 4 additions & 1 deletion packages/react-native-sdk/src/utils/push/internal/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Call,
CallingState,
RxUtils,
StreamVideoClient,
getLogger,
Expand Down Expand Up @@ -112,7 +113,9 @@ export const processCallFromPush = async (
}
await callFromPush.join();
} else if (action === 'decline') {
await callFromPush.leave({ reject: true, reason: 'decline' });
const canReject =
callFromPush.state.callingState === CallingState.RINGING;
await callFromPush.leave({ reject: canReject, reason: 'decline' });
}
} catch (e) {
const logger = getLogger(['processCallFromPush']);
Expand Down
7 changes: 7 additions & 0 deletions packages/react-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).

## [1.10.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.10.3...@stream-io/video-react-sdk-1.10.4) (2025-01-22)


### Bug Fixes

* **LivestreamPlayer:** don't render any component until `call` is ready ([#1653](https://github.com/GetStream/stream-video-js/issues/1653)) ([63afc30](https://github.com/GetStream/stream-video-js/commit/63afc3090a5ceb3d656f0111bc348d79b895ab5f))

## [1.10.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-react-sdk-1.10.2...@stream-io/video-react-sdk-1.10.3) (2025-01-21)

### Dependency Updates
Expand Down
2 changes: 1 addition & 1 deletion packages/react-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stream-io/video-react-sdk",
"version": "1.10.3",
"version": "1.10.4",
"packageManager": "[email protected]",
"main": "./dist/index.cjs.js",
"module": "./dist/index.es.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export const LivestreamPlayer = (props: LivestreamPlayerProps) => {
};
}, [callId, callType, client]);

if (!call) return null;

return (
<StreamCall call={call}>
<LivestreamLayout {...layoutProps} />
Expand Down
2 changes: 1 addition & 1 deletion sample-apps/react-native/dogfood/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stream-io/video-react-native-dogfood",
"version": "4.14.5",
"version": "4.14.7",
"private": true,
"scripts": {
"android": "react-native run-android",
Expand Down

0 comments on commit 55024a3

Please sign in to comment.