Merge "DO NOT MERGE release wakelock if no activity in Bluetooth MAP profile to avoid waste power." into klp-dev
diff --git a/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
index a876740..b497082 100644
--- a/src/com/android/bluetooth/map/BluetoothMapObexServer.java
+++ b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -100,6 +100,7 @@
     public int onConnect(final HeaderSet request, HeaderSet reply) {
         if (D) Log.d(TAG, "onConnect():");
         if (V) logHeader(request);
+        notifyUpdateWakeLock();
         try {
             byte[] uuid = (byte[])request.getHeader(HeaderSet.TARGET);
             if (uuid == null) {
@@ -149,7 +150,7 @@
     public void onDisconnect(final HeaderSet req, final HeaderSet resp) {
         if (D) Log.d(TAG, "onDisconnect(): enter");
         if (V) logHeader(req);
-
+        notifyUpdateWakeLock();
         resp.responseCode = ResponseCodes.OBEX_HTTP_OK;
         if (mCallback != null) {
             Message msg = Message.obtain(mCallback);
@@ -162,6 +163,7 @@
     @Override
     public int onAbort(HeaderSet request, HeaderSet reply) {
         if (D) Log.d(TAG, "onAbort(): enter.");
+        notifyUpdateWakeLock();
         sIsAborted = true;
         return ResponseCodes.OBEX_HTTP_OK;
     }
@@ -169,6 +171,7 @@
     @Override
     public int onPut(final Operation op) {
         if (D) Log.d(TAG, "onPut(): enter");
+        notifyUpdateWakeLock();
         HeaderSet request = null;
         String type, name;
         byte[] appParamRaw;
@@ -321,6 +324,7 @@
             final boolean create) {
         String folderName;
         BluetoothMapFolderElement folder;
+        notifyUpdateWakeLock();
         try {
             folderName = (String)request.getHeader(HeaderSet.NAME);
         } catch (Exception e) {
@@ -366,6 +370,7 @@
 
     @Override
     public int onGet(Operation op) {
+        notifyUpdateWakeLock();
         sIsAborted = false;
         HeaderSet request;
         String type;
@@ -686,6 +691,11 @@
         return ResponseCodes.OBEX_HTTP_OK;
     }
 
+    private void notifyUpdateWakeLock() {
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMapService.MSG_ACQUIRE_WAKE_LOCK;
+        msg.sendToTarget();
+    }
 
     private static final void logHeader(HeaderSet hs) {
         Log.v(TAG, "Dumping HeaderSet " + hs.toString());
diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java
index c5c03ef..3497cf8 100644
--- a/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -97,6 +97,10 @@
 
     public static final int MSG_OBEX_AUTH_CHALL = 5003;
 
+    public static final int MSG_ACQUIRE_WAKE_LOCK = 5004;
+
+    public static final int MSG_RELEASE_WAKE_LOCK = 5005;
+
     private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
 
     private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
@@ -107,6 +111,8 @@
 
     private static final int DISCONNECT_MAP = 3;
 
+    private static final int RELEASE_WAKE_LOCK_DELAY = 10000;
+
     private PowerManager.WakeLock mWakeLock = null;
 
     private BluetoothAdapter mAdapter;
@@ -289,7 +295,8 @@
             mWakeLock.acquire();
         }
 
-        mBluetoothMnsObexClient = new BluetoothMnsObexClient(this, mRemoteDevice);
+        mBluetoothMnsObexClient = new BluetoothMnsObexClient(this, mRemoteDevice,
+                                                             mSessionStatusHandler);
         mMapServer = new BluetoothMapObexServer(mSessionStatusHandler, this,
                                                 mBluetoothMnsObexClient);
         synchronized (this) {
@@ -302,6 +309,11 @@
         BluetoothMapRfcommTransport transport = new BluetoothMapRfcommTransport(mConnSocket);
         mServerSession = new ServerSession(transport, mMapServer, mAuth);
         setState(BluetoothMap.STATE_CONNECTED);
+
+        mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK);
+        mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler
+            .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY);
+
         if (VERBOSE) {
             Log.v(TAG, "startObexServerSession() success!");
         }
@@ -310,6 +322,9 @@
     private void stopObexServerSession() {
         if (DEBUG) Log.d(TAG, "MAP Service stopObexServerSession");
 
+        mSessionStatusHandler.removeMessages(MSG_ACQUIRE_WAKE_LOCK);
+        mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK);
+
         // Release the wake lock if obex transaction is over
         if (mWakeLock != null) {
             mWakeLock.release();
@@ -458,6 +473,27 @@
                 case DISCONNECT_MAP:
                     disconnectMap((BluetoothDevice)msg.obj);
                     break;
+                case MSG_ACQUIRE_WAKE_LOCK:
+                    if (mWakeLock == null) {
+                        PowerManager pm = (PowerManager)getSystemService(
+                                          Context.POWER_SERVICE);
+                        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                                    "StartingObexMapTransaction");
+                        mWakeLock.setReferenceCounted(false);
+                        mWakeLock.acquire();
+                        Log.w(TAG, "Acquire Wake Lock");
+                    }
+                    mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK);
+                    mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler
+                      .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY);
+                    break;
+                case MSG_RELEASE_WAKE_LOCK:
+                    if (mWakeLock != null) {
+                        mWakeLock.release();
+                        mWakeLock = null;
+                        Log.w(TAG, "Release Wake Lock");
+                    }
+                    break;
                 default:
                     break;
             }
diff --git a/src/com/android/bluetooth/map/BluetoothMnsObexClient.java b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
index 544c621..adee460 100644
--- a/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
+++ b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
@@ -58,6 +58,7 @@
     private ClientSession mClientSession;
     private boolean mConnected = false;
     BluetoothDevice mRemoteDevice;
+    private Handler mCallback = null;
     private BluetoothMapContentObserver mObserver;
     private boolean mObserverRegistered = false;
 
@@ -69,7 +70,8 @@
             ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
 
 
-    public BluetoothMnsObexClient(Context context, BluetoothDevice remoteDevice) {
+    public BluetoothMnsObexClient(Context context, BluetoothDevice remoteDevice,
+                                  Handler callback) {
         if (remoteDevice == null) {
             throw new NullPointerException("Obex transport is null");
         }
@@ -79,6 +81,7 @@
         mHandler = new MnsObexClientHandler(looper);
         mContext = context;
         mRemoteDevice = remoteDevice;
+        mCallback = callback;
         mObserver = new BluetoothMapContentObserver(mContext);
         mObserver.init();
     }
@@ -268,6 +271,8 @@
             return responseCode;
         }
 
+        notifyUpdateWakeLock();
+
         request = new HeaderSet();
         BluetoothMapAppParams appParams = new BluetoothMapAppParams();
         appParams.setMasInstanceId(masInstanceId);
@@ -368,4 +373,10 @@
     private void handleSendException(String exception) {
         Log.e(TAG, "Error when sending event: " + exception);
     }
+
+    private void notifyUpdateWakeLock() {
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMapService.MSG_ACQUIRE_WAKE_LOCK;
+        msg.sendToTarget();
+    }
 }