Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2019-02-27 18:03:06 +01:00
parent 171ea65fde
commit 90a099b04e
7 changed files with 236 additions and 7 deletions

View File

@ -92,7 +92,6 @@ import org.apache.commons.lang3.StringEscapeUtils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.parceler.Parcels;
import org.webrtc.*;
import pub.devrel.easypermissions.AfterPermissionGranted;

View File

@ -23,7 +23,6 @@ package com.nextcloud.talk.controllers;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@ -31,7 +30,6 @@ import android.view.ViewGroup;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Delete;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
@ -50,7 +48,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.controllers.base.BaseController;
import com.nextcloud.talk.jobs.DeleteConversationWorker;
import com.nextcloud.talk.jobs.LeaveConversationWorker;
import com.nextcloud.talk.jobs.PushRegistrationWorker;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter;
import com.nextcloud.talk.models.json.participants.Participant;
@ -73,7 +70,6 @@ import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.parceler.Parcels;
import javax.inject.Inject;
import java.util.ArrayList;

View File

@ -20,7 +20,6 @@
package com.nextcloud.talk.utils;
import android.net.Uri;
import android.text.TextUtils;
import androidx.annotation.DimenRes;
import com.nextcloud.talk.BuildConfig;

View File

@ -107,5 +107,4 @@ public class NotificationUtils {
}
}
}
}

View File

@ -0,0 +1,163 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* This class is in part based on the code from the great people that wrote Signal
* https://github.com/signalapp/Signal-Android/raw/f9adb4e4554a44fd65b77320e34bf4bccf7924ce/src/org/thoughtcrime/securesms/webrtc/locks/LockManager.java
*/
package com.nextcloud.talk.utils.power;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import autodagger.AutoInjector;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import javax.inject.Inject;
@AutoInjector(NextcloudTalkApplication.class)
public class PowerManagerUtils {
private static final String TAG = "PowerManagerUtils";
@Inject
Context context;
private final PowerManager.WakeLock fullLock;
private final PowerManager.WakeLock partialLock;
private final WifiManager.WifiLock wifiLock;
private ProximityLock proximityLock;
private final boolean wifiLockEnforced;
private boolean proximityDisabled = false;
public enum PhoneState {
IDLE,
PROCESSING, //used when the phone is active but before the user should be alerted.
INTERACTIVE,
WITHOUT_PROXIMITY_SENSOR_LOCK,
WITH_PROXIMITY_SENSOR_LOCK
}
public enum WakeLockState {
FULL,
PARTIAL,
SLEEP,
PROXIMITY
}
public PowerManagerUtils() {
NextcloudTalkApplication.getSharedApplication().getComponentApplication().inject(this);
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
fullLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "nctalk:fullwakelock");
partialLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "nctalk:partialwakelock");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
proximityLock = new ProximityLock(pm);
}
// we suppress a possible leak because this is indeed application context
@SuppressLint("WifiManagerPotentialLeak") WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "nctalk:wifiwakelock");
fullLock.setReferenceCounted(false);
partialLock.setReferenceCounted(false);
wifiLock.setReferenceCounted(false);
wifiLockEnforced = isWifiPowerActiveModeEnabled(context);
}
public void updatePhoneState(PhoneState state) {
switch(state) {
case IDLE:
setWakeLockState(WakeLockState.SLEEP);
break;
case PROCESSING:
setWakeLockState(WakeLockState.PARTIAL);
break;
case INTERACTIVE:
setWakeLockState(WakeLockState.FULL);
break;
case WITH_PROXIMITY_SENSOR_LOCK:
proximityDisabled = false;
updateInCallWakeLockState();
break;
case WITHOUT_PROXIMITY_SENSOR_LOCK:
proximityDisabled = true;
updateInCallWakeLockState();
break;
}
}
private void updateInCallWakeLockState() {
if (wifiLockEnforced && !proximityDisabled) {
setWakeLockState(WakeLockState.PROXIMITY);
} else {
setWakeLockState(WakeLockState.FULL);
}
}
private boolean isWifiPowerActiveModeEnabled(Context context) {
int wifi_pwr_active_mode = Settings.Secure.getInt(context.getContentResolver(), "wifi_pwr_active_mode", -1);
return (wifi_pwr_active_mode != 0);
}
@SuppressLint("WakelockTimeout")
private synchronized void setWakeLockState(WakeLockState newState) {
switch(newState) {
case FULL:
fullLock.acquire();
partialLock.acquire();
wifiLock.acquire();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
proximityLock.release();
}
break;
case PARTIAL:
partialLock.acquire();
wifiLock.acquire();
fullLock.release();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
proximityLock.release();
}
break;
case SLEEP:
fullLock.release();
partialLock.release();
wifiLock.release();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
proximityLock.release();
}
break;
case PROXIMITY:
partialLock.acquire();
wifiLock.acquire();
fullLock.release();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
proximityLock.acquire();
}
break;
default:
// something went very very wrong
}
}
}

View File

@ -0,0 +1,65 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.utils.power;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.PowerManager;
import androidx.annotation.RequiresApi;
import java.util.Optional;
class ProximityLock {
private final Optional<PowerManager.WakeLock> proximityLock;
@RequiresApi(api = Build.VERSION_CODES.N)
ProximityLock(PowerManager pm) {
proximityLock = getProximityLock(pm);
}
@RequiresApi(api = Build.VERSION_CODES.N)
private Optional<PowerManager.WakeLock> getProximityLock(PowerManager powerManager) {
if (powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
return Optional.ofNullable(powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "nctalk:proximitylock"));
} else {
return Optional.empty();
}
}
@SuppressLint("WakelockTimeout")
@RequiresApi(api = Build.VERSION_CODES.N)
void acquire() {
if (!proximityLock.isPresent() || proximityLock.get().isHeld()) {
return;
}
proximityLock.get().acquire();
}
@RequiresApi(api = Build.VERSION_CODES.N)
void release() {
if (!proximityLock.isPresent() || !proximityLock.get().isHeld()) {
return;
}
proximityLock.get().release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
}
}

View File

@ -41,6 +41,7 @@ import android.media.AudioManager;
import android.os.Build;
import android.util.Log;
import com.nextcloud.talk.events.PeerConnectionEvent;
import com.nextcloud.talk.utils.power.PowerManagerUtils;
import org.greenrobot.eventbus.EventBus;
import org.webrtc.ThreadUtils;
@ -94,6 +95,8 @@ public class MagicAudioManager {
// Callback method for changes in audio focus.
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
private PowerManagerUtils powerManagerUtils;
private MagicAudioManager(Context context, boolean useProximitySensor) {
Log.d(TAG, "ctor");
ThreadUtils.checkIsOnMainThread();
@ -103,6 +106,9 @@ public class MagicAudioManager {
wiredHeadsetReceiver = new WiredHeadsetReceiver();
amState = AudioManagerState.UNINITIALIZED;
powerManagerUtils = new PowerManagerUtils();
powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.WITH_PROXIMITY_SENSOR_LOCK);
if (useProximitySensor) {
useSpeakerphone = SPEAKERPHONE_AUTO;
} else {
@ -313,6 +319,8 @@ public class MagicAudioManager {
proximitySensor = null;
}
powerManagerUtils.updatePhoneState(PowerManagerUtils.PhoneState.IDLE);
audioManagerEvents = null;
Log.d(TAG, "AudioManager stopped");
}