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.Context;
     23 import android.content.Intent;
     24 import android.os.PowerManager;
     25 import android.provider.Telephony.Sms.Intents;
     26 
     27 /**
     28  * Handle incoming SMSes.  Just dispatches the work off to a Service.
     29  */
     30 public class SmsReceiver extends BroadcastReceiver {
     31     static final Object mStartingServiceSync = new Object();
     32     static PowerManager.WakeLock mStartingService;
     33     private static SmsReceiver sInstance;
     34 
     35     public static SmsReceiver getInstance() {
     36         if (sInstance == null) {
     37             sInstance = new SmsReceiver();
     38         }
     39         return sInstance;
     40     }
     41 
     42     @Override
     43     public void onReceive(Context context, Intent intent) {
     44         onReceiveWithPrivilege(context, intent, false);
     45     }
     46 
     47     protected void onReceiveWithPrivilege(Context context, Intent intent, boolean privileged) {
     48         // If 'privileged' is false, it means that the intent was delivered to the base
     49         // no-permissions receiver class.  If we get an SMS_RECEIVED message that way, it
     50         // means someone has tried to spoof the message by delivering it outside the normal
     51         // permission-checked route, so we just ignore it.
     52         if (!privileged && intent.getAction().equals(Intents.SMS_DELIVER_ACTION)) {
     53             return;
     54         }
     55 
     56         intent.setClass(context, SmsReceiverService.class);
     57         intent.putExtra("result", getResultCode());
     58         beginStartingService(context, intent);
     59     }
     60 
     61     // N.B.: <code>beginStartingService</code> and
     62     // <code>finishStartingService</code> were copied from
     63     // <code>com.android.calendar.AlertReceiver</code>.  We should
     64     // factor them out or, even better, improve the API for starting
     65     // services under wake locks.
     66 
     67     /**
     68      * Start the service to process the current event notifications, acquiring
     69      * the wake lock before returning to ensure that the service will run.
     70      */
     71     public static void beginStartingService(Context context, Intent intent) {
     72         synchronized (mStartingServiceSync) {
     73             if (mStartingService == null) {
     74                 PowerManager pm =
     75                     (PowerManager)context.getSystemService(Context.POWER_SERVICE);
     76                 mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
     77                         "StartingAlertService");
     78                 mStartingService.setReferenceCounted(false);
     79             }
     80             mStartingService.acquire();
     81             context.startService(intent);
     82         }
     83     }
     84 
     85     /**
     86      * Called back by the service when it has finished processing notifications,
     87      * releasing the wake lock if the service is now stopping.
     88      */
     89     public static void finishStartingService(Service service, int startId) {
     90         synchronized (mStartingServiceSync) {
     91             if (mStartingService != null) {
     92                 if (service.stopSelfResult(startId)) {
     93                     mStartingService.release();
     94                 }
     95             }
     96         }
     97     }
     98 }
     99