Merge "Add VisualVoicemailService"

This commit is contained in:
Chen Xu
2017-04-25 21:54:51 +00:00
committed by Gerrit Code Review
10 changed files with 654 additions and 62 deletions

View File

@@ -36,6 +36,7 @@ package android {
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -38309,6 +38310,54 @@ package android.telephony {
method public void onReceiveUssdResponseFailed(java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
ctor public VisualVoicemailService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
}
public static class VisualVoicemailService.VisualVoicemailTask {
method public final void finish();
}
public final class VisualVoicemailSms implements android.os.Parcelable {
method public int describeContents();
method public android.os.Bundle getFields();
method public java.lang.String getMessageBody();
method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
method public java.lang.String getPrefix();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
}
public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
field public final java.lang.String clientPrefix;
field public final int destinationPort;
field public final java.util.List<java.lang.String> originatingNumbers;
}
public static class VisualVoicemailSmsFilterSettings.Builder {
ctor public VisualVoicemailSmsFilterSettings.Builder();
method public android.telephony.VisualVoicemailSmsFilterSettings build();
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
}
}
package android.telephony.cdma {

View File

@@ -55,6 +55,7 @@ package android {
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -41555,6 +41556,54 @@ package android.telephony {
method public void onReceiveUssdResponseFailed(java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
ctor public VisualVoicemailService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
}
public static class VisualVoicemailService.VisualVoicemailTask {
method public final void finish();
}
public final class VisualVoicemailSms implements android.os.Parcelable {
method public int describeContents();
method public android.os.Bundle getFields();
method public java.lang.String getMessageBody();
method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
method public java.lang.String getPrefix();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
}
public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
field public final java.lang.String clientPrefix;
field public final int destinationPort;
field public final java.util.List<java.lang.String> originatingNumbers;
}
public static class VisualVoicemailSmsFilterSettings.Builder {
ctor public VisualVoicemailSmsFilterSettings.Builder();
method public android.telephony.VisualVoicemailSmsFilterSettings build();
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
}
}
package android.telephony.cdma {

View File

@@ -36,6 +36,7 @@ package android {
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -38408,6 +38409,54 @@ package android.telephony {
method public void onReceiveUssdResponseFailed(java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
ctor public VisualVoicemailService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
}
public static class VisualVoicemailService.VisualVoicemailTask {
method public final void finish();
}
public final class VisualVoicemailSms implements android.os.Parcelable {
method public int describeContents();
method public android.os.Bundle getFields();
method public java.lang.String getMessageBody();
method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
method public java.lang.String getPrefix();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
}
public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
field public static final java.lang.String DEFAULT_CLIENT_PREFIX = "//VVM";
field public static final int DEFAULT_DESTINATION_PORT = -1; // 0xffffffff
field public static final java.util.List<java.lang.String> DEFAULT_ORIGINATING_NUMBERS;
field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
field public final java.lang.String clientPrefix;
field public final int destinationPort;
field public final java.util.List<java.lang.String> originatingNumbers;
}
public static class VisualVoicemailSmsFilterSettings.Builder {
ctor public VisualVoicemailSmsFilterSettings.Builder();
method public android.telephony.VisualVoicemailSmsFilterSettings build();
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
}
}
package android.telephony.cdma {

View File

@@ -107,15 +107,7 @@ public class VoicemailContract {
/**
* Broadcast intent to inform a new visual voicemail SMS has been received. This intent will
* only be delivered to the voicemail client. The intent will have the following extra values:
*
* <ul>
* <li><em>{@link #EXTRA_VOICEMAIL_SMS_TYPE}</em> - (String) The event type of the SMS. Common
* values are "SYNC" or "STATUS"</li>
* <li><em>{@link #EXTRA_VOICEMAIL_SMS_DATA}</em> - (Bundle) The fields sent by the SMS</li>
* <li><em>{@link #EXTRA_VOICEMAIL_SMS_SUBID}</em> - (Integer) The subscription ID of the
* phone account that received the SMS</li>
* </ul>
* only be delivered to the telephony service. {@link #EXTRA_VOICEMAIL_SMS} will be included.
*/
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -123,42 +115,11 @@ public class VoicemailContract {
"android.intent.action.VOICEMAIL_SMS_RECEIVED";
/**
* Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
* indicate the event type of the SMS. Common values are "SYNC" or "STATUS". The extra will not
* exist if the framework cannot parse the SMS as voicemail but the carrier pattern indicates
* it is.
*/
/** @hide */
public static final String EXTRA_VOICEMAIL_SMS_PREFIX =
"com.android.voicemail.extra.VOICEMAIL_SMS_PREFIX";
/**
* Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
* indicate the fields sent by the SMS. The extra will not exist if the framework cannot
* parse the SMS as voicemail but the carrier pattern indicates it is.
*/
/** @hide */
public static final String EXTRA_VOICEMAIL_SMS_FIELDS =
"com.android.voicemail.extra.VOICEMAIL_SMS_FIELDS";
/**
* Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate the
* message body of the SMS. This extra is included if the framework cannot
* parse the SMS as voicemail but the carrier pattern indicates it is.
*/
/**
* Extra in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} indicating the content of the SMS.
*
* @hide
*/
public static final String EXTRA_VOICEMAIL_SMS_MESSAGE_BODY =
"com.android.voicemail.extra.VOICEMAIL_SMS_MESSAGE_BODY";
/**
* Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate he
* subscription ID of the phone account that received the SMS.
*/
/** @hide */
public static final String EXTRA_VOICEMAIL_SMS_SUBID =
"com.android.voicemail.extra.VOICEMAIL_SMS_SUBID";
public static final String EXTRA_VOICEMAIL_SMS = "android.provider.extra.VOICEMAIL_SMS";
/**
* Extra included in {@link Intent#ACTION_PROVIDER_CHANGED} broadcast intents to indicate if the

View File

@@ -1560,6 +1560,14 @@
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="signature|privileged" />
<!-- Must be required by a link {@link android.telephony.VisualVoicemailService} to ensure that
only the system can bind to it.
<p>Protection level: signature|privileged
-->
<permission
android:name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"
android:protectionLevel="signature|privileged"/>
<!-- Must be required by a {@link android.telecom.CallScreeningService},
to ensure that only the system can bind to it.
<p>Protection level: signature|privileged

View File

@@ -25,12 +25,14 @@ import android.annotation.SystemApi;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.ActivityThread;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.os.Bundle;
@@ -65,6 +67,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -2785,18 +2788,17 @@ public class TelephonyManager {
/**
* @returns the settings of the visual voicemail SMS filter for a phone account set by the
* package, or {@code null} if the filter is disabled.
* current active visual voicemail client, or {@code null} if the filter is disabled.
*
* <p>Requires the calling app to have READ_PRIVILEGED_PHONE_STATE permission.
*/
/** @hide */
@Nullable
public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(String packageName,
int subId) {
public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
return telephony.getSystemVisualVoicemailSmsFilterSettings(packageName, subId);
return telephony.getActiveVisualVoicemailSmsFilterSettings(subId);
}
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
@@ -2805,6 +2807,35 @@ public class TelephonyManager {
return null;
}
/**
* Send a visual voicemail SMS. The IPC caller must be the current default dialer.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#SEND_SMS SEND_SMS}
*
* @param phoneAccountHandle The account to send the SMS with.
* @param number The destination number.
* @param port The destination port for data SMS, or 0 for text SMS.
* @param text The message content. For data sms, it will be encoded as a UTF-8 byte stream.
* @param sentIntent The sent intent passed to the {@link SmsManager}
*
* @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
* @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
*
* @hide
*/
public void sendVisualVoicemailSmsForSubscriber(int subId, String number, int port,
String text, PendingIntent sentIntent) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
telephony.sendVisualVoicemailSmsForSubscriber(
mContext.getOpPackageName(), subId, number, port, text, sentIntent);
}
} catch (RemoteException ex) {
}
}
/**
* Initial SIM activation state, unknown. Not set by any carrier apps.
* @hide

View File

@@ -0,0 +1,281 @@
/*
* Copyright (C) 2016 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.MainThread;
import android.annotation.SdkConstant;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.util.Log;
/**
* This service is implemented by dialer apps that wishes to handle OMTP or similar visual
* voicemails. Telephony binds to this service when the cell service is first connected, a visual
* voicemail SMS has been received, or when a SIM has been removed. Telephony will only bind to the
* default dialer for such events (See {@link TelecomManager#getDefaultDialerPackage()}). The
* {@link android.service.carrier.CarrierMessagingService} precedes the VisualVoicemailService in
* the SMS filtering chain and may intercept the visual voicemail SMS before it reaches this
* service.
* <p>
* Below is an example manifest registration for a {@code VisualVoicemailService}.
* <pre>
* {@code
* <service android:name="your.package.YourVisualVoicemailServiceImplementation"
* android:permission="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE">
* <intent-filter>
* <action android:name="android.telephony.VisualVoicemailService"/>
* </intent-filter>
* </service>
* }
* </pre>
*/
public abstract class VisualVoicemailService extends Service {
private static final String TAG = "VvmService";
/**
* The {@link Intent} that must be declared as handled by the service.
*/
@SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
/**
* @hide
*/
public static final int MSG_ON_CELL_SERVICE_CONNECTED = 1;
/**
* @hide
*/
public static final int MSG_ON_SMS_RECEIVED = 2;
/**
* @hide
*/
public static final int MSG_ON_SIM_REMOVED = 3;
/**
* @hide
*/
public static final int MSG_TASK_ENDED = 4;
/**
* @hide
*/
public static final int MSG_TASK_STOPPED = 5;
/**
* @hide
*/
public static final String DATA_PHONE_ACCOUNT_HANDLE = "data_phone_account_handle";
/**
* @hide
*/
public static final String DATA_SMS = "data_sms";
/**
* Represents a visual voicemail event which needs to be handled. While the task is being
* processed telephony will hold a wakelock for the VisualVoicemailService. The service can
* unblock the main thread and pass the task to a worker thread. Once the task is finished,
* {@link VisualVoicemailTask#finish()} should be called to signal telephony to release the
* resources. Telephony will call {@link VisualVoicemailService#onStopped(VisualVoicemailTask)}
* when the task is going to be terminated before completion.
*
* @see #onCellServiceConnected(VisualVoicemailTask, PhoneAccountHandle)
* @see #onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)
* @see #onSimRemoved(VisualVoicemailTask, PhoneAccountHandle)
* @see #onStopped(VisualVoicemailTask)
*/
public static class VisualVoicemailTask {
private final int mTaskId;
private final Messenger mReplyTo;
private VisualVoicemailTask(Messenger replyTo, int taskId) {
mTaskId = taskId;
mReplyTo = replyTo;
}
/**
* Call to signal telephony the task has completed. Must be called for every task.
*/
public final void finish() {
Message message = Message.obtain();
try {
message.what = MSG_TASK_ENDED;
message.arg1 = mTaskId;
mReplyTo.send(message);
} catch (RemoteException e) {
Log.e(TAG,
"Cannot send MSG_TASK_ENDED, remote handler no longer exist");
}
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof VisualVoicemailTask)) {
return false;
}
return mTaskId == ((VisualVoicemailTask) obj).mTaskId;
}
@Override
public int hashCode() {
return mTaskId;
}
}
/**
* Handles messages sent by telephony.
*/
private final Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(final Message msg) {
final PhoneAccountHandle handle = msg.getData()
.getParcelable(DATA_PHONE_ACCOUNT_HANDLE);
VisualVoicemailTask task = new VisualVoicemailTask(msg.replyTo, msg.arg1);
switch (msg.what) {
case MSG_ON_CELL_SERVICE_CONNECTED:
onCellServiceConnected(task, handle);
break;
case MSG_ON_SMS_RECEIVED:
VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS);
onSmsReceived(task, sms);
break;
case MSG_ON_SIM_REMOVED:
onSimRemoved(task, handle);
break;
case MSG_TASK_STOPPED:
onStopped(task);
break;
default:
super.handleMessage(msg);
break;
}
}
});
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
/**
* Called when the cellular service is connected on a {@link PhoneAccountHandle} for the first
* time, or when the carrier config has changed. It will not be called when the signal is lost
* then restored.
*
* @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
* called when the task is completed.
* @param phoneAccountHandle The {@link PhoneAccountHandle} triggering this event.
*/
@MainThread
public abstract void onCellServiceConnected(VisualVoicemailTask task,
PhoneAccountHandle phoneAccountHandle);
/**
* Called when a SMS matching the {@link VisualVoicemailSmsFilterSettings} set by
* {@link #setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)}
* is received.
*
* @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
* called when the task is completed.
* @param sms The content of the received SMS.
*/
@MainThread
public abstract void onSmsReceived(VisualVoicemailTask task,
VisualVoicemailSms sms);
/**
* Called when a SIM is removed.
*
* @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
* called when the task is completed.
* @param phoneAccountHandle The {@link PhoneAccountHandle} triggering this event.
*/
@MainThread
public abstract void onSimRemoved(VisualVoicemailTask task,
PhoneAccountHandle phoneAccountHandle);
/**
* Called before the system is about to terminate a task. The service should persist any
* necessary data and call finish on the task immediately.
*/
@MainThread
public abstract void onStopped(VisualVoicemailTask task);
/**
* Set the visual voicemail SMS filter settings for the VisualVoicemailService.
* {@link #onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be called when
* a SMS matching the settings is received. The caller should have
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} and implements a
* VisualVoicemailService.
* <p>
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*
* @param phoneAccountHandle The account to apply the settings to.
* @param settings The settings for the filter, or {@code null} to disable the filter.
*/
public final static void setSmsFilterSettings(Context context,
PhoneAccountHandle phoneAccountHandle,
VisualVoicemailSmsFilterSettings settings) {
TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
int subId = getSubId(context, phoneAccountHandle);
if (settings == null) {
telephonyManager.disableVisualVoicemailSmsFilter(subId);
} else {
telephonyManager.enableVisualVoicemailSmsFilter(subId, settings);
}
}
/**
* Send a visual voicemail SMS. The caller must be the current default dialer.
* <p>
* <p>Requires Permission:
* {@link android.Manifest.permission#SEND_SMS SEND_SMS}
*
* @param phoneAccountHandle The account to send the SMS with.
* @param number The destination number.
* @param port The destination port for data SMS, or 0 for text SMS.
* @param text The message content. For data sms, it will be encoded as a UTF-8 byte stream.
* @param sentIntent The sent intent passed to the {@link SmsManager}
* @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
* @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
*/
public final static void sendVisualVoicemailSms(Context context,
PhoneAccountHandle phoneAccountHandle, String number,
short port, String text, PendingIntent sentIntent) {
TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
telephonyManager.sendVisualVoicemailSmsForSubscriber(getSubId(context, phoneAccountHandle),
number, port, text, sentIntent);
}
private static int getSubId(Context context, PhoneAccountHandle phoneAccountHandle) {
TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
return telephonyManager
.getSubIdForPhoneAccount(telecomManager.getPhoneAccount(phoneAccountHandle));
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2016 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.Nullable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telecom.PhoneAccountHandle;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
/**
* Represents the content of a visual voicemail SMS. If a incoming SMS matches the {@link
* VisualVoicemailSmsFilterSettings} set by the default dialer, {@link
* VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be called.
*/
public final class VisualVoicemailSms implements Parcelable {
private final PhoneAccountHandle mPhoneAccountHandle;
@Nullable
private final String mPrefix;
@Nullable
private final Bundle mFields;
private final String mMessageBody;
VisualVoicemailSms(Builder builder) {
mPhoneAccountHandle = builder.mPhoneAccountHandle;
mPrefix = builder.mPrefix;
mFields = builder.mFields;
mMessageBody = builder.mMessageBody;
}
/**
* The {@link PhoneAccountHandle} that received the SMS.
*/
public PhoneAccountHandle getPhoneAccountHandle() {
return mPhoneAccountHandle;
}
/**
* The event type of the SMS or {@code null} if the framework cannot parse the SMS as voicemail
* but the carrier pattern indicates it is. Common values are "SYNC" or "STATUS".
*/
public String getPrefix() {
return mPrefix;
}
/**
* The key-value pairs sent by the SMS, or {@code null} if the framework cannot parse the SMS as
* voicemail but the carrier pattern indicates it is.
*/
public Bundle getFields() {
return mFields;
}
/**
* Raw message body of the received SMS.
*/
public String getMessageBody() {
return mMessageBody;
}
/**
* Builder for the {@link VisualVoicemailSms}. Internal use only.
*
* @hide
*/
public static class Builder {
private PhoneAccountHandle mPhoneAccountHandle;
private String mPrefix;
private Bundle mFields;
private String mMessageBody;
public VisualVoicemailSms build() {
return new VisualVoicemailSms(this);
}
public Builder setPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
this.mPhoneAccountHandle = phoneAccountHandle;
return this;
}
public Builder setPrefix(String prefix) {
this.mPrefix = prefix;
return this;
}
public Builder setFields(Bundle fields) {
this.mFields = fields;
return this;
}
public Builder setMessageBody(String messageBody) {
this.mMessageBody = messageBody;
return this;
}
}
public static final Creator<VisualVoicemailSms> CREATOR =
new Creator<VisualVoicemailSms>() {
@Override
public VisualVoicemailSms createFromParcel(Parcel in) {
return new Builder()
.setPhoneAccountHandle((PhoneAccountHandle) in.readParcelable(null))
.setPrefix(in.readString())
.setFields(in.readBundle())
.setMessageBody(in.readString())
.build();
}
@Override
public VisualVoicemailSms[] newArray(int size) {
return new VisualVoicemailSms[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(getPhoneAccountHandle(), flags);
dest.writeString(getPrefix());
dest.writeBundle(getFields());
dest.writeString(getMessageBody());
}
}

View File

@@ -15,9 +15,13 @@
*/
package android.telephony;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telecom.PhoneAccountHandle;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
import java.util.Collections;
import java.util.List;
@@ -28,31 +32,26 @@ import java.util.List;
* <p>[clientPrefix]:[prefix]:([key]=[value];)*
*
* <p>will be regarded as a visual voicemail SMS, and removed before reaching the SMS provider. The
* intent {@link android.provider.VoicemailContract#ACTION_VOICEMAIL_SMS_RECEIVED} will then be sent
* to the default dialer with the information extracted from the SMS.
* {@link VisualVoicemailService} in the current default dialer will be bound and
* {@link VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)}
* will called with the information extracted from the SMS.
*
* <p>Use {@link android.telephony.VisualVoicemailSmsFilterSettings.Builder} to construct this
* class.
*
* @see android.telephony.TelephonyManager#enableVisualVoicemailSmsFilter
*
* @hide
* @see VisualVoicemailService#setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)
*/
public class VisualVoicemailSmsFilterSettings implements Parcelable {
public final class VisualVoicemailSmsFilterSettings implements Parcelable {
/**
* The visual voicemail SMS message does not have to be a data SMS, and can be directed to any
* port.
*
* @hide
*/
public static final int DESTINATION_PORT_ANY = -1;
/**
* The visual voicemail SMS message can be directed to any port, but must be a data SMS.
*
* @hide
*/
public static final int DESTINATION_PORT_DATA_SMS = -2;
@@ -62,8 +61,6 @@ public class VisualVoicemailSmsFilterSettings implements Parcelable {
/**
* Builder class for {@link VisualVoicemailSmsFilterSettings} objects.
*
* @hide
*/
public static class Builder {
@@ -171,4 +168,13 @@ public class VisualVoicemailSmsFilterSettings implements Parcelable {
dest.writeInt(destinationPort);
}
@Override
public String toString(){
return "[VisualVoicemailSmsFilterSettings "
+ "clientPrefix=" + clientPrefix
+ ", originatingNumbers=" + originatingNumbers
+ ", destinationPort=" + destinationPort
+ "]";
}
}

View File

@@ -16,6 +16,7 @@
package com.android.internal.telephony;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
@@ -507,9 +508,18 @@ interface ITelephony {
VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(String callingPackage,
int subId);
// Get settings set by the package, requires READ_PRIVILEGED_PHONE_STATE permission
VisualVoicemailSmsFilterSettings getSystemVisualVoicemailSmsFilterSettings(String packageName,
int subId);
/**
* Get settings set by the current default dialer, Internal use only.
* Requires READ_PRIVILEGED_PHONE_STATE permission.
*/
VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId);
/**
* Send a visual voicemail SMS. Internal use only.
* Requires caller to be the default dialer and have SEND_SMS permission
*/
oneway void sendVisualVoicemailSmsForSubscriber(in String callingPackage, in int subId,
in String number, in int port, in String text, in PendingIntent sentIntent);
/**
* Returns the network type for data transmission