Home | History | Annotate | Download | only in transaction
      1 /*
      2  * Copyright (C) 2007-2008 Esmertec AG.
      3  * Copyright (C) 2007-2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.transaction;
     19 
     20 import android.app.Service;
     21 import android.content.BroadcastReceiver;
     22 import android.content.ComponentName;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.provider.Telephony.Sms.Intents;
     26 import android.os.PowerManager;
     27 
     28 /**
     29  * Handle incoming SMSes.  Just dispatches the work off to a Service.
     30  */
     31 public class SmsReceiver extends BroadcastReceiver {
     32     static final Object mStartingServiceSync = new Object();
     33     static PowerManager.WakeLock mStartingService;
     34     private static SmsReceiver sInstance;
     35 
     36     public static SmsReceiver getInstance() {
     37         if (sInstance == null) {
     38             sInstance = new SmsReceiver();
     39         }
     40         return sInstance;
     41     }
     42 
     43     @Override
     44     public void onReceive(Context context, Intent intent) {
     45         onReceiveWithPrivilege(context, intent, false);
     46     }
     47 
     48     protected void onReceiveWithPrivilege(Context context, Intent intent, boolean privileged) {
     49         // If 'privileged' is false, it means that the intent was delivered to the base
     50         // no-permissions receiver class.  If we get an SMS_RECEIVED message that way, it
     51         // means someone has tried to spoof the message by delivering it outside the normal
     52         // permission-checked route, so we just ignore it.
     53         if (!privileged && intent.getAction().equals(Intents.SMS_RECEIVED_ACTION)) {
     54             return;
     55         }
     56 
     57         intent.setClass(context, SmsReceiverService.class);
     58         intent.putExtra("result", getResultCode());
     59         beginStartingService(context, intent);
     60     }
     61 
     62     // N.B.: <code>beginStartingService</code> and
     63     // <code>finishStartingService</code> were copied from
     64     // <code>com.android.calendar.AlertReceiver</code>.  We should
     65     // factor them out or, even better, improve the API for starting
     66     // services under wake locks.
     67 
     68     /**
     69      * Start the service to process the current event notifications, acquiring
     70      * the wake lock before returning to ensure that the service will run.
     71      */
     72     public static void beginStartingService(Context context, Intent intent) {
     73         synchronized (mStartingServiceSync) {
     74             if (mStartingService == null) {
     75                 PowerManager pm =
     76                     (PowerManager)context.getSystemService(Context.POWER_SERVICE);
     77                 mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
     78                         "StartingAlertService");
     79                 mStartingService.setReferenceCounted(false);
     80             }
     81             mStartingService.acquire();
     82             context.startService(intent);
     83         }
     84     }
     85 
     86     /**
     87      * Called back by the service when it has finished processing notifications,
     88      * releasing the wake lock if the service is now stopping.
     89      */
     90     public static void finishStartingService(Service service, int startId) {
     91         synchronized (mStartingServiceSync) {
     92             if (mStartingService != null) {
     93                 if (service.stopSelfResult(startId)) {
     94                     mStartingService.release();
     95                 }
     96             }
     97         }
     98     }
     99 }
    100