Files
packages_apps_Messaging/src/com/android/messaging/receiver/SmsReceiver.java
T
Michael W e128bff457 Messaging: Language cleanup
No unnecessary boxing, enhanced for loops, redundant checks and throws,
imports (removal, reordering), possible void returns

Change-Id: I7a8e1b2007e3b0906e01b41785c518d02c2f3fab
2024-12-26 15:54:37 +01:00

232 lines
10 KiB
Java

/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* 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.android.messaging.receiver;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.provider.Telephony;
import android.provider.Telephony.Sms;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import com.android.messaging.Factory;
import com.android.messaging.R;
import com.android.messaging.datamodel.NoConfirmationSmsSendService;
import com.android.messaging.datamodel.action.ReceiveSmsMessageAction;
import com.android.messaging.sms.MmsUtils;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.NotificationsUtil;
import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PendingIntentConstants;
import com.android.messaging.util.PhoneUtils;
import java.util.ArrayList;
import java.util.regex.Pattern;
/**
* Class that receives incoming SMS messages through android.provider.Telephony.SMS_RECEIVED
*
* This class serves two purposes:
* - Process phone verification SMS messages
* - Handle SMS messages when the user has enabled us to be the default SMS app (Pre-KLP)
*/
public final class SmsReceiver extends BroadcastReceiver {
private static final String TAG = LogUtil.BUGLE_TAG;
private static ArrayList<Pattern> sIgnoreSmsPatterns;
/**
* Enable or disable the SmsReceiver as appropriate. Pre-KLP we use this receiver for
* receiving incoming SMS messages. For KLP+ this receiver is not used when running as the
* primary user and the SmsDeliverReceiver is used for receiving incoming SMS messages.
* When running as a secondary user, this receiver is still used to trigger the incoming
* notification.
*/
public static void updateSmsReceiveHandler(final Context context) {
// When we're running as the secondary user, we don't get the new SMS_DELIVER intent,
// only the primary user receives that. As secondary, we need to go old-school and
// listen for the SMS_RECEIVED intent. For the secondary user, use this SmsReceiver
// for both sms and mms notification. For the primary user on KLP (and above), we don't
// use the SmsReceiver.
boolean smsReceiverEnabled = OsUtil.isSecondaryUser();
final PackageManager packageManager = context.getPackageManager();
final boolean logv = LogUtil.isLoggable(TAG, LogUtil.VERBOSE);
if (smsReceiverEnabled) {
if (logv) {
LogUtil.v(TAG, "Enabling SMS message receiving");
}
packageManager.setComponentEnabledSetting(
new ComponentName(context, SmsReceiver.class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
} else {
if (logv) {
LogUtil.v(TAG, "Disabling SMS message receiving");
}
packageManager.setComponentEnabledSetting(
new ComponentName(context, SmsReceiver.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
if (logv) {
LogUtil.v(TAG, "Enabling respond via message intent");
}
packageManager.setComponentEnabledSetting(
new ComponentName(context, NoConfirmationSmsSendService.class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
private static final String EXTRA_ERROR_CODE = "errorCode";
private static final String EXTRA_SUB_ID = "subscription";
public static void deliverSmsIntent(final Context context, final Intent intent) {
final android.telephony.SmsMessage[] messages = getMessagesFromIntent(intent);
// Check messages for validity
if (messages == null || messages.length < 1) {
LogUtil.e(TAG, "processReceivedSms: null or zero or ignored message");
return;
}
final int errorCode =
intent.getIntExtra(EXTRA_ERROR_CODE, SendStatusReceiver.NO_ERROR_CODE);
// Always convert negative subIds into -1
int subId = PhoneUtils.getDefault().getEffectiveIncomingSubIdFromSystem(
intent, EXTRA_SUB_ID);
deliverSmsMessages(context, subId, errorCode, messages);
}
public static void deliverSmsMessages(final Context context, final int subId,
final int errorCode, final android.telephony.SmsMessage[] messages) {
final ContentValues messageValues =
MmsUtils.parseReceivedSmsMessage(context, messages, errorCode);
LogUtil.v(TAG, "SmsReceiver.deliverSmsMessages");
final long nowInMillis = System.currentTimeMillis();
final long receivedTimestampMs = MmsUtils.getMessageDate(messages[0], nowInMillis);
messageValues.put(Sms.Inbox.DATE, receivedTimestampMs);
// Default to unread and unseen for us but ReceiveSmsMessageAction will override
// seen for the telephony db.
messageValues.put(Sms.Inbox.READ, 0);
messageValues.put(Sms.Inbox.SEEN, 0);
messageValues.put(Sms.SUBSCRIPTION_ID, subId);
if (messages[0].getMessageClass() == android.telephony.SmsMessage.MessageClass.CLASS_0) {
Factory.get().getUIIntents().launchClassZeroActivity(context, messageValues);
} else {
final ReceiveSmsMessageAction action = new ReceiveSmsMessageAction(messageValues);
action.start();
}
}
@Override
public void onReceive(final Context context, final Intent intent) {
LogUtil.v(TAG, "SmsReceiver.onReceive " + intent);
// On KLP+ we only take delivery of SMS messages in SmsDeliverReceiver.
if (PhoneUtils.getDefault().isSmsEnabled()) {
final String action = intent.getAction();
if (OsUtil.isSecondaryUser() &&
(Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(action) ||
// TODO: update this with the actual constant from Telephony
"android.provider.Telephony.MMS_DOWNLOADED".equals(action))) {
postNewMessageSecondaryUserNotification();
}
}
}
public static void postNewMessageSecondaryUserNotification() {
final Context context = Factory.get().getApplicationContext();
final Resources resources = context.getResources();
final PendingIntent pendingIntent = UIIntents.get()
.getPendingIntentForSecondaryUserNewMessageNotification(context);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context,
NotificationsUtil.DEFAULT_CHANNEL_ID);
builder.setContentTitle(resources.getString(R.string.secondary_user_new_message_title))
.setTicker(resources.getString(R.string.secondary_user_new_message_ticker))
.setSmallIcon(R.drawable.ic_sms_light)
// Returning PRIORITY_HIGH causes L to put up a HUD notification. Without it, the ticker
// isn't displayed.
.setPriority(Notification.PRIORITY_HIGH)
.setContentIntent(pendingIntent);
final NotificationCompat.BigTextStyle bigTextStyle =
new NotificationCompat.BigTextStyle(builder);
bigTextStyle.bigText(resources.getString(R.string.secondary_user_new_message_title));
final Notification notification = bigTextStyle.build();
final NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(Factory.get().getApplicationContext());
int defaults = Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE;
notification.defaults = defaults;
notificationManager.notify(getNotificationTag(),
PendingIntentConstants.SMS_SECONDARY_USER_NOTIFICATION_ID, notification);
}
/**
* Cancel the notification
*/
public static void cancelSecondaryUserNotification() {
final NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(Factory.get().getApplicationContext());
notificationManager.cancel(getNotificationTag(),
PendingIntentConstants.SMS_SECONDARY_USER_NOTIFICATION_ID);
}
private static String getNotificationTag() {
return Factory.get().getApplicationContext().getPackageName() + ":secondaryuser";
}
/**
* Get the SMS messages from the specified SMS intent.
* @return the messages. If there is an error or the message should be ignored, return null.
*/
public static android.telephony.SmsMessage[] getMessagesFromIntent(Intent intent) {
final android.telephony.SmsMessage[] messages = Sms.Intents.getMessagesFromIntent(intent);
// Check messages for validity
if (messages == null || messages.length < 1) {
return null;
}
return messages;
}
/**
* Check the specified SMS intent to see if the message should be ignored
* @return true if the message should be ignored
*/
public static boolean shouldIgnoreMessage(Intent intent) {
return getMessagesFromIntent(intent) == null;
}
}