Home | History | Annotate | Download | only in util
      1 /**
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.util;
     18 
     19 import android.app.Service;
     20 import android.content.Intent;
     21 import android.os.Handler;
     22 import android.os.IBinder;
     23 import android.os.Message;
     24 import android.os.Messenger;
     25 import android.util.Slog;
     26 
     27 /**
     28  * A service that receives Intents and IBinder transactions
     29  * as messages via an AsyncChannel.
     30  * <p>
     31  * The Start Intent arrives as CMD_ASYNC_SERVICE_ON_START_INTENT with msg.arg1 = flags,
     32  * msg.arg2 = startId, and msg.obj = intent.
     33  * <p>
     34  */
     35 abstract public class AsyncService extends Service {
     36     private static final String TAG = "AsyncService";
     37 
     38     protected static final boolean DBG = true;
     39 
     40     /** The command sent when a onStartCommand is invoked */
     41     public static final int CMD_ASYNC_SERVICE_ON_START_INTENT = IBinder.LAST_CALL_TRANSACTION;
     42 
     43     /** The command sent when a onDestroy is invoked */
     44     public static final int CMD_ASYNC_SERVICE_DESTROY = IBinder.LAST_CALL_TRANSACTION + 1;
     45 
     46     /** Messenger transport */
     47     protected Messenger mMessenger;
     48 
     49     /** Message Handler that will receive messages */
     50     Handler mHandler;
     51 
     52     public static final class AsyncServiceInfo {
     53         /** Message Handler that will receive messages */
     54         public Handler mHandler;
     55 
     56         /**
     57          * The flags returned by onStartCommand on how to restart.
     58          * For instance @see android.app.Service#START_STICKY
     59          */
     60         public int mRestartFlags;
     61     }
     62 
     63     AsyncServiceInfo mAsyncServiceInfo;
     64 
     65     /**
     66      * Create the service's handler returning AsyncServiceInfo.
     67      *
     68      * @return AsyncServiceInfo
     69      */
     70     abstract public AsyncServiceInfo createHandler();
     71 
     72     /**
     73      * Get the handler
     74      */
     75     public Handler getHandler() {
     76         return mHandler;
     77     }
     78 
     79     /**
     80      * onCreate
     81      */
     82     @Override
     83     public void onCreate() {
     84         super.onCreate();
     85         mAsyncServiceInfo = createHandler();
     86         mHandler = mAsyncServiceInfo.mHandler;
     87         mMessenger = new Messenger(mHandler);
     88     }
     89 
     90     /**
     91      * Sends the CMD_ASYNC_SERVICE_ON_START_INTENT message.
     92      */
     93     @Override
     94     public int onStartCommand(Intent intent, int flags, int startId) {
     95         if (DBG) Slog.d(TAG, "onStartCommand");
     96 
     97         Message msg = mHandler.obtainMessage();
     98         msg.what = CMD_ASYNC_SERVICE_ON_START_INTENT;
     99         msg.arg1 = flags;
    100         msg.arg2 = startId;
    101         msg.obj = intent;
    102         mHandler.sendMessage(msg);
    103 
    104         return mAsyncServiceInfo.mRestartFlags;
    105     }
    106 
    107     /**
    108      * Called when service is destroyed. After returning the
    109      * service is dead and no more processing should be expected
    110      * to occur.
    111      */
    112     @Override
    113     public void onDestroy() {
    114         if (DBG) Slog.d(TAG, "onDestroy");
    115 
    116         Message msg = mHandler.obtainMessage();
    117         msg.what = CMD_ASYNC_SERVICE_DESTROY;
    118         mHandler.sendMessage(msg);
    119     }
    120 
    121     /**
    122      * Returns the Messenger's binder.
    123      */
    124     @Override
    125     public IBinder onBind(Intent intent) {
    126         return mMessenger.getBinder();
    127     }
    128 }
    129