Skip to content

Commit

Permalink
add initial implementation for thermal info for android
Browse files Browse the repository at this point in the history
  • Loading branch information
kristian-mkd committed Nov 19, 2024
1 parent 9da68db commit 1d474a1
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission
android:name="android.permission.BLUETOOTH"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MainApplication : Application(), ReactApplication {
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
add(VideoEffectsPackage())
add(ThermalPackage())
}

override fun getJSMainModuleName(): String = "index"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.getstream.rnvideosample

import android.os.Build
import android.os.PowerManager
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise

class ThermalModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

override fun getName(): String = "ThermalModule"

@ReactMethod
fun getCurrentThermalStatus(promise: Promise) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val powerManager = reactContext.getSystemService(ReactApplicationContext.POWER_SERVICE) as PowerManager
val status = powerManager.currentThermalStatus
val thermalStatus = when (status) {
PowerManager.THERMAL_STATUS_NONE -> "NONE"
PowerManager.THERMAL_STATUS_LIGHT -> "LIGHT"
PowerManager.THERMAL_STATUS_MODERATE -> "MODERATE"
PowerManager.THERMAL_STATUS_SEVERE -> "SEVERE"
PowerManager.THERMAL_STATUS_CRITICAL -> "CRITICAL"
PowerManager.THERMAL_STATUS_EMERGENCY -> "EMERGENCY"
PowerManager.THERMAL_STATUS_SHUTDOWN -> "SHUTDOWN"
else -> "UNKNOWN"
}
promise.resolve(thermalStatus)
} else {
promise.resolve("NOT_SUPPORTED")
}
} catch (e: Exception) {
promise.reject("THERMAL_ERROR", e.message)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.getstream.rnvideosample

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class ThermalPackage : ReactPackage {
override fun createViewManagers(reactContext: ReactApplicationContext) = emptyList<ViewManager<*, *>>()

override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
listOf(ThermalModule(reactContext))
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Pressable, StyleSheet, View, Text } from 'react-native';
import { MeetingStackParamList } from '../../types';
import { appTheme } from '../theme';
import { useOrientation } from '../hooks/useOrientation';
import { ThermalInfo } from './ThermalInfo';

type LobbyViewComponentType = NativeStackScreenProps<
MeetingStackParamList,
Expand All @@ -30,6 +31,7 @@ export const LobbyViewComponent = ({
const JoinCallButtonComponent = useCallback(() => {
return (
<>
<ThermalInfo />
<JoinCallButton onPressHandler={onJoinCallHandler} />
{route.name === 'MeetingScreen' ? (
<Pressable
Expand Down
73 changes: 73 additions & 0 deletions sample-apps/react-native/dogfood/src/components/ThermalInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet, Platform, NativeModules } from 'react-native';
import { useTheme } from '@stream-io/video-react-native-sdk';

const { ThermalModule } = NativeModules;

export const ThermalInfo = () => {
const [thermalStatus, setThermalStatus] = useState<string>('Unknown');
const { theme } = useTheme();

useEffect(() => {
const checkThermalStatus = async () => {
if (Platform.OS === 'android') {
try {
const status = await ThermalModule.getCurrentThermalStatus();
setThermalStatus(status);
} catch (error) {
console.error('Failed to get thermal status:', error);
setThermalStatus('Error');
}
}
};

checkThermalStatus();
const interval = setInterval(checkThermalStatus, 5000);

return () => clearInterval(interval);
}, []);

const getStatusColor = () => {
switch (thermalStatus) {
case 'NONE':
case 'LIGHT':
return '#4CAF50';
case 'MODERATE':
return '#FFC107';
case 'SEVERE':
case 'CRITICAL':
return '#F44336';
case 'EMERGENCY':
case 'SHUTDOWN':
return '#D32F2F';
default:
return theme.colors.textLowEmphasis;
}
};

return (
<View style={styles.container}>
<Text style={[styles.label, { color: 'white' }]}>Thermal Status</Text>

Check warning on line 50 in sample-apps/react-native/dogfood/src/components/ThermalInfo.tsx

View workflow job for this annotation

GitHub Actions / Code Lint, Unit Test and dogfood versioning

Inline style: { color: 'white' }
<Text style={[styles.status, { color: getStatusColor() }]}>
{thermalStatus}
</Text>
</View>
);
};

const styles = StyleSheet.create({
container: {
padding: 8,
borderRadius: 8,
marginVertical: 4,
},
label: {
fontSize: 14,
fontWeight: '600',
marginBottom: 4,
},
status: {
fontSize: 16,
fontWeight: 'bold',
},
});

0 comments on commit 1d474a1

Please sign in to comment.