From 28f63c06894b9ca9252f43bc54a098c0a785d4b4 Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Fri, 15 Oct 2010 01:22:44 +0800 Subject: [PATCH] SipService: add wake lock for incoming INVITE packets. + Keep the wake lock for 500ms. (Some measurements on N1 indicate 160~180ms needed to bring up InCallScreen but since INVITE doesn't come in frequently we can be more generous just to be safe.) + Move MyWakeupLock out of SipService so SipSessionGroup can use it without awkward inter-dependency with SipService. + Add acquire(int timeout) to be used to create the "timed" wake lock. http://b/issue?id=3081828 Change-Id: Iffd1d78d1a5cae9f795252ada75310917095204d --- .../com/android/server/sip/SipService.java | 50 ++----------- .../android/server/sip/SipSessionGroup.java | 17 ++++- .../com/android/server/sip/SipWakeLock.java | 71 +++++++++++++++++++ 3 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 voip/java/com/android/server/sip/SipWakeLock.java diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java index f41f156c1a837..1df08c0b42010 100644 --- a/voip/java/com/android/server/sip/SipService.java +++ b/voip/java/com/android/server/sip/SipService.java @@ -55,7 +55,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Timer; @@ -67,8 +66,8 @@ import javax.sip.SipException; * @hide */ public final class SipService extends ISipService.Stub { - private static final String TAG = "SipService"; - private static final boolean DEBUGV = false; + static final String TAG = "SipService"; + static final boolean DEBUGV = false; private static final boolean DEBUG = true; private static final boolean DEBUG_TIMER = DEBUG && false; private static final int EXPIRY_TIME = 3600; @@ -95,7 +94,7 @@ public final class SipService extends ISipService.Stub { private ConnectivityReceiver mConnectivityReceiver; private boolean mWifiEnabled; - private MyWakeLock mMyWakeLock; + private SipWakeLock mMyWakeLock; /** * Starts the SIP service. Do nothing if the SIP API is not supported on the @@ -117,7 +116,7 @@ public final class SipService extends ISipService.Stub { new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); context.registerReceiver(mWifiStateReceiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)); - mMyWakeLock = new MyWakeLock((PowerManager) + mMyWakeLock = new SipWakeLock((PowerManager) context.getSystemService(Context.POWER_SERVICE)); mTimer = new WakeupTimer(context); @@ -459,7 +458,8 @@ public final class SipService extends ISipService.Stub { private SipSessionGroup createSipSessionGroup(String localIp, SipProfile localProfile, String password) throws SipException { try { - return new SipSessionGroup(localIp, localProfile, password); + return new SipSessionGroup(localIp, localProfile, password, + mMyWakeLock); } catch (IOException e) { // network disconnected Log.w(TAG, "createSipSessionGroup(): network disconnected?"); @@ -546,6 +546,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRinging(ISipSession s, SipProfile caller, String sessionDescription) { + if (DEBUGV) Log.d(TAG, "<<<<< onRinging()"); SipSessionGroup.SipSessionImpl session = (SipSessionGroup.SipSessionImpl) s; synchronized (SipService.this) { @@ -1360,41 +1361,4 @@ public final class SipService extends ISipService.Stub { } } } - - private static class MyWakeLock { - private PowerManager mPowerManager; - private PowerManager.WakeLock mWakeLock; - private HashSet mHolders = new HashSet(); - - MyWakeLock(PowerManager powerManager) { - mPowerManager = powerManager; - } - - synchronized void reset() { - mHolders.clear(); - release(null); - if (DEBUGV) Log.v(TAG, "~~~ hard reset wakelock"); - } - - synchronized void acquire(Object holder) { - mHolders.add(holder); - if (mWakeLock == null) { - mWakeLock = mPowerManager.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock"); - } - if (!mWakeLock.isHeld()) mWakeLock.acquire(); - if (DEBUGV) Log.v(TAG, "acquire wakelock: holder count=" - + mHolders.size()); - } - - synchronized void release(Object holder) { - mHolders.remove(holder); - if ((mWakeLock != null) && mHolders.isEmpty() - && mWakeLock.isHeld()) { - mWakeLock.release(); - } - if (DEBUGV) Log.v(TAG, "release wakelock: holder count=" - + mHolders.size()); - } - } } diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java index 2b8058feda43e..d861fa51accd5 100644 --- a/voip/java/com/android/server/sip/SipSessionGroup.java +++ b/voip/java/com/android/server/sip/SipSessionGroup.java @@ -84,6 +84,7 @@ class SipSessionGroup implements SipListener { private static final String ANONYMOUS = "anonymous"; private static final int EXPIRY_TIME = 3600; // in seconds private static final int CANCEL_CALL_TIMER = 3; // in seconds + private static final long WAKE_LOCK_HOLDING_TIME = 500; // in milliseconds private static final EventObject DEREGISTER = new EventObject("Deregister"); private static final EventObject END_CALL = new EventObject("End call"); @@ -101,6 +102,8 @@ class SipSessionGroup implements SipListener { private SipSessionImpl mCallReceiverSession; private String mLocalIp; + private SipWakeLock mWakeLock; + // call-id-to-SipSession map private Map mSessionMap = new HashMap(); @@ -110,10 +113,11 @@ class SipSessionGroup implements SipListener { * @param password the password of the profile * @throws IOException if cannot assign requested address */ - public SipSessionGroup(String localIp, SipProfile myself, String password) - throws SipException, IOException { + public SipSessionGroup(String localIp, SipProfile myself, String password, + SipWakeLock wakeLock) throws SipException, IOException { mLocalProfile = myself; mPassword = password; + mWakeLock = wakeLock; reset(localIp); } @@ -271,7 +275,14 @@ class SipSessionGroup implements SipListener { } } - public void processRequest(RequestEvent event) { + public void processRequest(final RequestEvent event) { + if (isRequestEvent(Request.INVITE, event)) { + if (DEBUG) Log.d(TAG, "<<<<< got INVITE, thread:" + + Thread.currentThread()); + // Acquire a wake lock and keep it for WAKE_LOCK_HOLDING_TIME; + // should be large enough to bring up the app. + mWakeLock.acquire(WAKE_LOCK_HOLDING_TIME); + } process(event); } diff --git a/voip/java/com/android/server/sip/SipWakeLock.java b/voip/java/com/android/server/sip/SipWakeLock.java new file mode 100644 index 0000000000000..52bc094afab4d --- /dev/null +++ b/voip/java/com/android/server/sip/SipWakeLock.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.sip; + +import android.os.PowerManager; +import android.util.Log; + +import java.util.HashSet; + +class SipWakeLock { + private static final boolean DEBUGV = SipService.DEBUGV; + private static final String TAG = SipService.TAG; + private PowerManager mPowerManager; + private PowerManager.WakeLock mWakeLock; + private PowerManager.WakeLock mTimerWakeLock; + private HashSet mHolders = new HashSet(); + + SipWakeLock(PowerManager powerManager) { + mPowerManager = powerManager; + } + + synchronized void reset() { + mHolders.clear(); + release(null); + if (DEBUGV) Log.v(TAG, "~~~ hard reset wakelock"); + } + + synchronized void acquire(long timeout) { + if (mTimerWakeLock == null) { + mTimerWakeLock = mPowerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock.timer"); + mTimerWakeLock.setReferenceCounted(true); + } + mTimerWakeLock.acquire(timeout); + } + + synchronized void acquire(Object holder) { + mHolders.add(holder); + if (mWakeLock == null) { + mWakeLock = mPowerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock"); + } + if (!mWakeLock.isHeld()) mWakeLock.acquire(); + if (DEBUGV) Log.v(TAG, "acquire wakelock: holder count=" + + mHolders.size()); + } + + synchronized void release(Object holder) { + mHolders.remove(holder); + if ((mWakeLock != null) && mHolders.isEmpty() + && mWakeLock.isHeld()) { + mWakeLock.release(); + } + if (DEBUGV) Log.v(TAG, "release wakelock: holder count=" + + mHolders.size()); + } +}