Skip to content

Commit db8fb8a

Browse files
committed
android: add wakelock control
1 parent 00a50c3 commit db8fb8a

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

android/src/main/java/com/zxcpoiu/incallmanager/InCallManagerModule.java

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import android.support.v4.content.ContextCompat;
2626
import android.util.Log;
2727
import android.util.SparseArray;
28+
import android.view.Display;
2829
import android.view.KeyEvent;
2930
import android.view.Window;
3031
import android.view.WindowManager;
@@ -57,10 +58,13 @@ public class InCallManagerModule extends ReactContextBaseJavaModule implements L
5758

5859
// --- Screen Manager
5960
private PowerManager mPowerManager;
61+
private WakeLock mFullLock = null;
62+
private WakeLock mPokeFullLock = null;
6063
private WakeLock mPartialLock = null;
6164
private WakeLock mProximityLock = null;
6265
private Method mPowerManagerRelease;
6366
private WindowManager.LayoutParams lastLayoutParams;
67+
private WindowManager mWindowManager;
6468

6569
// --- AudioRouteManager
6670
private AudioManager audioManager;
@@ -117,7 +121,12 @@ public InCallManagerModule(ReactApplicationContext _reactContext) {
117121
super(_reactContext);
118122
reactContext = _reactContext;
119123
reactContext.addLifecycleEventListener(this);
124+
mWindowManager = (WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE);
120125
mPowerManager = (PowerManager) reactContext.getSystemService(Context.POWER_SERVICE);
126+
mPokeFullLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, TAG);
127+
mPokeFullLock.setReferenceCounted(false);
128+
mFullLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, TAG);
129+
mFullLock.setReferenceCounted(false);
121130
mPartialLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
122131
mPartialLock.setReferenceCounted(false);
123132
audioManager = ((AudioManager) reactContext.getSystemService(Context.AUDIO_SERVICE));
@@ -211,6 +220,61 @@ private void releaseProximityWakeLock(final boolean waitForNoProximity) {
211220
}
212221
}
213222

