172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Service;
2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.BroadcastReceiver;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ComponentName;
2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
25f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms.Intents;
2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.PowerManager;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle incoming SMSes.  Just dispatches the work off to a Service.
3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class SmsReceiver extends BroadcastReceiver {
3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static final Object mStartingServiceSync = new Object();
3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    static PowerManager.WakeLock mStartingService;
34cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor    private static SmsReceiver sInstance;
35cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor
36cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor    public static SmsReceiver getInstance() {
37cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor        if (sInstance == null) {
38cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor            sInstance = new SmsReceiver();
39cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor        }
40cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor        return sInstance;
41cd88c0f1da9bc67a67dd7174428ab3195a2dc11fTom Taylor    }
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onReceive(Context context, Intent intent) {
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        onReceiveWithPrivilege(context, intent, false);
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onReceiveWithPrivilege(Context context, Intent intent, boolean privileged) {
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If 'privileged' is false, it means that the intent was delivered to the base
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // no-permissions receiver class.  If we get an SMS_RECEIVED message that way, it
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // means someone has tried to spoof the message by delivering it outside the normal
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // permission-checked route, so we just ignore it.
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!privileged && intent.getAction().equals(Intents.SMS_RECEIVED_ACTION)) {
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.setClass(context, SmsReceiverService.class);
5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.putExtra("result", getResultCode());
5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        beginStartingService(context, intent);
6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // N.B.: <code>beginStartingService</code> and
6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // <code>finishStartingService</code> were copied from
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // <code>com.android.calendar.AlertReceiver</code>.  We should
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // factor them out or, even better, improve the API for starting
6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // services under wake locks.
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Start the service to process the current event notifications, acquiring
7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * the wake lock before returning to ensure that the service will run.
7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void beginStartingService(Context context, Intent intent) {
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        synchronized (mStartingServiceSync) {
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mStartingService == null) {
7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                PowerManager pm =
7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    (PowerManager)context.getSystemService(Context.POWER_SERVICE);
7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        "StartingAlertService");
7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mStartingService.setReferenceCounted(false);
8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mStartingService.acquire();
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            context.startService(intent);
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Called back by the service when it has finished processing notifications,
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * releasing the wake lock if the service is now stopping.
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static void finishStartingService(Service service, int startId) {
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        synchronized (mStartingServiceSync) {
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mStartingService != null) {
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (service.stopSelfResult(startId)) {
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mStartingService.release();
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
100