From acbfe5cb0960033689c2a7a350afc0116d588768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 16 Jan 2017 19:12:43 -0600 Subject: [PATCH] [RN] Keep device screen on while in a conference --- android/app/build.gradle | 1 + .../java/org/jitsi/meet/MainApplication.java | 1 + android/settings.gradle | 2 + .../project.pbxproj | 35 ++++++++++++ package.json | 1 + react/features/app/components/App.native.js | 1 + react/features/wake-lock/index.js | 1 + react/features/wake-lock/middleware.js | 53 +++++++++++++++++++ 8 files changed, 95 insertions(+) create mode 100644 react/features/wake-lock/index.js create mode 100644 react/features/wake-lock/middleware.js diff --git a/android/app/build.gradle b/android/app/build.gradle index ff69d4ed7..70fce4d85 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -153,6 +153,7 @@ repositories { maven { url 'https://maven.fabric.io/public' } } dependencies { + compile project(':react-native-keep-awake') compile project(':react-native-vector-icons') compile project(':react-native-webrtc') compile fileTree(dir: 'libs', include: ['*.jar']) diff --git a/android/app/src/main/java/org/jitsi/meet/MainApplication.java b/android/app/src/main/java/org/jitsi/meet/MainApplication.java index 5f36b87f0..f89391eb9 100644 --- a/android/app/src/main/java/org/jitsi/meet/MainApplication.java +++ b/android/app/src/main/java/org/jitsi/meet/MainApplication.java @@ -28,6 +28,7 @@ public class MainApplication extends Application implements ReactApplication { @Override protected List getPackages() { return Arrays.asList( + new com.corbt.keepawake.KCKeepAwakePackage(), new com.facebook.react.shell.MainReactPackage(), new com.oblador.vectoricons.VectorIconsPackage(), new com.oney.WebRTCModule.WebRTCModulePackage() diff --git a/android/settings.gradle b/android/settings.gradle index 8e74fe814..ed5415526 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,6 +1,8 @@ rootProject.name = 'jitsi-meet-react' include ':app' +include ':react-native-keep-awake' +project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android') include ':react-native-vector-icons' project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') include ':react-native-webrtc' diff --git a/ios/jitsi-meet-react.xcodeproj/project.pbxproj b/ios/jitsi-meet-react.xcodeproj/project.pbxproj index 4bf84fe60..2e7be8d39 100644 --- a/ios/jitsi-meet-react.xcodeproj/project.pbxproj +++ b/ios/jitsi-meet-react.xcodeproj/project.pbxproj @@ -24,6 +24,7 @@ 2602576C1D0A7703001E3363 /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2602576B1D0A7703001E3363 /* jitsi.ttf */; }; 3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; + 901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */; }; B30EF2311DC0ED7C00690F45 /* WebRTC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B30EF2301DC0ED7C00690F45 /* WebRTC.framework */; }; B30EF2331DC0EEA500690F45 /* WebRTC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B30EF2301DC0ED7C00690F45 /* WebRTC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; B3A9D0251E0481E10009343D /* POSIX.m in Sources */ = {isa = PBXBuildFile; fileRef = B3A9D0241E0481E10009343D /* POSIX.m */; }; @@ -76,6 +77,13 @@ remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; remoteInfo = RCTVibration; }; + 0B8752851E26E54A004C5CAB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = KCKeepAwake; + }; 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; @@ -197,6 +205,7 @@ 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; + 0EA8C046B2BF46279796F07D /* libKCKeepAwake.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libKCKeepAwake.a; sourceTree = ""; }; 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* jitsi-meet-react.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet-react.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -209,6 +218,7 @@ 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = ""; }; 2602576B1D0A7703001E3363 /* jitsi.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = jitsi.ttf; path = ../android/app/src/main/assets/fonts/jitsi.ttf; sourceTree = ""; }; + 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = KCKeepAwake.xcodeproj; path = "../node_modules/react-native-keep-awake/ios/KCKeepAwake.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 821D8ABD506944B4BDBB069B /* libRNVectorIcons.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNVectorIcons.a; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; @@ -258,6 +268,7 @@ BFC745141CB829B300673F38 /* libRCTWebRTC.a in Frameworks */, 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 3847F11906B4479A9162628F /* libRNVectorIcons.a in Frameworks */, + 901FE90FA5744B5B94DCDC41 /* libKCKeepAwake.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -306,6 +317,14 @@ name = Products; sourceTree = ""; }; + 0B8752821E26E54A004C5CAB /* Products */ = { + isa = PBXGroup; + children = ( + 0B8752861E26E54A004C5CAB /* libKCKeepAwake.a */, + ); + name = Products; + sourceTree = ""; + }; 139105B71AF99BAD00B5F7CC /* Products */ = { isa = PBXGroup; children = ( @@ -393,6 +412,7 @@ 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 22418656B14845609F953A42 /* RNVectorIcons.xcodeproj */, + 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */, ); name = Libraries; sourceTree = ""; @@ -506,6 +526,10 @@ productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; projectReferences = ( + { + ProductGroup = 0B8752821E26E54A004C5CAB /* Products */; + ProjectRef = 5B09C20C78C74A548AAAC1FA /* KCKeepAwake.xcodeproj */; + }, { ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; @@ -598,6 +622,13 @@ remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 0B8752861E26E54A004C5CAB /* libKCKeepAwake.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libKCKeepAwake.a; + remoteRef = 0B8752851E26E54A004C5CAB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -798,6 +829,7 @@ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", + "$(SRCROOT)/../node_modules/react-native-keep-awake/ios", "$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager", ); INFOPLIST_FILE = app/Info.plist; @@ -833,6 +865,7 @@ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/**", + "$(SRCROOT)/../node_modules/react-native-keep-awake/ios", "$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager", ); INFOPLIST_FILE = app/Info.plist; @@ -890,6 +923,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-keep-awake/ios", "$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -931,6 +965,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", + "$(SRCROOT)/../node_modules/react-native-keep-awake/ios", "$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; diff --git a/package.json b/package.json index 0a8ea5c68..981c7b263 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "react": "15.4.2", "react-dom": "15.4.2", "react-native": "0.39.2", + "react-native-keep-awake": "^1.0.7", "react-native-prompt": "^1.0.0", "react-native-vector-icons": "^3.0.0", "react-native-webrtc": "jitsi/react-native-webrtc", diff --git a/react/features/app/components/App.native.js b/react/features/app/components/App.native.js index ff7580042..5de51b59e 100644 --- a/react/features/app/components/App.native.js +++ b/react/features/app/components/App.native.js @@ -3,6 +3,7 @@ import { Linking } from 'react-native'; import { Platform } from '../../base/react'; +import '../../wake-lock'; import { AbstractApp } from './AbstractApp'; diff --git a/react/features/wake-lock/index.js b/react/features/wake-lock/index.js new file mode 100644 index 000000000..d43689289 --- /dev/null +++ b/react/features/wake-lock/index.js @@ -0,0 +1 @@ +import './middleware'; diff --git a/react/features/wake-lock/middleware.js b/react/features/wake-lock/middleware.js new file mode 100644 index 000000000..50642cc58 --- /dev/null +++ b/react/features/wake-lock/middleware.js @@ -0,0 +1,53 @@ +import KeepAwake from 'react-native-keep-awake'; + +import { + CONFERENCE_FAILED, + CONFERENCE_JOINED, + CONFERENCE_LEFT +} from '../base/conference'; +import { MiddlewareRegistry } from '../base/redux'; + +/** + * Middleware that captures conference actions and activates or deactivates the + * wake lock accordingly. If the wake lock is active, it will prevent the screen + * from dimming. + * + * @param {Store} store - Redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(store => next => action => { + switch (action.type) { + case CONFERENCE_JOINED: { + const state = store.getState()['features/base/conference']; + + // TODO(saghul): Implement audio-only mode. + if (!state.audioOnly) { + setWakeLock(true); + } + break; + } + + case CONFERENCE_FAILED: + case CONFERENCE_LEFT: + setWakeLock(false); + break; + } + + return next(action); +}); + +/** + * Activates/deactivates the wake lock. If the wake lock is active, it will + * prevent the screen from dimming. + * + * @param {boolean} wakeLock - True to active the wake lock or false to + * deactivate it. + * @returns {void} + */ +function setWakeLock(wakeLock) { + if (wakeLock) { + KeepAwake.activate(); + } else { + KeepAwake.deactivate(); + } +}