/*
* Copyright (C) 2012 Louis Fazen
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.alphabetbloc.accessadmin.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import com.alphabetbloc.accessadmin.R;
import com.alphabetbloc.accessadmin.data.Constants;
import com.alphabetbloc.accessadmin.data.EncryptedPreferences;
import com.alphabetbloc.accessadmin.data.Policy;
import com.alphabetbloc.accessadmin.services.DeviceAdminService;
import com.commonsware.cwac.wakeful.WakefulIntentService;
/**
* Receives and parses SMS messages, sends the intent on to DeviceAdminService,
* and blocks the SMS from being placed into the inbox.
*
* @author Louis Fazen (louis.fazen@gmail.com)
*/
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = SmsReceiver.class.getSimpleName();
private static String Imei;
private static String lockDevice;
private static String sendGPS;
private static String wipeData;
private static String wipeSdOdk;
private static String resetPwdToDefault;
private static String resetPwdToSmsPwd;
private static String lockRandomPwd;
private static String resetAdminId;
private static String holdScreen;
private static String stopHoldScreen;
private static String cancelAlarm;
private static String editAccessMrsPreference;
private static String sendSms;
private static String holdDeviceLocked;
private static String verifySim;
private static String mSmsMessage = null;
private Context mContext;
private int mExtra;
public SmsReceiver() {
// Auto-generated constructor stub
}
@Override
public void onReceive(Context context, Intent intent) {
if(Constants.DEBUG)
Log.v("SmsReceiver", "Received a new SMS");
mContext = context;
Policy policy = new Policy(context);
if (intent.getAction().equals(Constants.SMS_RECEIVED) && policy.isAdminActive()) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] smsMessage = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
smsMessage[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
if (smsMessage.length > -1) {
String message = smsMessage[0].getMessageBody();
if(Constants.DEBUG)
Log.v("SmsReceiver", "Received a new SMS with \n\tMESSAGE=\'" + message + "\'");
String prefix = Constants.SMS_CODE_ADMIN_PREFIX;
if (message.length() > prefix.length()) {
String substring = message.substring(0, prefix.length());
if (substring.equalsIgnoreCase(Constants.SMS_CODE_ADMIN_PREFIX))
readSMS(message);
}
}
}
}
}
private void readSMS(String sms) {
if (Imei == null)
createSmsStrings();
if (matchingSmsString(sms)) {
try {
abortBroadcast();
} catch (Exception e) {
Log.e(TAG, "Unordered broadcast");
}
Intent i = new Intent(mContext, DeviceAdminService.class);
i.putExtra(Constants.DEVICE_ADMIN_WORK, mExtra);
if (mSmsMessage != null)
i.putExtra(Constants.SMS_MESSAGE, mSmsMessage);
WakefulIntentService.sendWakefulWork(mContext, i);
}
}
private void createSmsStrings() {
final SharedPreferences prefs = new EncryptedPreferences(mContext, mContext.getSharedPreferences(Constants.ENCRYPTED_PREFS, Context.MODE_PRIVATE));
String smsAdminCode = Constants.SMS_CODE_ADMIN_PREFIX + prefs.getString(Constants.UNIQUE_DEVICE_ID, null);
if (Constants.DEBUG)
Log.e("CODE", "smsCode=" + smsAdminCode);
// REQUIRE smsAdminCode:
lockDevice = smsAdminCode + Constants.SMS_CODE_LOCK;
sendGPS = smsAdminCode + Constants.SMS_CODE_GPS;
wipeData = smsAdminCode + Constants.SMS_CODE_WIPE_DATA;
wipeSdOdk = smsAdminCode + Constants.SMS_CODE_WIPE_ODK;
holdScreen = smsAdminCode + Constants.SMS_CODE_HOLD;
stopHoldScreen = smsAdminCode + Constants.SMS_CODE_STOP_HOLD;
cancelAlarm = smsAdminCode + Constants.SMS_CODE_CANCEL_ALARM;
resetPwdToDefault = smsAdminCode + Constants.SMS_CODE_RESET_PWD_DEFAULT;
resetPwdToSmsPwd = smsAdminCode + Constants.SMS_CODE_RESET_PWD_TO_SMS_PWD;
editAccessMrsPreference = smsAdminCode + Constants.SMS_CODE_EDIT_ACCESS_MRS_PREF;
sendSms = smsAdminCode + Constants.SMS_CODE_SEND_SMS;
holdDeviceLocked = smsAdminCode + Constants.SMS_CODE_HOLD_LOCKED;
verifySim = smsAdminCode + Constants.SMS_CODE_VERIFY_SIM;
// DO NOT REQUIRE smsAdminCode:
lockRandomPwd = Constants.SMS_CODE_ADMIN_PREFIX + Constants.SMS_CODE_RESET_PWD_SECRET;
resetAdminId = Constants.SMS_CODE_ADMIN_PREFIX + Constants.SMS_CODE_RESET_ADMIN_ID;
}
private boolean matchingSmsString(String sms) {
if (sms.equals(lockDevice)) {
mExtra = Constants.LOCK_SCREEN;
return true;
} else if (sms.equals(sendGPS)) {
mExtra = Constants.SEND_GPS;
return true;
} else if (sms.equals(wipeData)) {
mExtra = Constants.WIPE_DATA;
return true;
} else if (sms.equals(wipeSdOdk)) {
mExtra = Constants.WIPE_ODK_DATA;
return true;
} else if (sms.equals(lockRandomPwd)) {
mExtra = Constants.LOCK_RANDOM_PWD;
return true;
} else if (sms.equals(resetAdminId)) {
mExtra = Constants.RESET_ADMIN_ID;
return true;
} else if (sms.equals(cancelAlarm)) {
mExtra = Constants.CANCEL_ALARMS;
return true;
} else if (sms.equals(stopHoldScreen)) {
mExtra = Constants.STOP_HOLD_DEVICE;
return true;
} else if (sms.equals(resetPwdToDefault)) {
mExtra = Constants.RESET_TO_DEFAULT_PWD;
return true;
} else if (sms.equals(sendSms)) {
mExtra = Constants.SEND_SMS;
mSmsMessage = "AccessAdmin is active on this device. Version = " + mContext.getString(R.string.app_version);
return true;
} else if (sms.equals(holdDeviceLocked)) {
mExtra = Constants.HOLD_DEVICE_LOCKED;
return true;
} else if (sms.equals(verifySim)) {
mExtra = Constants.VERIFY_SIM;
return true;
} else if (sms.contains(editAccessMrsPreference)) {
mExtra = Constants.EDIT_ACCESS_MRS_PREF;
int message = sms.indexOf(":");
mSmsMessage = sms.substring(message + 1);
return true;
} else if (sms.contains(resetPwdToSmsPwd)) {
mExtra = Constants.RESET_PWD_TO_SMS_PWD;
int message = sms.indexOf(":");
mSmsMessage = sms.substring(message + 1);
return true;
} else if (sms.contains(holdScreen)) {
mExtra = Constants.HOLD_DEVICE;
int message = sms.indexOf(":");
mSmsMessage = sms.substring(message + 1);
return true;
} else {
return false;
}
}
}