diff options
Diffstat (limited to 'src/com/android')
10 files changed, 162 insertions, 42 deletions
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java index fd24887c7..ec860856b 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java @@ -293,6 +293,14 @@ public class CellBroadcastAlertDialog extends Activity { | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); + // Disable home button when alert dialog is showing if mute_by_physical_button is false. + if (!CellBroadcastSettings.getResources(getApplicationContext(), + SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) + .getBoolean(R.bool.mute_by_physical_button)) { + final View decorView = win.getDecorView(); + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + } + setFinishOnTouchOutside(false); // Initialize the view. @@ -389,7 +397,7 @@ public class CellBroadcastAlertDialog extends Activity { @Override protected void onStop() { - super.onStop(); + Log.d(TAG, "onStop called"); // When the activity goes in background eg. clicking Home button, send notification. // Avoid doing this when activity will be recreated because of orientation change or if // screen goes off @@ -400,6 +408,7 @@ public class CellBroadcastAlertDialog extends Activity { } // Stop playing alert sound/vibration/speech (if started) stopService(new Intent(this, CellBroadcastAlertAudio.class)); + super.onStop(); } @Override @@ -751,7 +760,8 @@ public class CellBroadcastAlertDialog extends Activity { } @Override - public boolean dispatchKeyEvent(KeyEvent event) { + public boolean onKeyDown(int keyCode, KeyEvent event) { + Log.d(TAG, "onKeyDown: " + event); SmsCbMessage message = getLatestMessage(); if (CellBroadcastSettings.getResources(getApplicationContext(), message.getSubscriptionId()) .getBoolean(R.bool.mute_by_physical_button)) { @@ -769,8 +779,14 @@ public class CellBroadcastAlertDialog extends Activity { default: break; } + return super.onKeyDown(keyCode, event); + } else { + if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) { + // TODO: do something to prevent screen off + } + // Disable all physical keys if mute_by_physical_button is false + return true; } - return super.dispatchKeyEvent(event); } @Override diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java index ce810c0bf..53c32a601 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java @@ -312,7 +312,7 @@ public class CellBroadcastAlertService extends Service CellBroadcastChannelRange range = channelManager .getCellBroadcastChannelRangeFromMessage(message); if (CellBroadcastReceiver.isTestingMode(getApplicationContext()) - || range.mWriteToSmsInbox) { + || (range != null && range.mWriteToSmsInbox)) { writeMessageToSmsInbox(message); } } diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastChannelManager.java b/src/com/android/cellbroadcastreceiver/CellBroadcastChannelManager.java index 32d93f9e7..178b026b6 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastChannelManager.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastChannelManager.java @@ -92,8 +92,8 @@ public class CellBroadcastChannelManager { private static final String KEY_ALERT_DURATION = "alert_duration"; /** Defines if Do Not Disturb should be overridden for this alert */ private static final String KEY_OVERRIDE_DND = "override_dnd"; - /** Defines whether writing alert message to SMS inbox. */ - private static final String KEY_WRITE_TO_SMS_INBOX = "write_to_sms_inbox"; + /** Defines whether writing alert message should exclude from SMS inbox. */ + private static final String KEY_EXCLUDE_FROM_SMS_INBOX = "exclude_from_sms_inbox"; /** * Defines whether the channel needs language filter or not. True indicates that the alert @@ -122,7 +122,9 @@ public class CellBroadcastChannelManager { // by default no custom alert duration. play the alert tone with the tone's duration. public int mAlertDuration = -1; public boolean mOverrideDnd = false; - public boolean mWriteToSmsInbox = false; + // If enable_write_alerts_to_sms_inbox is true, write to sms inbox is enabled by default + // for all channels except for channels which explicitly set to exclude from sms inbox. + public boolean mWriteToSmsInbox = true; public CellBroadcastChannelRange(Context context, int subId, String channelRange) { @@ -192,9 +194,9 @@ public class CellBroadcastChannelManager { mOverrideDnd = true; } break; - case KEY_WRITE_TO_SMS_INBOX: + case KEY_EXCLUDE_FROM_SMS_INBOX: if (value.equalsIgnoreCase("true")) { - mWriteToSmsInbox = true; + mWriteToSmsInbox = false; } break; } diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java index be5d38a23..c290dd809 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java @@ -34,6 +34,7 @@ import androidx.annotation.NonNull; import com.android.cellbroadcastreceiver.CellBroadcastChannelManager.CellBroadcastChannelRange; import com.android.internal.annotations.VisibleForTesting; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -98,6 +99,23 @@ public class CellBroadcastConfigService extends IntentService { return subIds; } + private void resetCellBroadcastChannels(int subId) { + SmsManager manager; + if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { + manager = SmsManager.getSmsManagerForSubscriptionId(subId); + } else { + manager = SmsManager.getDefault(); + } + + // TODO: Call manager.resetAllCellBroadcastRanges() in Android S. + try { + Method method = SmsManager.class.getDeclaredMethod("resetAllCellBroadcastRanges"); + method.invoke(manager); + } catch (Exception e) { + log("Can't reset cell broadcast ranges. e=" + e); + } + } + /** * Enable cell broadcast messages channels. Messages can be only received on the * enabled channels. @@ -106,6 +124,7 @@ public class CellBroadcastConfigService extends IntentService { */ @VisibleForTesting public void enableCellBroadcastChannels(int subId) { + resetCellBroadcastChannels(subId); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); Resources res = CellBroadcastSettings.getResources(this, subId); diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastContentProvider.java b/src/com/android/cellbroadcastreceiver/CellBroadcastContentProvider.java index 4f7572d6b..6c93104af 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastContentProvider.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastContentProvider.java @@ -34,6 +34,7 @@ import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.text.TextUtils; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; /** * ContentProvider for the database of received cell broadcasts. @@ -68,7 +69,8 @@ public class CellBroadcastContentProvider extends ContentProvider { } /** The database for this content provider. */ - private SQLiteOpenHelper mOpenHelper; + @VisibleForTesting + public SQLiteOpenHelper mOpenHelper; /** * Initialize content provider. @@ -232,7 +234,8 @@ public class CellBroadcastContentProvider extends ContentProvider { * @param message the message to insert * @return true if the broadcast is new, false if it's a duplicate broadcast. */ - boolean insertNewBroadcast(SmsCbMessage message) { + @VisibleForTesting + public boolean insertNewBroadcast(SmsCbMessage message) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); ContentValues cv = getContentValues(message); @@ -257,7 +260,8 @@ public class CellBroadcastContentProvider extends ContentProvider { * @param rowId the row ID of the broadcast to delete * @return true if the database was updated, false otherwise */ - boolean deleteBroadcast(long rowId) { + @VisibleForTesting + public boolean deleteBroadcast(long rowId) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int rowCount = db.delete(CellBroadcastDatabaseHelper.TABLE_NAME, @@ -275,7 +279,8 @@ public class CellBroadcastContentProvider extends ContentProvider { * Internal method to delete all cell broadcasts and notify observers. * @return true if the database was updated, false otherwise */ - boolean deleteAllBroadcasts() { + @VisibleForTesting + public boolean deleteAllBroadcasts() { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int rowCount = db.delete(CellBroadcastDatabaseHelper.TABLE_NAME, null, null); diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastDatabaseHelper.java b/src/com/android/cellbroadcastreceiver/CellBroadcastDatabaseHelper.java index fd736f330..ff264d3a2 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastDatabaseHelper.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastDatabaseHelper.java @@ -25,7 +25,9 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.RemoteException; import android.provider.Telephony; +import android.provider.Telephony.CellBroadcasts; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; /** * Open, create, and upgrade the cell broadcast SQLite database. Previously an inner class of @@ -38,7 +40,8 @@ public class CellBroadcastDatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "CellBroadcastDatabaseHelper"; private static final String DATABASE_NAME = "cell_broadcasts.db"; - static final String TABLE_NAME = "broadcasts"; + @VisibleForTesting + public static final String TABLE_NAME = "broadcasts"; /* * Query columns for instantiating SmsCbMessage. @@ -68,6 +71,37 @@ public class CellBroadcastDatabaseHelper extends SQLiteOpenHelper { }; /** + * Returns a string used to create the cell broadcast table. This is exposed so the unit test + * can construct its own in-memory database to match the cell broadcast db. + */ + @VisibleForTesting + public static String getStringForCellBroadcastTableCreation(String tableName) { + return "CREATE TABLE " + tableName + " (" + + CellBroadcasts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + CellBroadcasts.SLOT_INDEX + " INTEGER DEFAULT 0," + + CellBroadcasts.GEOGRAPHICAL_SCOPE + " INTEGER," + + CellBroadcasts.PLMN + " TEXT," + + CellBroadcasts.LAC + " INTEGER," + + CellBroadcasts.CID + " INTEGER," + + CellBroadcasts.SERIAL_NUMBER + " INTEGER," + + Telephony.CellBroadcasts.SERVICE_CATEGORY + " INTEGER," + + Telephony.CellBroadcasts.LANGUAGE_CODE + " TEXT," + + Telephony.CellBroadcasts.MESSAGE_BODY + " TEXT," + + Telephony.CellBroadcasts.DELIVERY_TIME + " INTEGER," + + Telephony.CellBroadcasts.MESSAGE_READ + " INTEGER," + + Telephony.CellBroadcasts.MESSAGE_FORMAT + " INTEGER," + + Telephony.CellBroadcasts.MESSAGE_PRIORITY + " INTEGER," + + Telephony.CellBroadcasts.ETWS_WARNING_TYPE + " INTEGER," + + Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS + " INTEGER," + + Telephony.CellBroadcasts.CMAS_CATEGORY + " INTEGER," + + Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE + " INTEGER," + + Telephony.CellBroadcasts.CMAS_SEVERITY + " INTEGER," + + Telephony.CellBroadcasts.CMAS_URGENCY + " INTEGER," + + Telephony.CellBroadcasts.CMAS_CERTAINTY + " INTEGER);"; + } + + + /** * Database version 1: initial version (support removed) * Database version 2-9: (reserved for OEM database customization) (support removed) * Database version 10: adds ETWS and CMAS columns and CDMA support (support removed) @@ -87,28 +121,7 @@ public class CellBroadcastDatabaseHelper extends SQLiteOpenHelper { @Override public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + TABLE_NAME + " (" - + Telephony.CellBroadcasts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," - + Telephony.CellBroadcasts.SLOT_INDEX + " INTEGER DEFAULT 0," - + Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE + " INTEGER," - + Telephony.CellBroadcasts.PLMN + " TEXT," - + Telephony.CellBroadcasts.LAC + " INTEGER," - + Telephony.CellBroadcasts.CID + " INTEGER," - + Telephony.CellBroadcasts.SERIAL_NUMBER + " INTEGER," - + Telephony.CellBroadcasts.SERVICE_CATEGORY + " INTEGER," - + Telephony.CellBroadcasts.LANGUAGE_CODE + " TEXT," - + Telephony.CellBroadcasts.MESSAGE_BODY + " TEXT," - + Telephony.CellBroadcasts.DELIVERY_TIME + " INTEGER," - + Telephony.CellBroadcasts.MESSAGE_READ + " INTEGER," - + Telephony.CellBroadcasts.MESSAGE_FORMAT + " INTEGER," - + Telephony.CellBroadcasts.MESSAGE_PRIORITY + " INTEGER," - + Telephony.CellBroadcasts.ETWS_WARNING_TYPE + " INTEGER," - + Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS + " INTEGER," - + Telephony.CellBroadcasts.CMAS_CATEGORY + " INTEGER," - + Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE + " INTEGER," - + Telephony.CellBroadcasts.CMAS_SEVERITY + " INTEGER," - + Telephony.CellBroadcasts.CMAS_URGENCY + " INTEGER," - + Telephony.CellBroadcasts.CMAS_CERTAINTY + " INTEGER);"); + db.execSQL(getStringForCellBroadcastTableCreation(TABLE_NAME)); db.execSQL("CREATE INDEX IF NOT EXISTS deliveryTimeIndex ON " + TABLE_NAME + " (" + Telephony.CellBroadcasts.DELIVERY_TIME + ");"); diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastReceiver.java b/src/com/android/cellbroadcastreceiver/CellBroadcastReceiver.java index 91e562921..b02f75c7d 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastReceiver.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastReceiver.java @@ -36,6 +36,7 @@ import android.preference.PreferenceManager; import android.provider.Telephony; import android.provider.Telephony.CellBroadcasts; import android.telephony.CarrierConfigManager; +import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.cdma.CdmaSmsCbProgramData; @@ -63,9 +64,15 @@ public class CellBroadcastReceiver extends BroadcastReceiver { @VisibleForTesting public static final String TESTING_MODE = "testing_mode"; + // Key to access the shared preference of service state. + private static final String SERVICE_STATE = "service_state"; + // shared preference under developer settings private static final String ENABLE_ALERT_MASTER_PREF = "enable_alerts_master_toggle"; + public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE"; + public static final String EXTRA_VOICE_REG_STATE = "voiceRegState"; + // Intent actions and extras public static final String CELLBROADCAST_START_CONFIG_ACTION = "com.android.cellbroadcastreceiver.intent.START_CONFIG"; @@ -121,6 +128,16 @@ public class CellBroadcastReceiver extends BroadcastReceiver { initializeSharedPreference(); enableLauncher(); startConfigService(); + } else if (ACTION_SERVICE_STATE.equals(action)) { + // lower layer clears channel configurations under APM, thus need to resend + // configurations once moving back from APM. This should be fixed in lower layer + // going forward. + int ss = intent.getIntExtra(EXTRA_VOICE_REG_STATE, ServiceState.STATE_IN_SERVICE); + if (ss != ServiceState.STATE_POWER_OFF + && getServiceState(context) == ServiceState.STATE_POWER_OFF) { + startConfigService(); + } + setServiceState(ss); } else if (CELLBROADCAST_START_CONFIG_ACTION.equals(action) || SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED.equals(action)) { startConfigService(); @@ -181,6 +198,24 @@ public class CellBroadcastReceiver extends BroadcastReceiver { } /** + * Store the current service state for voice registration. + * + * @param ss current voice registration service state. + */ + private void setServiceState(int ss) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + sp.edit().putInt(SERVICE_STATE, ss).commit(); + } + + /** + * @return the stored voice registration service state + */ + private static int getServiceState(Context context) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); + return sp.getInt(SERVICE_STATE, ServiceState.STATE_IN_SERVICE); + } + + /** * update reminder interval */ @VisibleForTesting diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastResources.java b/src/com/android/cellbroadcastreceiver/CellBroadcastResources.java index 70e80c119..23f4dd19b 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastResources.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastResources.java @@ -319,12 +319,14 @@ public class CellBroadcastResources { } if (channelManager.checkCellBroadcastChannelRange(serviceCategory, R.array.cmas_alert_extreme_channels_range_strings)) { - if (cmasInfo.getSeverity() == SmsCbCmasInfo.CMAS_SEVERITY_EXTREME - && cmasInfo.getUrgency() == SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE) { - if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED) { - return R.string.cmas_extreme_immediate_observed_alert; - } else if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY) { - return R.string.cmas_extreme_immediate_likely_alert; + if (message.isCmasMessage()) { + if (cmasInfo.getSeverity() == SmsCbCmasInfo.CMAS_SEVERITY_EXTREME + && cmasInfo.getUrgency() == SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE) { + if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED) { + return R.string.cmas_extreme_immediate_observed_alert; + } else if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY) { + return R.string.cmas_extreme_immediate_likely_alert; + } } } return R.string.cmas_extreme_alert; diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastSearchIndexableProvider.java b/src/com/android/cellbroadcastreceiver/CellBroadcastSearchIndexableProvider.java index 3d56f7b05..16dbc2649 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastSearchIndexableProvider.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastSearchIndexableProvider.java @@ -38,6 +38,7 @@ import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLU import android.annotation.Nullable; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.Cursor; import android.database.MatrixCursor; @@ -108,6 +109,10 @@ public class CellBroadcastSearchIndexableProvider extends SearchIndexablesProvid @Override public Cursor queryXmlResources(String[] projection) { + if (isAutomotive()) { + return null; + } + MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS); final int count = INDEXABLE_RES.length; for (int n = 0; n < count; n++) { @@ -126,6 +131,10 @@ public class CellBroadcastSearchIndexableProvider extends SearchIndexablesProvid @Override public Cursor queryRawData(String[] projection) { + if (isAutomotive()) { + return null; + } + MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS); final Resources res = getResourcesMethod(); @@ -255,4 +264,14 @@ public class CellBroadcastSearchIndexableProvider extends SearchIndexablesProvid return cursor; } + + /** + * Whether or not this is an Android Automotive platform. + * @return true if the current platform is automotive + */ + @VisibleForTesting + public boolean isAutomotive() { + return getContextMethod().getPackageManager().hasSystemFeature( + PackageManager.FEATURE_AUTOMOTIVE); + } } diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java b/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java index 679e75437..8702f25d2 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java @@ -59,6 +59,9 @@ public class CellBroadcastSettings extends Activity { private static final boolean DBG = false; + // Preference key for alert header (A text view, not clickable). + public static final String KEY_ALERTS_HEADER = "alerts_header"; + // Preference key for a master toggle to enable/disable all alerts message (default enabled). public static final String KEY_ENABLE_ALERTS_MASTER_TOGGLE = "enable_alerts_master_toggle"; @@ -197,6 +200,7 @@ public class CellBroadcastSettings extends Activity { private TwoStatePreference mStateLocalTestCheckBox; private TwoStatePreference mEnableVibrateCheckBox; private Preference mAlertHistory; + private Preference mAlertsHeader; private PreferenceCategory mAlertCategory; private PreferenceCategory mAlertPreferencesCategory; private boolean mDisableSevereWhenExtremeDisabled = true; @@ -261,6 +265,7 @@ public class CellBroadcastSettings extends Activity { mStateLocalTestCheckBox = (TwoStatePreference) findPreference(KEY_ENABLE_STATE_LOCAL_TEST_ALERTS); mAlertHistory = findPreference(KEY_EMERGENCY_ALERT_HISTORY); + mAlertsHeader = findPreference(KEY_ALERTS_HEADER); mReceiveCmasInSecondLanguageCheckBox = (TwoStatePreference) findPreference (KEY_RECEIVE_CMAS_IN_SECOND_LANGUAGE); mEnableVibrateCheckBox = findPreference(KEY_ENABLE_ALERT_VIBRATE); @@ -502,6 +507,10 @@ public class CellBroadcastSettings extends Activity { res.getBoolean(R.bool.show_override_dnd_settings) || !res.getBoolean(R.bool.override_dnd_default)); } + if (mAlertsHeader != null) { + mAlertsHeader.setVisible( + !getContext().getString(R.string.alerts_header_summary).isEmpty()); + } } private void initReminderIntervalList() { |