瀏覽代碼

Fix #480, Fix #188

Signed-off-by: Mario Danic <mario@lovelyhq.com>
Mario Danic 6 年之前
父節點
當前提交
90a099b04e

+ 0 - 1
app/src/main/java/com/nextcloud/talk/controllers/CallController.java

@@ -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;
 

+ 0 - 4
app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.java

@@ -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;

+ 0 - 1
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java

@@ -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;

+ 0 - 1
app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.java

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

+ 163 - 0
app/src/main/java/com/nextcloud/talk/utils/power/PowerManagerUtils.java

@@ -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
+        }
+    }
+}

+ 65 - 0
app/src/main/java/com/nextcloud/talk/utils/power/ProximityLock.java

@@ -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);
+    }
+}

+ 8 - 0
app/src/main/java/com/nextcloud/talk/webrtc/MagicAudioManager.java

@@ -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");
     }