223+
private boolean acquireFullWakeLock() {
224+
synchronized (mFullLock) {
225+
if (!mFullLock.isHeld()) {
226+
Log.d(TAG, "acquireFullWakeLock()");
227+
mFullLock.acquire();
228+
return true;
229+
}
230+
}
231+
return false;
232+
}
233+
234+
private boolean releaseFullWakeLock() {
235+
synchronized (mFullLock) {
236+
if (mFullLock.isHeld()) {
237+
Log.d(TAG, "releaseFullWakeLock()");
238+
mFullLock.release();
239+
return true;
240+
}
241+
}
242+
return false;
243+
}
244+
245+
private boolean acquirePokeFullWakeLockReleaseAfter(long timeout) {
246+
synchronized (mPokeFullLock) {
247+
if (!mPokeFullLock.isHeld()) {
248+
mPokeFullLock.acquire(timeout);
249+
Log.d(TAG, String.format("acquirePokeFullWakeLockReleaseAfter(%s)", timeout));
250+
return true;
251+
}
252+
}
253+
return false;
254+
}
255+
256+
private boolean acquirePokeFullWakeLock() {
257+
synchronized (mPokeFullLock) {
258+
if (!mPokeFullLock.isHeld()) {
259+
Log.d(TAG, "acquirePokeFullWakeLock()");
260+
mPokeFullLock.acquire();
261+
return true;
262+
}
263+
}
264+
return false;
265+
}
266+
267+
private boolean releasePokeFullWakeLock() {
268+
synchronized (mPokeFullLock) {
269+
if (mPokeFullLock.isHeld()) {
270+
Log.d(TAG, "releasePokeFullWakeLock()");
271+
mPokeFullLock.release();
272+
return true;
273+
}
274+
}
275+
return false;
276+
}
277+
214278
private boolean acquirePartialWakeLock() {
215279
synchronized (mPartialLock) {
216280
if (!mPartialLock.isHeld()) {
@@ -688,6 +752,59 @@ private void releaseAudioFocus() {
688752
}
689753
}
690754

755+
@ReactMethod
756+
public void pokeScreen(int timeout) {
757+
//debugScreenPowerState();
758+
if (!mPowerManager.isInteractive() && mWindowManager.getDefaultDisplay().getState() != Display.STATE_ON) {
759+
Log.d(TAG, "pokeScreen()");
760+
if (timeout > 0) {
761+
acquirePokeFullWakeLockReleaseAfter(timeout); // --- ms
762+
} else {
763+
acquirePokeFullWakeLock();
764+
releasePokeFullWakeLock();
765+
}
766+
}
767+
}
768+
769+
private void debugScreenPowerState() {
770+
String isDeviceIdleMode = "unknow"; // --- API 23
771+
String isIgnoringBatteryOptimizations = "unknow"; // --- API 23
772+
String isPowerSaveMode = "unknow"; // --- API 21
773+
String isInteractive = "unknow"; // --- API 20 ( before since API 7 is: isScreenOn())
774+
String screenState = "unknow"; // --- API 20
775+
776+
if (android.os.Build.VERSION.SDK_INT >= 23) {
777+
isDeviceIdleMode = String.format("%s", mPowerManager.isDeviceIdleMode());
778+
isIgnoringBatteryOptimizations = String.format("%s", mPowerManager.isIgnoringBatteryOptimizations(reactContext.getPackageName()));
779+
}
780+
if (android.os.Build.VERSION.SDK_INT >= 21) {
781+
isPowerSaveMode = String.format("%s", mPowerManager.isPowerSaveMode());
782+
}
783+
if (android.os.Build.VERSION.SDK_INT >= 20) {
784+
isInteractive = String.format("%s", mPowerManager.isInteractive());
785+
Display display = mWindowManager.getDefaultDisplay();
786+
switch (display.getState()) {
787+
case Display.STATE_OFF:
788+
screenState = "STATE_OFF";
789+
break;
790+
case Display.STATE_ON:
791+
screenState = "STATE_ON";
792+
break;
793+
case Display.STATE_DOZE:
794+
screenState = "STATE_DOZE";
795+
break;
796+
case Display.STATE_DOZE_SUSPEND:
797+
screenState = "STATE_DOZE_SUSPEND";
798+
break;
799+
default:
800+
break;
801+
}
802+
} else {
803+
isInteractive = String.format("%s", mPowerManager.isScreenOn());
804+
}
805+
Log.d(TAG, String.format("debugScreenPowerState(): screenState='%s', isInteractive='%s', isPowerSaveMode='%s', isDeviceIdleMode='%s', isIgnoringBatteryOptimizations='%s'", screenState, isInteractive, isPowerSaveMode, isDeviceIdleMode, isIgnoringBatteryOptimizations));
806+
}
807+
691808
@ReactMethod
692809
public void turnScreenOn() {
693810
if (isProximityWakeLockSupported()) {
@@ -956,8 +1073,11 @@ public void startRingtone(final String ringtoneUriType) {
9561073
data.put("audioContentType", AudioAttributes.CONTENT_TYPE_MUSIC);
9571074
*/
9581075
setMediaPlayerEvents((MediaPlayer) mRingtone, "mRingtone");
1076+
releasePokeFullWakeLock();
1077+
acquireFullWakeLock();
9591078
mRingtone.startPlay(data);
9601079
} catch(Exception e) {
1080+
releaseFullWakeLock();
9611081
Log.d(TAG, "startRingtone() failed");
9621082
}
9631083
}
@@ -970,6 +1090,7 @@ public void stopRingtone() {
9701090
mRingtone = null;
9711091
restoreOriginalAudioSetup();
9721092
}
1093+
releaseFullWakeLock();
9731094
} catch(Exception e) {
9741095
Log.d(TAG, "stopRingtone() failed");
9751096
}

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ class InCallManager {
119119
this.cameraPermission = result;
120120
return result;
121121
}
122+
123+
pokeScreen(_timeout) {
124+
if (Platform.OS === 'android') {
125+
let timeout = (typeof _timeout === "number" && _timeout > 0) ? _timeout : 0;
126+
_InCallManager.pokeScreen(timeout);
127+
} else {
128+
console.log("ios doesn't support pokeScreen()");
129+
}
130+
}
122131
}
123132

124133
export default new InCallManager();

0 commit comments

Comments
 (0)