Merge "Add CellBroadcastService and related permissions"
diff --git a/api/system-current.txt b/api/system-current.txt
index 5bac2b7..3a65dfb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24,6 +24,7 @@
     field public static final String BACKUP = "android.permission.BACKUP";
     field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE";
     field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE";
+    field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
     field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
     field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
     field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
@@ -7214,6 +7215,14 @@
     method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
   }
 
+  public abstract class CellBroadcastService extends android.app.Service {
+    ctor public CellBroadcastService();
+    method @CallSuper public android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onCdmaCellBroadcastSms(int, byte[]);
+    method public abstract void onGsmCellBroadcastSms(int, byte[]);
+    field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
+  }
+
   public final class DataFailCause {
     field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab
     field public static final int ACCESS_BLOCK = 2087; // 0x827
diff --git a/api/test-current.txt b/api/test-current.txt
index 23d7eca..f1b00b2 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5,6 +5,7 @@
     field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
     field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
     field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
+    field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
     field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
     field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
     field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b4c757..c101697 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -772,6 +772,18 @@
         android:permissionFlags="hardRestricted"
         android:protectionLevel="dangerous" />
 
+    <!-- @SystemApi @TestApi Allows an application to forward cell broadcast messages to the cell
+         broadcast module. This is required in order to bind to the cell broadcast service, and
+         ensures that only the system can forward messages to it.
+
+         <p>Protection level: signature|privileged
+
+         @hide -->
+    <permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE"
+        android:label="@string/permlab_bindCellBroadcastService"
+        android:description="@string/permdesc_bindCellBroadcastService"
+        android:protectionLevel="signature" />
+
     <!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
          messages and to register a content observer to get notifications when
          a cell broadcast has been received and added to the database. For
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8336f54..0098abb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -441,6 +441,10 @@
         -->
     </string-array>
 
+    <!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] -->
+    <string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastreceiver
+    </string>
+
     <!-- If the mobile hotspot feature requires provisioning, a package name and class name
         can be provided to launch a supported application that provisions the devices.
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 152b131..e132c36 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -884,6 +884,16 @@
       messages. This means the app could monitor or delete messages sent to your
       device without showing them to you.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this.[CHAR LIMIT=NONE] -->
+    <string name="permlab_bindCellBroadcastService">Forward cell broadcast messages</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+    <string name="permdesc_bindCellBroadcastService">Allows the app to bind to the
+        cell broadcast module in order to forward cell broadcast messages
+        as they are received. Cell broadcast alerts are delivered in some
+        locations to warn you of emergency situations. Malicious apps may
+        interfere with the performance or operation of your device when an
+        emergency cell broadcast is received.</string>
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readCellBroadcasts">read cell broadcast messages</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0bd5e43..94b9127 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -744,6 +744,7 @@
   <java-symbol type="string" name="config_ethernet_iface_regex" />
   <java-symbol type="array" name="config_ethernet_interfaces" />
   <java-symbol type="array" name="config_wakeonlan_supported_interfaces" />
+  <java-symbol type="string" name="cellbroadcast_default_package" />
   <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
   <java-symbol type="string" name="config_mms_user_agent" />
   <java-symbol type="string" name="config_mms_user_agent_profile_url" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index ff4e100..3d47f42 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -125,6 +125,7 @@
         <permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
         <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
         <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.BIND_CELL_BROADCAST_SERVICE"/>
         <permission name="android.permission.BIND_IMS_SERVICE"/>
         <permission name="android.permission.BIND_TELEPHONY_DATA_SERVICE"/>
         <permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
new file mode 100644
index 0000000..d5e447e
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 The Android Open Source 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 android.telephony;
+
+import android.annotation.CallSuper;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * A service which exposes the cell broadcast handling module to the system.
+ * <p>
+ * To extend this class, you must declare the service in your manifest file to require the
+ * {@link android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE} permission and include an intent
+ * filter with the {@link #CELL_BROADCAST_SERVICE_INTERFACE}.
+ * Implementations of this service should run in the phone process and with its UID.
+ * <p>
+ * For example:
+ * <pre>{@code
+ * <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ *       android:sharedUserId="android.uid.phone">
+ *   <service android:name=".MyCellBroadcastService"
+ *         android:label="@string/service_name"
+ *         android:process="com.android.phone"
+ *         android:exported="true"
+ *         android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE">
+ *     <intent-filter>
+ *           <action android:name="android.telephony.CellBroadcastService" />
+ *     </intent-filter>
+ *   </service>
+ * </manifest>
+ * }</pre>
+ * @hide
+ */
+@SystemApi
+public abstract class CellBroadcastService extends Service {
+
+    public static final String CELL_BROADCAST_SERVICE_INTERFACE =
+            "android.telephony.CellBroadcastService";
+
+    private final ICellBroadcastService.Stub mStubWrapper;
+
+    public CellBroadcastService() {
+        mStubWrapper = new ICellBroadcastServiceWrapper();
+    }
+
+    /**
+     * Handle a GSM cell broadcast SMS message forwarded from the system.
+     * @param slotIndex the index of the slot which received the message
+     * @param message the SMS PDU
+     */
+    public abstract void onGsmCellBroadcastSms(int slotIndex, byte[] message);
+
+    /**
+     * Handle a CDMA cell broadcast SMS message forwarded from the system.
+     * @param slotIndex the index of the slot which received the message
+     * @param message the SMS PDU
+     */
+    public abstract void onCdmaCellBroadcastSms(int slotIndex, byte[] message);
+
+    /**
+     * If overriding this method, call through to the super method for any unknown actions.
+     * {@inheritDoc}
+     */
+    @Override
+    @CallSuper
+    public IBinder onBind(Intent intent) {
+        return mStubWrapper;
+    }
+
+    /**
+     * A wrapper around ICellBroadcastService that forwards calls to implementations of
+     * {@link CellBroadcastService}.
+     * @hide
+     */
+    public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub {
+        /**
+         * Handle a GSM cell broadcast SMS.
+         * @param slotIndex the index of the slot which received the broadcast
+         * @param message the SMS message PDU
+         */
+        @Override
+        public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) {
+            CellBroadcastService.this.onGsmCellBroadcastSms(slotIndex, message);
+        }
+
+        /**
+         * Handle a CDMA cell broadcast SMS.
+         * @param slotIndex the index of the slot which received the broadcast
+         * @param message the SMS message PDU
+         */
+        @Override
+        public void handleCdmaCellBroadcastSms(int slotIndex, byte[] message) {
+            CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, message);
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ICellBroadcastService.aidl b/telephony/java/android/telephony/ICellBroadcastService.aidl
new file mode 100644
index 0000000..eff64a2
--- /dev/null
+++ b/telephony/java/android/telephony/ICellBroadcastService.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019, The Android Open Source 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 android.telephony;
+
+/**
+ * Service bound to by the system to allow custom handling of cell broadcast messages.
+ * <p>
+ * @see android.telephony.CellBroadcastService
+ * @hide
+ */
+interface ICellBroadcastService {
+
+    /** @see android.telephony.CellBroadcastService#onGsmCellBroadcastSms */
+    oneway void handleGsmCellBroadcastSms(int slotId, in byte[] message);
+
+    /** @see android.telephony.CellBroadcastService#onCdmaCellBroadcastSms */
+    oneway void handleCdmaCellBroadcastSms(int slotId, in byte[] message);
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 6eea118..c65c45f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -461,7 +461,11 @@
         }
     }
 
-    static final class GeoFencingTriggerMessage {
+    /**
+     * Part of a GSM SMS cell broadcast message which may trigger geo-fencing logic.
+     * @hide
+     */
+    public static final class GeoFencingTriggerMessage {
         /**
          * Indicate the list of active alerts share their warning area coordinates which means the
          * broadcast area is the union of the broadcast areas of the active alerts in this list.
@@ -476,6 +480,11 @@
             this.cbIdentifiers = cbIdentifiers;
         }
 
+        /**
+         * Whether the trigger message indicates that the broadcast areas are shared between all
+         * active alerts.
+         * @return true if broadcast areas are to be shared
+         */
         boolean shouldShareBroadcastArea() {
             return type == TYPE_ACTIVE_ALERT_SHARE_WAC;
         }
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
index acdc838..465840f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
@@ -72,22 +72,22 @@
     /**
      * Length of SMS-CB header
      */
-    static final int PDU_HEADER_LENGTH = 6;
+    public static final int PDU_HEADER_LENGTH = 6;
 
     /**
      * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
      */
-    static final int FORMAT_GSM = 1;
+    public static final int FORMAT_GSM = 1;
 
     /**
      * UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
      */
-    static final int FORMAT_UMTS = 2;
+    public static final int FORMAT_UMTS = 2;
 
     /**
-     * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
+     * ETWS pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
      */
-    static final int FORMAT_ETWS_PRIMARY = 3;
+    public static final int FORMAT_ETWS_PRIMARY = 3;
 
     /**
      * Message type value as defined in 3gpp TS 25.324, section 11.1.
@@ -237,11 +237,11 @@
         return mMessageIdentifier;
     }
 
-    int getDataCodingScheme() {
+    public int getDataCodingScheme() {
         return mDataCodingScheme;
     }
 
-    DataCodingScheme getDataCodingSchemeStructedData() {
+    public DataCodingScheme getDataCodingSchemeStructedData() {
         return mDataCodingSchemeStructedData;
     }
 
@@ -253,11 +253,11 @@
         return mNrOfPages;
     }
 
-    SmsCbEtwsInfo getEtwsInfo() {
+    public SmsCbEtwsInfo getEtwsInfo() {
         return mEtwsInfo;
     }
 
-    SmsCbCmasInfo getCmasInfo() {
+    public SmsCbCmasInfo getCmasInfo() {
         return mCmasInfo;
     }
 
@@ -265,7 +265,7 @@
      * Return whether this broadcast is an emergency (PWS) message type.
      * @return true if this message is emergency type; false otherwise
      */
-    boolean isEmergencyMessage() {
+    public boolean isEmergencyMessage() {
         return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
                 && mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
     }
@@ -283,7 +283,7 @@
      * Return whether this broadcast is an ETWS primary notification.
      * @return true if this message is an ETWS primary notification; false otherwise
      */
-    boolean isEtwsPrimaryNotification() {
+    public boolean isEtwsPrimaryNotification() {
         return mFormat == FORMAT_ETWS_PRIMARY;
     }
 
@@ -291,7 +291,7 @@
      * Return whether this broadcast is in UMTS format.
      * @return true if this message is in UMTS format; false otherwise
      */
-    boolean isUmtsFormat() {
+    public boolean isUmtsFormat() {
         return mFormat == FORMAT_UMTS;
     }
 
@@ -583,4 +583,4 @@
             this.hasLanguageIndicator = hasLanguageIndicator;
         }
     }
-}
\ No newline at end of file
+}