From 32011c8f7276a6ac5d413f4946a9971dc2e4c4a5 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 8 Dec 2016 16:51:06 +0100 Subject: [PATCH] Enable and disable Keep Alive according to device Doze mode --- src/org/linphone/CallActivity.java | 20 ++-- src/org/linphone/DozeReceiver.java | 35 ++++++ src/org/linphone/KeepAliveReceiver.java | 2 +- .../linphone/LinphoneLauncherActivity.java | 14 +-- src/org/linphone/LinphoneManager.java | 25 +++- src/org/linphone/LinphoneService.java | 110 +++++++++--------- src/org/linphone/PreferencesMigrator.java | 36 +++--- src/org/linphone/SettingsFragment.java | 2 +- submodules/cmake-builder | 2 +- 9 files changed, 152 insertions(+), 94 deletions(-) create mode 100644 src/org/linphone/DozeReceiver.java diff --git a/src/org/linphone/CallActivity.java b/src/org/linphone/CallActivity.java index eed85b24e..280f623aa 100644 --- a/src/org/linphone/CallActivity.java +++ b/src/org/linphone/CallActivity.java @@ -133,7 +133,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); instance = this; - + if (getResources().getBoolean(R.bool.orientation_portrait_only)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } @@ -166,7 +166,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message) { displayMissedChats(); } - + @Override public void callState(LinphoneCore lc, final LinphoneCall call, LinphoneCall.State state, String message) { if (LinphoneManager.getLc().getCallsNb() == 0) { @@ -436,7 +436,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve public void checkAndRequestPermission(String permission, int result) { int permissionGranted = getPackageManager().checkPermission(permission, getPackageName()); Log.i("[Permission] " + permission + " is " + (permissionGranted == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); - + if (permissionGranted != PackageManager.PERMISSION_GRANTED) { if (LinphonePreferences.instance().firstTimeAskingForPermission(permission) || ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { Log.i("[Permission] Asking for " + permission); @@ -450,7 +450,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve for (int i = 0; i < permissions.length; i++) { Log.i("[Permission] " + permissions[i] + " is " + (grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); } - + switch (requestCode) { case PERMISSIONS_REQUEST_CAMERA: UIThreadDispatcher.dispatch(new Runnable() { @@ -618,7 +618,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve if (id == R.id.video) { int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()); Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); - + if (camera == PackageManager.PERMISSION_GRANTED) { disableVideo(isVideoEnabled(LinphoneManager.getLc().getCurrentCall())); } else { @@ -629,7 +629,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve else if (id == R.id.micro) { int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()); Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); - + if (recordAudio == PackageManager.PERMISSION_GRANTED) { toggleMicro(); } else { @@ -783,7 +783,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve //Check if the call is not terminated if(call.getState() == State.CallEnd || call.getState() == State.CallReleased) return; - + if (!displayVideo) { showAudioView(); } else { @@ -1143,7 +1143,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve public void onClick(View view) { int camera = getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()); Log.i("[Permission] Camera permission is " + (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); - + if (camera == PackageManager.PERMISSION_GRANTED) { CallActivity.instance().acceptCallUpdate(true); } else { @@ -1568,14 +1568,14 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve public void onAccuracyChanged(Sensor sensor, int accuracy) { } - + private void displayMissedChats() { int count = 0; LinphoneChatRoom[] chats = LinphoneManager.getLc().getChatRooms(); for (LinphoneChatRoom chatroom : chats) { count += chatroom.getUnreadMessagesCount(); } - + if (count > 0) { missedChats.setText(count + ""); missedChats.setVisibility(View.VISIBLE); diff --git a/src/org/linphone/DozeReceiver.java b/src/org/linphone/DozeReceiver.java new file mode 100644 index 000000000..2fea22feb --- /dev/null +++ b/src/org/linphone/DozeReceiver.java @@ -0,0 +1,35 @@ +package org.linphone; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.PowerManager; + +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreFactory; +import org.linphone.mediastream.Log; + +/* + * Purpose of this receiver is to disable keep alives when device is on idle + * */ +public class DozeReceiver extends android.content.BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + PowerManager pm; + if (!LinphoneService.isReady()) return; + + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); + LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc == null) return; + + pm = (PowerManager) context.getSystemService(context.POWER_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + boolean dozeM = pm.isDeviceIdleMode(); + Log.i("[DozeReceiver] Idle Mode: " + dozeM); + LinphoneManager.getInstance().setDozeModeEnabled(dozeM); + LinphoneManager.getInstance().updateNetworkReachability(); + } + } +} diff --git a/src/org/linphone/KeepAliveReceiver.java b/src/org/linphone/KeepAliveReceiver.java index 87abaf7fe..7595377e6 100644 --- a/src/org/linphone/KeepAliveReceiver.java +++ b/src/org/linphone/KeepAliveReceiver.java @@ -44,7 +44,7 @@ public class KeepAliveReceiver extends BroadcastReceiver { LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); if (lc == null) return; - + String action = intent.getAction(); if (action == null) { Log.i("[KeepAlive] Refresh registers"); diff --git a/src/org/linphone/LinphoneLauncherActivity.java b/src/org/linphone/LinphoneLauncherActivity.java index fc1c3a9c7..584057a68 100644 --- a/src/org/linphone/LinphoneLauncherActivity.java +++ b/src/org/linphone/LinphoneLauncherActivity.java @@ -31,9 +31,9 @@ import android.os.Bundle; import android.os.Handler; /** - * + * * Launch Linphone main activity when Service is ready. - * + * * @author Guillaume Beraudo * */ @@ -45,19 +45,19 @@ public class LinphoneLauncherActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + // Hack to avoid to draw twice LinphoneActivity on tablets if (getResources().getBoolean(R.bool.orientation_portrait_only)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } setContentView(R.layout.launch_screen); - + mHandler = new Handler(); - + if (LinphoneService.isReady()) { onServiceReady(); } else { - // start linphone as background + // start linphone as background startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); mThread = new ServiceWaitThread(); mThread.start(); @@ -78,7 +78,7 @@ public class LinphoneLauncherActivity extends Activity { if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { BluetoothManager.getInstance().initBluetooth(); } - + mHandler.postDelayed(new Runnable() { @Override public void run() { diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index 1e4251929..a26ab7c26 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -140,10 +140,13 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag private static boolean sExited; private boolean mAudioFocused; private boolean echoTesterIsRunning; + private boolean dozeModeEnabled; private int mLastNetworkType=-1; private ConnectivityManager mConnectivityManager; private BroadcastReceiver mKeepAliveReceiver; + private BroadcastReceiver mDozeReceiver; private IntentFilter mKeepAliveIntentFilter; + private IntentFilter mDozeIntentFilter; private Handler mHandler = new Handler(); private WakeLock mIncallWakeLock; private LinphoneAccountCreator accountCreator; @@ -188,6 +191,12 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag mConnectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); mR = c.getResources(); mPendingChatFileMessage = new ArrayList(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + dozeModeEnabled = ((PowerManager)c.getSystemService(c.POWER_SERVICE)).isDeviceIdleMode(); + } else { + dozeModeEnabled = false; + } } private static final int LINPHONE_VOLUME_STREAM = STREAM_VOICE_CALL; @@ -663,6 +672,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag finally { try { mServiceContext.unregisterReceiver(mKeepAliveReceiver); + mServiceContext.unregisterReceiver(mDozeReceiver); } catch (Exception e) { Log.e(e); } @@ -679,6 +689,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag be sent by the system. */ mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); + mServiceContext.registerReceiver(mDozeReceiver, mDozeIntentFilter); sExited = false; } @@ -798,9 +809,17 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag */ mKeepAliveIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON); mKeepAliveIntentFilter.addAction(Intent.ACTION_SCREEN_OFF); + mKeepAliveReceiver = new KeepAliveReceiver(); mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter); + mDozeIntentFilter = new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); + mDozeIntentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); + + mDozeReceiver = new DozeReceiver(); + + mServiceContext.registerReceiver(mDozeReceiver, mDozeIntentFilter); + updateNetworkReachability(); resetCameraFromPreferences(); @@ -870,7 +889,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag ConnectivityManager cm = (ConnectivityManager) mServiceContext.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo eventInfo = cm.getActiveNetworkInfo(); - if (eventInfo == null || eventInfo.getState() == NetworkInfo.State.DISCONNECTED) { + if (eventInfo == null || eventInfo.getState() == NetworkInfo.State.DISCONNECTED || dozeModeEnabled) { Log.i("No connectivity: setting network unreachable"); mLc.setNetworkReachable(false); } else if (eventInfo.getState() == NetworkInfo.State.CONNECTED){ @@ -1495,6 +1514,10 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag dialog.show(); } + public void setDozeModeEnabled(boolean b) { + dozeModeEnabled = b; + } + @SuppressWarnings("serial") public static class LinphoneConfigException extends LinphoneException { diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index a0f3ccf9f..32f29a608 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -64,16 +64,16 @@ import android.provider.MediaStore; import android.view.WindowManager; /** - * + * * Linphone service, reacting to Incoming calls, ...
- * + * * Roles include: