1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony; 18 19 import android.annotation.CallSuper; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.annotation.WorkerThread; 24 import android.app.Service; 25 import android.content.Intent; 26 import android.os.Bundle; 27 import android.os.IBinder; 28 import android.os.RemoteCallback; 29 import android.telephony.cdma.CdmaSmsCbProgramData; 30 31 import com.android.internal.util.FastPrintWriter; 32 33 import java.io.FileDescriptor; 34 import java.io.FileOutputStream; 35 import java.io.PrintWriter; 36 import java.util.List; 37 import java.util.function.Consumer; 38 39 /** 40 * A service which exposes the cell broadcast handling module to the system. 41 * <p> 42 * To extend this class, you must declare the service in your manifest file to require the 43 * {@link android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE} permission and include an intent 44 * filter with the {@link #CELL_BROADCAST_SERVICE_INTERFACE}. 45 * Implementations of this service should run in the phone process and with its UID. 46 * <p> 47 * For example: 48 * <pre>{@code 49 * <manifest xmlns:android="http://schemas.android.com/apk/res/android" 50 * android:sharedUserId="android.uid.phone"> 51 * <service android:name=".MyCellBroadcastService" 52 * android:label="@string/service_name" 53 * android:process="com.android.phone" 54 * android:exported="true" 55 * android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE"> 56 * <intent-filter> 57 * <action android:name="android.telephony.CellBroadcastService" /> 58 * </intent-filter> 59 * </service> 60 * </manifest> 61 * }</pre> 62 * 63 * @hide 64 */ 65 @SystemApi 66 public abstract class CellBroadcastService extends Service { 67 68 public static final String CELL_BROADCAST_SERVICE_INTERFACE = 69 "android.telephony.CellBroadcastService"; 70 71 private final ICellBroadcastService.Stub mStubWrapper; 72 CellBroadcastService()73 public CellBroadcastService() { 74 mStubWrapper = new ICellBroadcastServiceWrapper(); 75 } 76 77 /** 78 * Handle a GSM cell broadcast SMS message forwarded from the system. 79 * 80 * @param slotIndex the index of the slot which received the message 81 * @param message the SMS PDU 82 */ onGsmCellBroadcastSms(int slotIndex, @NonNull byte[] message)83 public abstract void onGsmCellBroadcastSms(int slotIndex, @NonNull byte[] message); 84 85 /** 86 * Handle a CDMA cell broadcast SMS message forwarded from the system. 87 * 88 * @param slotIndex the index of the slot which received the message 89 * @param bearerData the CDMA SMS bearer data 90 * @param serviceCategory the CDMA SCPT service category 91 */ onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData, @CdmaSmsCbProgramData.Category int serviceCategory)92 public abstract void onCdmaCellBroadcastSms(int slotIndex, @NonNull byte[] bearerData, 93 @CdmaSmsCbProgramData.Category int serviceCategory); 94 95 /** 96 * Handle a CDMA cell broadcast SMS message forwarded from the system. 97 * 98 * @param slotIndex the index of the slot which received the message 99 * @param smsCbProgramData the SMS CB program data of the message 100 * @param originatingAddress the originating address of the message, as a non-separated dial 101 * string 102 * @param callback a callback to run after each cell broadcast receiver has handled 103 * the SCP message. The bundle will contain a non-separated 104 * dial string as and an ArrayList of {@link CdmaSmsCbProgramResults}. 105 */ onCdmaScpMessage(int slotIndex, @NonNull List<CdmaSmsCbProgramData> smsCbProgramData, @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback)106 public abstract void onCdmaScpMessage(int slotIndex, 107 @NonNull List<CdmaSmsCbProgramData> smsCbProgramData, 108 @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback); 109 110 /** 111 * Get broadcasted area information. 112 * 113 * @param slotIndex the index of the slot which received the area information. 114 * 115 * @return The area information string sent from the network. This is usually the human readable 116 * string shown in Setting app's SIM status page. 117 */ 118 @WorkerThread getCellBroadcastAreaInfo(int slotIndex)119 public abstract @NonNull CharSequence getCellBroadcastAreaInfo(int slotIndex); 120 121 /** 122 * If overriding this method, call through to the super method for any unknown actions. 123 * {@inheritDoc} 124 */ 125 @Override 126 @CallSuper onBind(@ullable Intent intent)127 public IBinder onBind(@Nullable Intent intent) { 128 return mStubWrapper; 129 } 130 131 /** 132 * A wrapper around ICellBroadcastService that forwards calls to implementations of 133 * {@link CellBroadcastService}. 134 * 135 * @hide 136 */ 137 public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub { 138 /** 139 * Handle a GSM cell broadcast SMS. 140 * 141 * @param slotIndex the index of the slot which received the broadcast 142 * @param message the SMS message PDU 143 */ 144 @Override handleGsmCellBroadcastSms(int slotIndex, byte[] message)145 public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) { 146 CellBroadcastService.this.onGsmCellBroadcastSms(slotIndex, message); 147 } 148 149 /** 150 * Handle a CDMA cell broadcast SMS. 151 * 152 * @param slotIndex the index of the slot which received the broadcast 153 * @param bearerData the CDMA SMS bearer data 154 * @param serviceCategory the CDMA SCPT service category 155 */ 156 @Override handleCdmaCellBroadcastSms(int slotIndex, byte[] bearerData, int serviceCategory)157 public void handleCdmaCellBroadcastSms(int slotIndex, byte[] bearerData, 158 int serviceCategory) { 159 CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, bearerData, 160 serviceCategory); 161 } 162 163 /** 164 * Handle a CDMA Service Category Program message. 165 * 166 * @param slotIndex the index of the slot which received the message 167 * @param smsCbProgramData the SMS CB program data of the message 168 * @param originatingAddress the originating address of the message 169 * @param callback a callback to run after each cell broadcast receiver has 170 * handled the SCP message 171 */ 172 @Override handleCdmaScpMessage(int slotIndex, List<CdmaSmsCbProgramData> smsCbProgramData, String originatingAddress, RemoteCallback callback)173 public void handleCdmaScpMessage(int slotIndex, 174 List<CdmaSmsCbProgramData> smsCbProgramData, String originatingAddress, 175 RemoteCallback callback) { 176 Consumer<Bundle> consumer = bundle -> { 177 callback.sendResult(bundle); 178 }; 179 CellBroadcastService.this.onCdmaScpMessage(slotIndex, smsCbProgramData, 180 originatingAddress, consumer); 181 } 182 183 /** 184 * Get broadcasted area information 185 * 186 * @param slotIndex the index of the slot which received the message 187 * 188 * @return The area information 189 */ 190 @Override getCellBroadcastAreaInfo(int slotIndex)191 public @NonNull CharSequence getCellBroadcastAreaInfo(int slotIndex) { 192 return CellBroadcastService.this.getCellBroadcastAreaInfo(slotIndex); 193 } 194 195 @Override dump(FileDescriptor fd, PrintWriter fout, String[] args)196 protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 197 CellBroadcastService.this.dump(fd, fout, args); 198 } 199 200 @Override dump(FileDescriptor fd, String[] args)201 public void dump(FileDescriptor fd, String[] args) { 202 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd)); 203 CellBroadcastService.this.dump(fd, pw, args); 204 } 205 } 206 } 207