Working proximity lock.

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2015-09-16 14:44:55 -07:00
parent 961b9b882f
commit fdfa15aa4d

View File

@ -1,8 +1,11 @@
package org.thoughtcrime.redphone.call; package org.thoughtcrime.redphone.call;
import android.os.Build;
import android.os.PowerManager; import android.os.PowerManager;
import android.util.Log; import android.util.Log;
import org.whispersystems.libaxolotl.util.guava.Optional;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -13,55 +16,70 @@ import java.lang.reflect.Method;
* @author Stuart O. Anderson * @author Stuart O. Anderson
*/ */
class ProximityLock { class ProximityLock {
private final Method wakelockParameterizedRelease = getWakelockParamterizedReleaseMethod(); private final Method wakelockParameterizedRelease = getWakelockParamterizedReleaseMethod();
private final PowerManager.WakeLock proximityLock; private final Optional<PowerManager.WakeLock> proximityLock;
private static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; private static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
private static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1; private static final int WAIT_FOR_PROXIMITY_NEGATIVE = 1;
ProximityLock(PowerManager pm) { ProximityLock(PowerManager pm) {
proximityLock = maybeGetProximityLock(pm); proximityLock = getProximityLock(pm);
} }
private PowerManager.WakeLock maybeGetProximityLock(PowerManager pm) { private Optional<PowerManager.WakeLock> getProximityLock(PowerManager pm) {
/*try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PowerManager.WakeLock lock = pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, "RedPhone Incall"); if (pm.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
if (lock != null) { return Optional.fromNullable(pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
return lock; "Signal Proximity Lock"));
} else {
return Optional.absent();
} }
} catch (Throwable t) { } else {
Log.e("LockManager", "Failed to create proximity lock", t); try {
}*/ return Optional.fromNullable(pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, "RedPhone Incall"));
return null; } catch (Throwable t) {
Log.e("LockManager", "Failed to create proximity lock", t);
return Optional.absent();
}
}
} }
public void acquire() { public void acquire() {
if (proximityLock == null || proximityLock.isHeld()) { if (!proximityLock.isPresent() || proximityLock.get().isHeld()) {
return; return;
} }
proximityLock.acquire();
proximityLock.get().acquire();
} }
public void release() { public void release() {
if (proximityLock == null || !proximityLock.isHeld()) { if (!proximityLock.isPresent() || !proximityLock.get().isHeld()) {
return; return;
} }
boolean released = false;
if (wakelockParameterizedRelease != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try { proximityLock.get().release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
wakelockParameterizedRelease.invoke(proximityLock, new Integer(WAIT_FOR_PROXIMITY_NEGATIVE)); } else {
released = true; boolean released = false;
} catch (IllegalAccessException e) {
Log.d("LockManager", "Failed to invoke release method", e); if (wakelockParameterizedRelease != null) {
} catch (InvocationTargetException e) { try {
Log.d("LockManager", "Failed to invoke release method", e); wakelockParameterizedRelease.invoke(proximityLock.get(), WAIT_FOR_PROXIMITY_NEGATIVE);
released = true;
} catch (IllegalAccessException e) {
Log.w("ProximityLock", e);
} catch (InvocationTargetException e) {
Log.w("ProximityLock", e);
}
}
if (!released) {
proximityLock.get().release();
} }
} }
if(!released) { Log.d("LockManager", "Released proximity lock:" + proximityLock.get().isHeld());
proximityLock.release();
}
Log.d("LockManager", "Released proximity lock:" + proximityLock.isHeld());
} }
private static Method getWakelockParamterizedReleaseMethod() { private static Method getWakelockParamterizedReleaseMethod() {