Merge "Revert isResolvingImsBinding ITelephony interface"
diff --git a/Android.bp b/Android.bp
index b2b3dff..e2b432c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -506,11 +506,14 @@
"telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
"telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
"telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
+ "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl",
"telephony/java/android/telephony/mbms/IDownloadStatusListener.aidl",
"telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl",
"telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl",
+ "telephony/java/android/telephony/mbms/IGroupCallCallback.aidl",
"telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl",
"telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl",
+ "telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl",
"telephony/java/android/telephony/INetworkService.aidl",
"telephony/java/android/telephony/INetworkServiceCallback.aidl",
"telephony/java/com/android/ims/internal/IImsCallSession.aidl",
@@ -795,7 +798,7 @@
java_library {
name: "ext",
installable: true,
- no_framework_libs: true,
+ sdk_version: "core_current",
static_libs: [
"libphonenumber-platform",
"nist-sip",
@@ -1267,6 +1270,9 @@
}
droiddoc {
+ // Please sync with android-api-council@ before making any changes for the name property below.
+ // Since there's cron jobs that fetch offline-sdk-referenceonly-docs-docs.zip periodically.
+ // See b/116221385 for reference.
name: "offline-sdk-referenceonly-docs",
defaults: ["framework-docs-default"],
srcs: [
@@ -1283,6 +1289,9 @@
}
droiddoc {
+ // Please sync with android-api-council@ before making any changes for the name property below.
+ // Since there's cron jobs that fetch offline-system-sdk-referenceonly-docs-docs.zip periodically.
+ // See b/116221385 for reference.
name: "offline-system-sdk-referenceonly-docs",
defaults: ["framework-docs-default"],
srcs: [
diff --git a/api/current.txt b/api/current.txt
index a254610..93fcf3b 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -41035,6 +41035,7 @@
field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
+ field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
field public static final int PROPERTY_RTT = 1024; // 0x400
field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
field public static final int PROPERTY_WIFI = 8; // 0x8
@@ -41988,6 +41989,7 @@
field public static final deprecated java.lang.String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool";
field public static final java.lang.String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool";
field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
+ field public static final java.lang.String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
field public static final java.lang.String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool";
@@ -42249,6 +42251,13 @@
field public static final int STATUS_UNKNOWN = 0; // 0x0
}
+ public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+ method public void close();
+ method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsGroupCallSessionCallback);
+ method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsGroupCallSessionCallback);
+ method public android.telephony.mbms.GroupCall startGroupCall(java.util.concurrent.Executor, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+ }
+
public class MbmsStreamingSession implements java.lang.AutoCloseable {
method public void close();
method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback);
@@ -42257,7 +42266,7 @@
method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, java.util.concurrent.Executor, android.telephony.mbms.StreamingServiceCallback);
}
- public class NeighboringCellInfo implements android.os.Parcelable {
+ public deprecated class NeighboringCellInfo implements android.os.Parcelable {
ctor public deprecated NeighboringCellInfo();
ctor public deprecated NeighboringCellInfo(int, int);
ctor public NeighboringCellInfo(int, java.lang.String, int);
@@ -42628,6 +42637,7 @@
method public static int getDefaultVoiceSubscriptionId();
method public static int[] getSubscriptionIds(int);
method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+ method public boolean isActiveSubscriptionId(int);
method public boolean isNetworkRoaming(int);
method public static boolean isValidSubscriptionId(int);
method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
@@ -42713,7 +42723,6 @@
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public java.lang.String getNai();
- method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public java.lang.String getNetworkCountryIso();
method public java.lang.String getNetworkOperator();
method public java.lang.String getNetworkOperatorName();
@@ -43194,6 +43203,29 @@
field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR;
}
+ public class GroupCall implements java.lang.AutoCloseable {
+ method public void close();
+ method public long getTmgi();
+ method public void updateGroupCall(int[], int[]);
+ field public static final int REASON_BY_USER_REQUEST = 1; // 0x1
+ field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3
+ field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; // 0x6
+ field public static final int REASON_NONE = 0; // 0x0
+ field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5
+ field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4
+ field public static final int STATE_STALLED = 3; // 0x3
+ field public static final int STATE_STARTED = 2; // 0x2
+ field public static final int STATE_STOPPED = 1; // 0x1
+ }
+
+ public class GroupCallCallback {
+ ctor public GroupCallCallback();
+ method public void onBroadcastSignalStrengthUpdated(int);
+ method public void onError(int, java.lang.String);
+ method public void onGroupCallStateChanged(int, int);
+ field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff
+ }
+
public class MbmsDownloadReceiver extends android.content.BroadcastReceiver {
ctor public MbmsDownloadReceiver();
method public void onReceive(android.content.Context, android.content.Intent);
@@ -43242,6 +43274,14 @@
field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e
}
+ public class MbmsGroupCallSessionCallback {
+ ctor public MbmsGroupCallSessionCallback();
+ method public void onAvailableSaisUpdated(java.util.List<java.lang.Integer>, java.util.List<java.util.List<java.lang.Integer>>);
+ method public void onError(int, java.lang.String);
+ method public void onMiddlewareReady();
+ method public void onServiceInterfaceAvailable(java.lang.String, int);
+ }
+
public class MbmsStreamingSessionCallback {
ctor public MbmsStreamingSessionCallback();
method public void onError(int, java.lang.String);
@@ -54833,6 +54873,7 @@
public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader);
ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader);
+ ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader, boolean);
}
public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
diff --git a/api/removed.txt b/api/removed.txt
index f35348e..fba5187 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -540,6 +540,7 @@
}
public class TelephonyManager {
+ method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
method public deprecated android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index e3f52a0..231a327 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5048,6 +5048,7 @@
method public deprecated android.content.ComponentName getDefaultPhoneApp();
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage();
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
+ method public boolean isInEmergencyCall();
method public boolean isRinging();
method public boolean isTtySupported();
field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
@@ -5074,6 +5075,10 @@
field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
}
+ public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+ field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall";
+ }
+
public class MbmsStreamingSession implements java.lang.AutoCloseable {
field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming";
}
@@ -5237,6 +5242,7 @@
method public boolean disableDataConnectivity();
method public boolean enableDataConnectivity();
method public void enableVideoCalling(boolean);
+ method public java.lang.String getAidForAppType(int);
method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
@@ -5251,6 +5257,8 @@
method public deprecated boolean getDataEnabled();
method public deprecated boolean getDataEnabled(int);
method public boolean getEmergencyCallbackMode();
+ method public java.lang.String getIsimDomain();
+ method public int getPreferredNetworkType(int);
method public int getSimApplicationState();
method public int getSimCardState();
method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
@@ -5260,10 +5268,7 @@
method public boolean handlePinMmi(java.lang.String);
method public boolean handlePinMmiForSubscriber(int, java.lang.String);
method public boolean isDataConnectivityPossible();
- method public deprecated boolean isIdle();
- method public deprecated boolean isOffhook();
method public deprecated boolean isRadioOn();
- method public deprecated boolean isRinging();
method public boolean isVideoCallingEnabled();
method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
method public boolean needsOtaServiceProvisioning();
@@ -5277,7 +5282,6 @@
method public void setSimPowerStateForSlot(int, int);
method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
method public void setVoiceActivationState(int);
- method public deprecated void silenceRinger();
method public boolean supplyPin(java.lang.String);
method public int[] supplyPinReportResult(java.lang.String);
method public boolean supplyPuk(java.lang.String, java.lang.String);
@@ -5295,6 +5299,29 @@
field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+ field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
+ field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
+ field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6
+ field public static final int NETWORK_MODE_GLOBAL = 7; // 0x7
+ field public static final int NETWORK_MODE_GSM_ONLY = 1; // 0x1
+ field public static final int NETWORK_MODE_GSM_UMTS = 3; // 0x3
+ field public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8; // 0x8
+ field public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; // 0xa
+ field public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9; // 0x9
+ field public static final int NETWORK_MODE_LTE_ONLY = 11; // 0xb
+ field public static final int NETWORK_MODE_LTE_TDSCDMA = 15; // 0xf
+ field public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; // 0x16
+ field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; // 0x11
+ field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; // 0x14
+ field public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; // 0x13
+ field public static final int NETWORK_MODE_LTE_WCDMA = 12; // 0xc
+ field public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; // 0x15
+ field public static final int NETWORK_MODE_TDSCDMA_GSM = 16; // 0x10
+ field public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; // 0x12
+ field public static final int NETWORK_MODE_TDSCDMA_ONLY = 13; // 0xd
+ field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe
+ field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2
+ field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0
field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
@@ -5630,6 +5657,7 @@
field public static final java.lang.String EXTRA_CODEC = "Codec";
field public static final java.lang.String EXTRA_DIALSTRING = "dialstring";
field public static final java.lang.String EXTRA_DISPLAY_TEXT = "DisplayText";
+ field public static final java.lang.String EXTRA_E_CALL = "e_call";
field public static final java.lang.String EXTRA_IS_CALL_PULL = "CallPull";
field public static final java.lang.String EXTRA_OI = "oi";
field public static final java.lang.String EXTRA_OIR = "oir";
@@ -6373,6 +6401,17 @@
method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
}
+ public class MbmsGroupCallServiceBase extends android.app.Service {
+ ctor public MbmsGroupCallServiceBase();
+ method public void dispose(int) throws android.os.RemoteException;
+ method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+ method public void onAppCallbackDied(int, int);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+ method public void stopGroupCall(int, long);
+ method public void updateGroupCall(int, long, int[], int[]);
+ }
+
public class MbmsStreamingServiceBase extends android.os.Binder {
ctor public MbmsStreamingServiceBase();
method public void dispose(int) throws android.os.RemoteException;
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 69ad3ea..72b60e2 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -148,6 +148,10 @@
public class TelephonyManager {
method public deprecated void answerRingingCall();
method public deprecated boolean endCall();
+ method public deprecated boolean isIdle();
+ method public deprecated boolean isOffhook();
+ method public deprecated boolean isRinging();
+ method public deprecated void silenceRinger();
}
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 634293a..a7bb467 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -966,6 +966,10 @@
field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
}
+ public class MbmsGroupCallSession implements java.lang.AutoCloseable {
+ field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = "mbms-group-call-service-override";
+ }
+
public class MbmsStreamingSession implements java.lang.AutoCloseable {
field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
}
@@ -1035,6 +1039,17 @@
method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException;
}
+ public class MbmsGroupCallServiceBase extends android.app.Service {
+ ctor public MbmsGroupCallServiceBase();
+ method public void dispose(int) throws android.os.RemoteException;
+ method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException;
+ method public void onAppCallbackDied(int, int);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback);
+ method public void stopGroupCall(int, long);
+ method public void updateGroupCall(int, long, int[], int[]);
+ }
+
public class MbmsStreamingServiceBase extends android.os.Binder {
ctor public MbmsStreamingServiceBase();
method public void dispose(int) throws android.os.RemoteException;
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 4bbe042..72a4103 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -425,7 +425,19 @@
WorkerThreadSection::~WorkerThreadSection() {}
+void sigpipe_handler(int signum) {
+ if (signum == SIGPIPE) {
+ ALOGE("Wrote to a broken pipe\n");
+ } else {
+ ALOGE("Received unexpected signal: %d\n", signum);
+ }
+}
+
static void* worker_thread_func(void* cookie) {
+ // Don't crash the service if we write to a closed pipe (which can happen if
+ // dumping times out).
+ signal(SIGPIPE, sigpipe_handler);
+
WorkerThreadData* data = (WorkerThreadData*)cookie;
status_t err = data->section->BlockingCall(data->pipe.writeFd().get());
@@ -506,6 +518,7 @@
}
}
}
+
write_section_stats(requests->sectionStats(this->id), buffer);
if (timedOut || buffer.timedOut()) {
ALOGW("WorkerThreadSection '%s' timed out", this->name.string());
@@ -813,7 +826,10 @@
}
}
gLastLogsRetrieved[mLogID] = lastTimestamp;
- proto.flush(pipeWriteFd);
+ if (!proto.flush(pipeWriteFd) && errno == EPIPE) {
+ ALOGE("[%s] wrote to a broken pipe\n", this->name.string());
+ return EPIPE;
+ }
return NO_ERROR;
}
@@ -915,7 +931,7 @@
break;
}
if (cStatus != NO_ERROR) {
- ALOGE("TombstoneSection '%s' child had an issue: %s\n", this->name.string(), strerror(-cStatus));
+ ALOGE("[%s] child had an issue: %s\n", this->name.string(), strerror(-cStatus));
}
auto dump = std::make_unique<char[]>(buffer.size());
@@ -934,7 +950,13 @@
dumpPipe.readFd().reset();
}
- proto.flush(pipeWriteFd);
+ if (!proto.flush(pipeWriteFd) && errno == EPIPE) {
+ ALOGE("[%s] wrote to a broken pipe\n", this->name.string());
+ if (err != NO_ERROR) {
+ return EPIPE;
+ }
+ }
+
return err;
}
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index a031a15..2f89370 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -173,7 +173,7 @@
*/
class TombstoneSection : public WorkerThreadSection {
public:
- TombstoneSection(int id, const char* type, int64_t timeoutMs = 30000 /* 30 seconds */);
+ TombstoneSection(int id, const char* type, int64_t timeoutMs = 120000 /* 2 minutes */);
virtual ~TombstoneSection();
virtual status_t BlockingCall(int pipeWriteFd) const;
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 9c94f96..fbf5b52 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -2147,27 +2147,20 @@
Lcom/android/internal/telephony/ISub;->getDefaultSubId()I
Lcom/android/internal/telephony/ISub;->setDefaultDataSubId(I)V
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z
-Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCallForSubscriber(I)Z
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->isRadioOn(Ljava/lang/String;)Z
Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony;
Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String;
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_answerRingingCall:I
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I
-Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
-Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V
Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V
Lcom/android/internal/telephony/ITelephony;->dial(Ljava/lang/String;)V
Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z
Lcom/android/internal/telephony/ITelephony;->disableLocationUpdates()V
Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z
Lcom/android/internal/telephony/ITelephony;->enableLocationUpdates()V
-Lcom/android/internal/telephony/ITelephony;->endCall()Z
-Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z
Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I
Lcom/android/internal/telephony/ITelephony;->getCallState()I
Lcom/android/internal/telephony/ITelephony;->getDataActivity()I
@@ -2179,12 +2172,8 @@
Lcom/android/internal/telephony/ITelephony;->hasIccCard()Z
Lcom/android/internal/telephony/ITelephony;->iccCloseLogicalChannel(II)Z
Lcom/android/internal/telephony/ITelephony;->iccTransmitApduLogicalChannel(IIIIIIILjava/lang/String;)Ljava/lang/String;
-Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z
-Lcom/android/internal/telephony/ITelephony;->isIdleForSubscriber(ILjava/lang/String;)Z
Lcom/android/internal/telephony/ITelephony;->isRadioOnForSubscriber(ILjava/lang/String;)Z
-Lcom/android/internal/telephony/ITelephony;->isRinging(Ljava/lang/String;)Z
Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z
-Lcom/android/internal/telephony/ITelephony;->silenceRinger()V
Lcom/android/internal/telephony/ITelephony;->supplyPin(Ljava/lang/String;)Z
Lcom/android/internal/telephony/ITelephony;->toggleRadioOnOff()V
Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 183be5f..559a59b 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -73,6 +73,8 @@
/** Connection canceled before completion. */
public static final int RESULT_CANCELED = 2;
+ private static final int UPLOADING_FEATURE_BITMASK = 0x08;
+
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
new IBluetoothStateChangeCallback.Stub() {
public void onBluetoothStateChange(boolean up) {
@@ -395,6 +397,23 @@
return false;
}
+ /**
+ * Returns the "Uploading" feature bit value from the SDP record's
+ * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114).
+ * @param device The Bluetooth device to get this value for.
+ * @return Returns true if the Uploading bit value in SDP record's
+ * MapSupportedFeatures field is set. False is returned otherwise.
+ */
+ public boolean isUploadingSupported(BluetoothDevice device) {
+ try {
+ return (mService != null && isEnabled() && isValidDevice(device))
+ && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ return false;
+ }
+
private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index f2e9078..8333b81 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -26,7 +26,6 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
@@ -3801,8 +3800,9 @@
private void unsupportedStartingFrom(int version) {
if (Process.myUid() == Process.SYSTEM_UID) {
- // The getApplicationInfo() call we make below is not supported in system context, and
- // we want to allow the system to use these APIs anyway.
+ // The getApplicationInfo() call we make below is not supported in system context. Let
+ // the call through here, and rely on the fact that ConnectivityService will refuse to
+ // allow the system to use these APIs anyway.
return;
}
@@ -3819,11 +3819,6 @@
// functions by accessing ConnectivityService directly. However, it should be clear that doing
// so is unsupported and may break in the future. http://b/22728205
private void checkLegacyRoutingApiAccess() {
- if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS")
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
-
unsupportedStartingFrom(VERSION_CODES.M);
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 149f2b4..dd011a0 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1444,18 +1444,6 @@
}
public static final class Media implements AudioColumns {
-
- private static final String[] EXTERNAL_PATHS;
-
- static {
- String secondary_storage = System.getenv("SECONDARY_STORAGE");
- if (secondary_storage != null) {
- EXTERNAL_PATHS = secondary_storage.split(":");
- } else {
- EXTERNAL_PATHS = new String[0];
- }
- }
-
/**
* Get the content:// style URI for the audio media table on the
* given volume.
@@ -1469,14 +1457,9 @@
}
public static Uri getContentUriForPath(String path) {
- for (String ep : EXTERNAL_PATHS) {
- if (path.startsWith(ep)) {
- return EXTERNAL_CONTENT_URI;
- }
- }
-
- return (path.startsWith(Environment.getExternalStorageDirectory().getPath()) ?
- EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI);
+ return (path.startsWith(
+ Environment.getStorageDirectory().getAbsolutePath() + "/")
+ ? EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI);
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4b76ba8..fccdad6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9469,8 +9469,7 @@
* Use the old dnsmasq DHCP server for tethering instead of the framework implementation.
*
* Integer values are interpreted as boolean, and the absence of an explicit setting
- * is interpreted as |true|.
- * TODO: make the default |false|
+ * is interpreted as |false|.
* @hide
*/
public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index 119f5d0..4f4d62a 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -16,26 +16,23 @@
package android.security.net.config;
-import android.os.Environment;
-import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;
-import android.util.Pair;
+
+import libcore.io.IoUtils;
+
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.InputStream;
import java.io.IOException;
-import java.security.cert.Certificate;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Set;
-import libcore.io.IoUtils;
-
-import com.android.org.conscrypt.Hex;
-import com.android.org.conscrypt.NativeCrypto;
import javax.security.auth.x500.X500Principal;
@@ -192,8 +189,36 @@
}
private String getHash(X500Principal name) {
- int hash = NativeCrypto.X509_NAME_hash_old(name);
- return Hex.intToHexString(hash, 8);
+ int hash = hashName(name);
+ return intToHexString(hash, 8);
+ }
+
+ private static final char[] DIGITS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ private static String intToHexString(int i, int minWidth) {
+ int bufLen = 8; // Max number of hex digits in an int
+ char[] buf = new char[bufLen];
+ int cursor = bufLen;
+
+ do {
+ buf[--cursor] = DIGITS[i & 0xf];
+ } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
+
+ return new String(buf, cursor, bufLen - cursor);
+ }
+
+ // This code matches the code in X509_NAME_hash_old() in Conscrypt, which in turn matches
+ // the names of certificate files. It must be kept in sync.
+ private static int hashName(X500Principal principal) {
+ try {
+ byte[] digest = MessageDigest.getInstance("MD5").digest(principal.getEncoded());
+ int offset = 0;
+ return (((digest[offset++] & 0xff) << 0) | ((digest[offset++] & 0xff) << 8)
+ | ((digest[offset++] & 0xff) << 16) | ((digest[offset] & 0xff) << 24));
+ } catch (NoSuchAlgorithmException e) {
+ throw new AssertionError(e);
+ }
}
private X509Certificate readCertificate(String file) {
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index b591163..f90eab1 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -236,6 +236,7 @@
displayName = FileUtils.buildValidFatFilename(displayName);
final File before = getFileForDocId(docId);
+ final File beforeVisibleFile = getFileForDocId(docId, true);
final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName);
if (!before.renameTo(after)) {
throw new IllegalStateException("Failed to rename to " + after);
@@ -245,7 +246,6 @@
onDocIdChanged(docId);
onDocIdChanged(afterDocId);
- final File beforeVisibleFile = getFileForDocId(docId, true);
final File afterVisibleFile = getFileForDocId(afterDocId, true);
moveInMediaStore(beforeVisibleFile, afterVisibleFile);
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index 6df23f7..a1f2377 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -58,6 +58,11 @@
int ret;
int fd;
+ if (name == NULL) {
+ jniThrowNullPointerException(env, NULL);
+ return;
+ }
+
fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
if (env->ExceptionCheck()) {
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index c15b7ee..109e65c 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -285,10 +285,6 @@
static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path,
jint limitUid, jobjectArray limitIfacesObj, jint limitTag,
jboolean useBpfStats) {
- ScopedUtfChars path8(env, path);
- if (path8.c_str() == NULL) {
- return -1;
- }
std::vector<std::string> limitIfaces;
if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
@@ -308,6 +304,11 @@
if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0)
return -1;
} else {
+ ScopedUtfChars path8(env, path);
+ if (path8.c_str() == NULL) {
+ ALOGE("the qtaguid legacy path is invalid: %s", path8.c_str());
+ return -1;
+ }
if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag,
limitUid, path8.c_str()) < 0)
return -1;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 632e439..477b17e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3463,4 +3463,12 @@
<!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
<bool name="config_swipe_up_gesture_setting_available">false</bool>
+ <!-- Pre-scale volume at volume step 1 for Absolute Volume -->
+ <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction>
+
+ <!-- Pre-scale volume at volume step 2 for Absolute Volume -->
+ <fraction name="config_prescaleAbsoluteVolume_index2">70%</fraction>
+
+ <!-- Pre-scale volume at volume step 3 for Absolute Volume -->
+ <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index de5dc43..e9a54f1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3393,4 +3393,9 @@
<java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
<java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
+
+ <!-- For Bluetooth AbsoluteVolume -->
+ <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" />
+ <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" />
+ <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" />
</resources>
diff --git a/core/tests/coretests/src/android/net/LocalSocketTest.java b/core/tests/coretests/src/android/net/LocalSocketTest.java
index 1349844..1286b13 100644
--- a/core/tests/coretests/src/android/net/LocalSocketTest.java
+++ b/core/tests/coretests/src/android/net/LocalSocketTest.java
@@ -22,6 +22,7 @@
import android.net.LocalSocketAddress;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
+
import junit.framework.TestCase;
import java.io.FileDescriptor;
@@ -39,6 +40,20 @@
ls = new LocalSocket();
+ try {
+ ls.connect(new LocalSocketAddress(null));
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // pass
+ }
+
+ try {
+ ls.bind(new LocalSocketAddress(null));
+ fail("Expected NullPointerException");
+ } catch (NullPointerException e) {
+ // pass
+ }
+
ls.connect(new LocalSocketAddress("android.net.LocalSocketTest"));
ls1 = ss.accept();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 02e1f2f..2eed70f 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -159,8 +159,9 @@
public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild";
public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint";
- private static final String SYSTEM_SOUNDS_DIR = "/system/media/audio";
- private static final String PRODUCT_SOUNDS_DIR = "/product/media/audio";
+ private static final String SYSTEM_SOUNDS_DIR = Environment.getRootDirectory() + "/media/audio";
+ private static final String OEM_SOUNDS_DIR = Environment.getOemDirectory() + "/media/audio";
+ private static final String PRODUCT_SOUNDS_DIR = Environment.getProductDirectory() + "/media/audio";
private static String sLastInternalScanFingerprint;
private static final String[] ID3_GENRES = {
@@ -1192,6 +1193,9 @@
if (path.startsWith(SYSTEM_SOUNDS_DIR + ALARMS_DIR)
|| path.startsWith(SYSTEM_SOUNDS_DIR + RINGTONES_DIR)
|| path.startsWith(SYSTEM_SOUNDS_DIR + NOTIFICATIONS_DIR)
+ || path.startsWith(OEM_SOUNDS_DIR + ALARMS_DIR)
+ || path.startsWith(OEM_SOUNDS_DIR + RINGTONES_DIR)
+ || path.startsWith(OEM_SOUNDS_DIR + NOTIFICATIONS_DIR)
|| path.startsWith(PRODUCT_SOUNDS_DIR + ALARMS_DIR)
|| path.startsWith(PRODUCT_SOUNDS_DIR + RINGTONES_DIR)
|| path.startsWith(PRODUCT_SOUNDS_DIR + NOTIFICATIONS_DIR)) {
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a46c3e6..76a216d 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1125,4 +1125,7 @@
<!-- time label for event have that happened very recently [CHAR LIMIT=60] -->
<string name="time_unit_just_now">Just now</string>
+
+ <!-- The notice header of Third-party licenses. not translatable -->
+ <string name="notice_header" translatable="false"></string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 541877c..3c58160 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -105,7 +105,7 @@
BluetoothProfile.A2DP);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 0e0f63c..656f23f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -99,7 +99,7 @@
BluetoothProfile.A2DP_SINK);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index e96c44d..8fa9597 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -250,7 +250,7 @@
int preferredProfiles = 0;
for (LocalBluetoothProfile profile : mProfiles) {
- if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
+ if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) {
if (profile.isPreferred(mDevice)) {
++preferredProfiles;
connectInt(profile);
@@ -736,7 +736,7 @@
List<LocalBluetoothProfile> connectableProfiles =
new ArrayList<LocalBluetoothProfile>();
for (LocalBluetoothProfile profile : mProfiles) {
- if (profile.isConnectable()) {
+ if (profile.accessProfileEnabled()) {
connectableProfiles.add(profile);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index 7f83860..3bb8450 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -106,7 +106,7 @@
BluetoothProfile.HEADSET);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index 1d2fda9..06d60e6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -103,7 +103,7 @@
BluetoothProfile.HEARING_AID);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return false;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 0857b01..4ae9b32 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -107,7 +107,7 @@
}
@Override
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
index af78c6f..1c04e83 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
@@ -97,7 +97,7 @@
}
@Override
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index dc17e44..1e06481 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -95,7 +95,7 @@
BluetoothProfile.HID_HOST);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
index 0447f37..4b0ca74 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
@@ -26,9 +26,9 @@
public interface LocalBluetoothProfile {
/**
- * Returns true if the user can initiate a connection, false otherwise.
+ * Return {@code true} if the user can initiate a connection for this profile in UI.
*/
- boolean isConnectable();
+ boolean accessProfileEnabled();
/**
* Returns true if the user can enable auto connection for this profile.
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index e9fcc11..57712e3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -108,7 +108,7 @@
BluetoothProfile.MAP_CLIENT);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index 511c4ce..e59a036 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -107,7 +107,7 @@
BluetoothProfile.MAP);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
index dfd1622..e1e5dbe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
@@ -32,7 +32,7 @@
// Order of this profile in device profiles list
private static final int ORDINAL = 2;
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return false;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index b18b19b..0d566c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -80,7 +80,7 @@
BluetoothProfile.PAN);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index fc54775..c83ff35 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -110,7 +110,7 @@
BluetoothProfile.PBAP_CLIENT);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index e9d8cb5..adef0841 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -80,7 +80,7 @@
BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener());
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index 2c455d5f..f7cd393 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -106,7 +106,7 @@
BluetoothProfile.SAP);
}
- public boolean isConnectable() {
+ public boolean accessProfileEnabled() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
index 42306f6..9870b3c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
@@ -107,12 +107,13 @@
mXmlFiles = xmlFiles;
}
- public static boolean generateHtml(List<File> xmlFiles, File outputFile) {
+ public static boolean generateHtml(List<File> xmlFiles, File outputFile,
+ String noticeHeader) {
LicenseHtmlGeneratorFromXml genertor = new LicenseHtmlGeneratorFromXml(xmlFiles);
- return genertor.generateHtml(outputFile);
+ return genertor.generateHtml(outputFile, noticeHeader);
}
- private boolean generateHtml(File outputFile) {
+ private boolean generateHtml(File outputFile, String noticeHeader) {
for (File xmlFile : mXmlFiles) {
parse(xmlFile);
}
@@ -125,7 +126,8 @@
try {
writer = new PrintWriter(outputFile);
- generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer);
+ generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer,
+ noticeHeader);
writer.flush();
writer.close();
@@ -239,13 +241,18 @@
@VisibleForTesting
static void generateHtml(Map<String, String> fileNameToContentIdMap,
- Map<String, String> contentIdToFileContentMap, PrintWriter writer) {
+ Map<String, String> contentIdToFileContentMap, PrintWriter writer,
+ String noticeHeader) {
List<String> fileNameList = new ArrayList();
fileNameList.addAll(fileNameToContentIdMap.keySet());
Collections.sort(fileNameList);
writer.println(HTML_HEAD_STRING);
+ if (!TextUtils.isEmpty(noticeHeader)) {
+ writer.println(noticeHeader);
+ }
+
int count = 0;
Map<String, Integer> contentIdToOrderMap = new HashMap();
List<ContentIdAndFileNames> contentIdAndFileNamesList = new ArrayList();
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
index 2aaea65..8b562f70 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java
@@ -21,6 +21,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settingslib.R;
import com.android.settingslib.utils.AsyncLoader;
import java.io.File;
@@ -108,6 +109,7 @@
@VisibleForTesting
boolean generateHtmlFile(List<File> xmlFiles, File htmlFile) {
- return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile);
+ return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile,
+ mContext.getString(R.string.notice_header));
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index 96b2a14..b00476b2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -50,7 +50,7 @@
+ "<file-content contentId=\"0\"><![CDATA[license content #0]]></file-content>\n"
+ "</licenses2>";
- private static final String EXPECTED_HTML_STRING =
+ private static final String HTML_HEAD_STRING =
"<html><head>\n"
+ "<style type=\"text/css\">\n"
+ "body { padding: 0; font-family: sans-serif; }\n"
@@ -63,8 +63,12 @@
+ "</head>"
+ "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n"
+ "<div class=\"toc\">\n"
- + "<ul>\n"
- + "<li><a href=\"#id0\">/file0</a></li>\n"
+ + "<ul>\n";
+
+ private static final String HTML_CUSTOM_HEADING = "Custom heading";
+
+ private static final String HTML_BODY_STRING =
+ "<li><a href=\"#id0\">/file0</a></li>\n"
+ "<li><a href=\"#id0\">/file1</a></li>\n"
+ "</ul>\n"
+ "</div><!-- table of contents -->\n"
@@ -81,6 +85,11 @@
+ "</td></tr><!-- same-license -->\n"
+ "</table></body></html>\n";
+ private static final String EXPECTED_HTML_STRING = HTML_HEAD_STRING + HTML_BODY_STRING;
+
+ private static final String EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING =
+ HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_BODY_STRING;
+
@Test
public void testParseValidXmlStream() throws XmlPullParserException, IOException {
Map<String, String> fileNameToContentIdMap = new HashMap<String, String>();
@@ -117,7 +126,23 @@
StringWriter output = new StringWriter();
LicenseHtmlGeneratorFromXml.generateHtml(
- fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output));
+ fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), "");
assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING);
}
+
+ @Test
+ public void testGenerateHtmlWithCustomHeading() {
+ Map<String, String> fileNameToContentIdMap = new HashMap<String, String>();
+ Map<String, String> contentIdToFileContentMap = new HashMap<String, String>();
+
+ fileNameToContentIdMap.put("/file0", "0");
+ fileNameToContentIdMap.put("/file1", "0");
+ contentIdToFileContentMap.put("0", "license content #0");
+
+ StringWriter output = new StringWriter();
+ LicenseHtmlGeneratorFromXml.generateHtml(
+ fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output),
+ HTML_CUSTOM_HEADING);
+ assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING);
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 9e4810c..35abb0a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -342,12 +342,11 @@
case SimPuk:
// Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
- if (securityMode != SecurityMode.None
- || !mLockPatternUtils.isLockScreenDisabled(
+ if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser())) {
- showSecurityScreen(securityMode);
- } else {
finish = true;
+ } else {
+ showSecurityScreen(securityMode);
}
break;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index e41a09e..a1989e5 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -57,6 +57,7 @@
import android.net.ConnectivityManager.PacketKeepalive;
import android.net.IConnectivityManager;
import android.net.IIpConnectivityMetrics;
+import android.net.INetd;
import android.net.INetdEventCallback;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkPolicyListener;
@@ -88,6 +89,7 @@
import android.net.metrics.NetworkEvent;
import android.net.netlink.InetDiagMessage;
import android.net.util.MultinetworkPolicyTracker;
+import android.net.util.NetdService;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -259,7 +261,8 @@
// 0 is full bad, 100 is full good
private int mDefaultInetConditionPublished = 0;
- private INetworkManagementService mNetd;
+ private INetworkManagementService mNMS;
+ private INetd mNetd;
private INetworkStatsService mStatsService;
private INetworkPolicyManager mPolicyManager;
private NetworkPolicyManagerInternal mPolicyManagerInternal;
@@ -759,7 +762,7 @@
mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS);
mContext = checkNotNull(context, "missing Context");
- mNetd = checkNotNull(netManager, "missing INetworkManagementService");
+ mNMS = checkNotNull(netManager, "missing INetworkManagementService");
mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
mPolicyManagerInternal = checkNotNull(
@@ -767,6 +770,7 @@
"missing NetworkPolicyManagerInternal");
mProxyTracker = new ProxyTracker(context, mHandler, EVENT_PROXY_HAS_CHANGED);
+ mNetd = NetdService.getInstance();
mKeyStore = KeyStore.getInstance();
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
@@ -849,7 +853,7 @@
mTethering = makeTethering();
- mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
+ mPermissionMonitor = new PermissionMonitor(mContext, mNMS);
//set up the listener for user state for creating user VPNs
IntentFilter intentFilter = new IntentFilter();
@@ -864,8 +868,8 @@
new IntentFilter(Intent.ACTION_USER_PRESENT), null, null);
try {
- mNetd.registerObserver(mTethering);
- mNetd.registerObserver(mDataActivityObserver);
+ mNMS.registerObserver(mTethering);
+ mNMS.registerObserver(mDataActivityObserver);
} catch (RemoteException e) {
loge("Error registering observer :" + e);
}
@@ -896,7 +900,7 @@
mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler);
- mDnsManager = new DnsManager(mContext, mNetd, mSystemProperties);
+ mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties);
registerPrivateDnsSettingsCallbacks();
}
@@ -912,7 +916,7 @@
return mDefaultRequest;
}
};
- return new Tethering(mContext, mNetd, mStatsService, mPolicyManager,
+ return new Tethering(mContext, mNMS, mStatsService, mPolicyManager,
IoThread.get().getLooper(), new MockableSystemProperties(),
deps);
}
@@ -1476,6 +1480,20 @@
};
/**
+ * Ensures that the system cannot call a particular method.
+ */
+ private boolean disallowedBecauseSystemCaller() {
+ // TODO: start throwing a SecurityException when GnssLocationProvider stops calling
+ // requestRouteToHost.
+ if (isSystem(Binder.getCallingUid())) {
+ log("This method exists only for app backwards compatibility"
+ + " and must not be called by system services.");
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface.
* @param networkType the type of the network over which traffic to the
@@ -1486,6 +1504,9 @@
*/
@Override
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
+ if (disallowedBecauseSystemCaller()) {
+ return false;
+ }
enforceChangePermission();
if (mProtectedNetworks.contains(networkType)) {
enforceConnectivityInternalPermission();
@@ -1563,7 +1584,7 @@
if (DBG) log("Adding legacy route " + bestRoute +
" for UID/PID " + uid + "/" + Binder.getCallingPid());
try {
- mNetd.addLegacyRouteForNetId(netId, bestRoute, uid);
+ mNMS.addLegacyRouteForNetId(netId, bestRoute, uid);
} catch (Exception e) {
// never crash - catch them all
if (DBG) loge("Exception trying to add a route: " + e);
@@ -1853,7 +1874,7 @@
if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
try {
- mNetd.addIdleTimer(iface, timeout, type);
+ mNMS.addIdleTimer(iface, timeout, type);
} catch (Exception e) {
// You shall not crash!
loge("Exception in setupDataActivityTracking " + e);
@@ -1872,7 +1893,7 @@
caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
try {
// the call fails silently if no idle timer setup for this interface
- mNetd.removeIdleTimer(iface);
+ mNMS.removeIdleTimer(iface);
} catch (Exception e) {
loge("Exception in removeDataActivityTracking " + e);
}
@@ -1880,6 +1901,18 @@
}
/**
+ * Update data activity tracking when network state is updated.
+ */
+ private void updateDataActivityTracking(NetworkAgentInfo newNetwork,
+ NetworkAgentInfo oldNetwork) {
+ if (newNetwork != null) {
+ setupDataActivityTracking(newNetwork);
+ }
+ if (oldNetwork != null) {
+ removeDataActivityTracking(oldNetwork);
+ }
+ }
+ /**
* Reads the network specific MTU size from resources.
* and set it on it's iface.
*/
@@ -1907,7 +1940,7 @@
try {
if (VDBG) log("Setting MTU size: " + iface + ", " + mtu);
- mNetd.setMtu(iface, mtu);
+ mNMS.setMtu(iface, mtu);
} catch (Exception e) {
Slog.e(TAG, "exception in setMtu()" + e);
}
@@ -2561,7 +2594,7 @@
}
nai.clearLingerState();
if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
- removeDataActivityTracking(nai);
+ updateDataActivityTracking(null /* newNetwork */, nai);
notifyLockdownVpn(nai);
ensureNetworkTransitionWakelock(nai.name());
}
@@ -2581,7 +2614,7 @@
// NetworkFactories, so network traffic isn't interrupted for an unnecessarily
// long time.
try {
- mNetd.removeNetwork(nai.network.netId);
+ mNMS.removeNetwork(nai.network.netId);
} catch (Exception e) {
loge("Exception removing network: " + e);
}
@@ -2779,20 +2812,6 @@
}
}
- // TODO: remove this code once we know that the Slog.wtf is never hit.
- //
- // Find all networks that are satisfying this request and remove the request
- // from their request lists.
- // TODO - it's my understanding that for a request there is only a single
- // network satisfying it, so this loop is wasteful
- for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) {
- if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) {
- Slog.wtf(TAG, "Request " + nri.request + " satisfied by " +
- otherNai.name() + ", but mNetworkAgentInfos says " +
- (nai != null ? nai.name() : "null"));
- }
- }
-
// Maintain the illusion. When this request arrived, we might have pretended
// that a network connected to serve it, even though the network was already
// connected. Now that this request has gone away, we might have to pretend
@@ -3760,7 +3779,7 @@
Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown");
return false;
}
- setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile));
+ setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile));
} else {
setLockdownTracker(null);
}
@@ -4015,7 +4034,7 @@
loge("Starting user already has a VPN");
return;
}
- userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId);
+ userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId);
mVpns.put(userId, userVpn);
if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) {
updateLockdownVpn();
@@ -4632,7 +4651,7 @@
mDnsManager.updatePrivateDnsStatus(netId, newLp);
// Start or stop clat accordingly to network state.
- networkAgent.updateClat(mNetd);
+ networkAgent.updateClat(mNMS);
if (isDefaultNetwork(networkAgent)) {
handleApplyDefaultProxy(newLp.getHttpProxy());
} else {
@@ -4671,9 +4690,9 @@
final String prefix = "iface:" + iface;
try {
if (add) {
- mNetd.getNetdService().wakeupAddInterface(iface, prefix, mark, mask);
+ mNetd.wakeupAddInterface(iface, prefix, mark, mask);
} else {
- mNetd.getNetdService().wakeupDelInterface(iface, prefix, mark, mask);
+ mNetd.wakeupDelInterface(iface, prefix, mark, mask);
}
} catch (Exception e) {
loge("Exception modifying wakeup packet monitoring: " + e);
@@ -4689,7 +4708,7 @@
for (String iface : interfaceDiff.added) {
try {
if (DBG) log("Adding iface " + iface + " to network " + netId);
- mNetd.addInterfaceToNetwork(iface, netId);
+ mNMS.addInterfaceToNetwork(iface, netId);
wakeupModifyInterface(iface, caps, true);
} catch (Exception e) {
loge("Exception adding interface: " + e);
@@ -4699,7 +4718,7 @@
try {
if (DBG) log("Removing iface " + iface + " from network " + netId);
wakeupModifyInterface(iface, caps, false);
- mNetd.removeInterfaceFromNetwork(iface, netId);
+ mNMS.removeInterfaceFromNetwork(iface, netId);
} catch (Exception e) {
loge("Exception removing interface: " + e);
}
@@ -4723,7 +4742,7 @@
if (route.hasGateway()) continue;
if (VDBG) log("Adding Route [" + route + "] to network " + netId);
try {
- mNetd.addRoute(netId, route);
+ mNMS.addRoute(netId, route);
} catch (Exception e) {
if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
loge("Exception in addRoute for non-gateway: " + e);
@@ -4734,7 +4753,7 @@
if (route.hasGateway() == false) continue;
if (VDBG) log("Adding Route [" + route + "] to network " + netId);
try {
- mNetd.addRoute(netId, route);
+ mNMS.addRoute(netId, route);
} catch (Exception e) {
if ((route.getGateway() instanceof Inet4Address) || VDBG) {
loge("Exception in addRoute for gateway: " + e);
@@ -4745,7 +4764,7 @@
for (RouteInfo route : routeDiff.removed) {
if (VDBG) log("Removing Route [" + route + "] from network " + netId);
try {
- mNetd.removeRoute(netId, route);
+ mNMS.removeRoute(netId, route);
} catch (Exception e) {
loge("Exception in removeRoute: " + e);
}
@@ -4857,7 +4876,7 @@
final String newPermission = getNetworkPermission(newNc);
if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
try {
- mNetd.setNetworkPermission(nai.network.netId, newPermission);
+ mNMS.setNetworkPermission(nai.network.netId, newPermission);
} catch (RemoteException e) {
loge("Exception in setNetworkPermission: " + e);
}
@@ -4917,12 +4936,12 @@
if (!newRanges.isEmpty()) {
final UidRange[] addedRangesArray = new UidRange[newRanges.size()];
newRanges.toArray(addedRangesArray);
- mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray);
+ mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray);
}
if (!prevRanges.isEmpty()) {
final UidRange[] removedRangesArray = new UidRange[prevRanges.size()];
prevRanges.toArray(removedRangesArray);
- mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray);
+ mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray);
}
} catch (Exception e) {
// Never crash!
@@ -5091,9 +5110,9 @@
private void makeDefault(NetworkAgentInfo newNetwork) {
if (DBG) log("Switching to new default network: " + newNetwork);
- setupDataActivityTracking(newNetwork);
+
try {
- mNetd.setDefaultNetId(newNetwork.network.netId);
+ mNMS.setDefaultNetId(newNetwork.network.netId);
} catch (Exception e) {
loge("Exception setting default network :" + e);
}
@@ -5266,6 +5285,7 @@
}
}
if (isNewDefault) {
+ updateDataActivityTracking(newNetwork, oldDefaultNetwork);
// Notify system services that this network is up.
makeDefault(newNetwork);
// Log 0 -> X and Y -> X default network transitions, where X is the new default.
@@ -5488,12 +5508,12 @@
try {
// This should never fail. Specifying an already in use NetID will cause failure.
if (networkAgent.isVPN()) {
- mNetd.createVirtualNetwork(networkAgent.network.netId,
+ mNMS.createVirtualNetwork(networkAgent.network.netId,
!networkAgent.linkProperties.getDnsServers().isEmpty(),
(networkAgent.networkMisc == null ||
!networkAgent.networkMisc.allowBypass));
} else {
- mNetd.createPhysicalNetwork(networkAgent.network.netId,
+ mNMS.createPhysicalNetwork(networkAgent.network.netId,
getNetworkPermission(networkAgent.networkCapabilities));
}
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 9c81748..ab0a565 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -160,6 +160,8 @@
private static final int MAX_UID_RANGES_PER_COMMAND = 10;
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
/**
* Name representing {@link #setGlobalAlert(long)} limit when delivered to
* {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -1229,18 +1231,12 @@
@Override
public void startTethering(String[] dhcpRange) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- // cmd is "tether start first_start first_stop second_start second_stop ..."
// an odd number of addrs will fail
- final Command cmd = new Command("tether", "start");
- for (String d : dhcpRange) {
- cmd.appendArg(d);
- }
-
try {
- mConnector.execute(cmd);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.tetherStart(dhcpRange);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
}
@@ -1248,9 +1244,9 @@
public void stopTethering() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("tether", "stop");
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.tetherStop();
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
}
@@ -1258,25 +1254,21 @@
public boolean isTetheringStarted() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- final NativeDaemonEvent event;
try {
- event = mConnector.execute("tether", "status");
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ final boolean isEnabled = mNetdService.tetherIsEnabled();
+ return isEnabled;
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
-
- // 210 Tethering services started
- event.checkCode(TetherStatusResult);
- return event.getMessage().endsWith("started");
}
@Override
public void tetherInterface(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("tether", "interface", "add", iface);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.tetherInterfaceAdd(iface);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
List<RouteInfo> routes = new ArrayList<>();
// The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
@@ -1289,9 +1281,9 @@
public void untetherInterface(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("tether", "interface", "remove", iface);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.tetherInterfaceRemove(iface);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
} finally {
removeInterfaceFromLocalNetwork(iface);
}
@@ -1301,11 +1293,10 @@
public String[] listTetheredInterfaces() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- return NativeDaemonEvent.filterMessageList(
- mConnector.executeForList("tether", "interface", "list"),
- TetherInterfaceListResult);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ final List<String> result = mNetdService.tetherInterfaceList();
+ return result.toArray(EMPTY_STRING_ARRAY);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
}
@@ -1314,16 +1305,11 @@
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
- final Command cmd = new Command("tether", "dns", "set", netId);
-
- for (String s : dns) {
- cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
- }
try {
- mConnector.execute(cmd);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.tetherDnsSet(netId, dns);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
}
@@ -1331,10 +1317,10 @@
public String[] getDnsForwarders() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- return NativeDaemonEvent.filterMessageList(
- mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ final List<String> result = mNetdService.tetherDnsList();
+ return result.toArray(EMPTY_STRING_ARRAY);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 59093c1..289143c 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -87,7 +87,7 @@
"media.metrics", // system/bin/mediametrics
"media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service
"com.android.bluetooth", // Bluetooth service
- "statsd", // Stats daemon
+ "/system/bin/statsd", // Stats daemon
};
public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0b9832d..6fa17d8 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -627,6 +627,13 @@
// If absolute volume is supported in AVRCP device
private boolean mAvrcpAbsVolSupported = false;
+ // Pre-scale for Bluetooth Absolute Volume
+ private float[] mPrescaleAbsoluteVolume = new float[] {
+ 0.5f, // Pre-scale for index 1
+ 0.7f, // Pre-scale for index 2
+ 0.85f, // Pre-scale for index 3
+ };
+
private static Long mLastDeviceConnectMsgTime = new Long(0);
private NotificationManager mNm;
@@ -878,6 +885,23 @@
mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
mRecordMonitor.initMonitor();
+
+ final float[] preScale = new float[3];
+ preScale[0] = mContext.getResources().getFraction(
+ com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
+ 1, 1);
+ preScale[1] = mContext.getResources().getFraction(
+ com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
+ 1, 1);
+ preScale[2] = mContext.getResources().getFraction(
+ com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
+ 1, 1);
+ for (int i = 0; i < preScale.length; i++) {
+ if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
+ mPrescaleAbsoluteVolume[i] = preScale[i];
+ }
+ }
+
}
public void systemReady() {
@@ -4879,18 +4903,12 @@
if (index == 0) {
// 0% for volume 0
index = 0;
- } else if (index == 1) {
- // 50% for volume 1
- index = (int)(mIndexMax * 0.5) /10;
- } else if (index == 2) {
- // 70% for volume 2
- index = (int)(mIndexMax * 0.70) /10;
- } else if (index == 3) {
- // 85% for volume 3
- index = (int)(mIndexMax * 0.85) /10;
+ } else if (index > 0 && index <= 3) {
+ // Pre-scale for volume steps 1 2 and 3
+ index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
} else {
// otherwise, full gain
- index = (mIndexMax + 5)/10;
+ index = (mIndexMax + 5) / 10;
}
return index;
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 2a80f0e..48082b6 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -163,8 +163,8 @@
// TODO: create separate trackers for each unique VPN to support
// automated reconnection
- private Context mContext;
- private NetworkInfo mNetworkInfo;
+ private final Context mContext;
+ private final NetworkInfo mNetworkInfo;
private String mPackage;
private int mOwnerUID;
private String mInterface;
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 2b1d919..1e6bb04 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -320,9 +320,8 @@
}
private static boolean getEnableLegacyDhcpServer(Context ctx) {
- // TODO: make the default false (0) and update javadoc in Settings.java
final ContentResolver cr = ctx.getContentResolver();
- final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
+ final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
return intVal != 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 271d205..fae4db9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17529,7 +17529,8 @@
// Prepare the application profiles for the new code paths.
// This needs to be done before invoking dexopt so that any install-time profile
// can be used for optimizations.
- mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
+ mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()),
+ /* updateReferenceProfileContent= */ true);
// Check whether we need to dexopt the app.
//
@@ -22606,8 +22607,18 @@
//
// We also have to cover non system users because we do not call the usual install package
// methods for them.
+ //
+ // NOTE: in order to speed up first boot time we only create the current profile and do not
+ // update the content of the reference profile. A system image should already be configured
+ // with the right profile keys and the profiles for the speed-profile prebuilds should
+ // already be copied. That's done in #performDexOptUpgrade.
+ //
+ // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
+ // manually copying them in #performDexOptUpgrade. When we do that we should have a more
+ // granular check here and only update the existing profiles.
if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
- mArtManagerService.prepareAppProfiles(pkg, userId);
+ mArtManagerService.prepareAppProfiles(pkg, userId,
+ /* updateReferenceProfileContent= */ false);
}
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 0ba7822..833cc5b 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -389,7 +389,8 @@
* - create the current primary profile to save time at app startup time.
* - copy the profiles from the associated dex metadata file to the reference profile.
*/
- public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user) {
+ public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user,
+ boolean updateReferenceProfileContent) {
final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
if (user < 0) {
Slog.wtf(TAG, "Invalid user id: " + user);
@@ -404,8 +405,14 @@
for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) {
String codePath = codePathsProfileNames.keyAt(i);
String profileName = codePathsProfileNames.valueAt(i);
- File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath));
- String dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
+ String dexMetadataPath = null;
+ // Passing the dex metadata file to the prepare method will update the reference
+ // profile content. As such, we look for the dex metadata file only if we need to
+ // perform an update.
+ if (updateReferenceProfileContent) {
+ File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath));
+ dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
+ }
synchronized (mInstaller) {
boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId,
profileName, codePath, dexMetadataPath);
@@ -423,9 +430,10 @@
/**
* Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}.
*/
- public void prepareAppProfiles(PackageParser.Package pkg, int[] user) {
+ public void prepareAppProfiles(PackageParser.Package pkg, int[] user,
+ boolean updateReferenceProfileContent) {
for (int i = 0; i < user.length; i++) {
- prepareAppProfiles(pkg, user[i]);
+ prepareAppProfiles(pkg, user[i], updateReferenceProfileContent);
}
}
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index e3e1590..602ce3b 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -93,7 +93,7 @@
@GuardedBy("mPackageUseInfoMap")
private final Map<String, PackageUseInfo> mPackageUseInfoMap;
- public PackageDexUsage() {
+ /* package */ PackageDexUsage() {
super("package-dex-usage.list", "PackageDexUsage_DiskWriter", /*lock*/ false);
mPackageUseInfoMap = new HashMap<>();
}
@@ -116,7 +116,7 @@
* @return true if the dex load constitutes new information, or false if this information
* has been seen before.
*/
- public boolean record(String owningPackageName, String dexPath, int ownerUserId,
+ /* package */ boolean record(String owningPackageName, String dexPath, int ownerUserId,
String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit,
String loadingPackageName, String classLoaderContext) {
if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
@@ -193,7 +193,7 @@
* Convenience method for sync reads which does not force the user to pass a useless
* (Void) null.
*/
- public void read() {
+ /* package */ void read() {
read((Void) null);
}
@@ -558,7 +558,7 @@
* Remove the usage data associated with package {@code packageName}.
* @return true if the package usage was found and removed successfully.
*/
- public boolean removePackage(String packageName) {
+ /* package */ boolean removePackage(String packageName) {
synchronized (mPackageUseInfoMap) {
return mPackageUseInfoMap.remove(packageName) != null;
}
@@ -653,11 +653,12 @@
return packages;
}
- public void clear() {
+ /* package */ void clear() {
synchronized (mPackageUseInfoMap) {
mPackageUseInfoMap.clear();
}
}
+
// Creates a deep copy of the class' mPackageUseInfoMap.
private Map<String, PackageUseInfo> clonePackageUseInfoMap() {
Map<String, PackageUseInfo> clone = new HashMap<>();
@@ -679,7 +680,7 @@
throw new IllegalArgumentException("Unknown bool encoding: " + bool);
}
- public String dump() {
+ /* package */ String dump() {
StringWriter sw = new StringWriter();
write(sw);
return sw.toString();
diff --git a/services/core/java/com/android/server/pm/dex/TEST_MAPPING b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
new file mode 100644
index 0000000..ad52559
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+ "presubmit": [
+ {
+ "name": "DexLoggerTests"
+ },
+ {
+ "name": "DexManagerTests"
+ },
+ {
+ "name": "DexoptOptionsTests"
+ },
+ {
+ "name": "DexoptUtilsTest"
+ },
+ {
+ "name": "PackageDexUsageTests"
+ },
+ {
+ "name": "DexLoggerIntegrationTests"
+ }
+ ]
+}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 89efe12..306f73a 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -98,7 +98,6 @@
"libsensorservicehidl",
"libgui",
"libusbhost",
- "libsuspend",
"libtinyalsa",
"libEGL",
"libGLESv2",
@@ -130,6 +129,7 @@
"android.hardware.vr@1.0",
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
+ "android.system.suspend@1.0",
],
static_libs: [
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index 02ad6c7..0ff60e4 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -30,6 +30,8 @@
#include <android/hardware/power/1.0/IPower.h>
#include <android/hardware/power/1.1/IPower.h>
+#include <android/system/suspend/1.0/ISystemSuspend.h>
+#include <android/system/suspend/1.0/ISystemSuspendCallback.h>
#include <android_runtime/AndroidRuntime.h>
#include <jni.h>
@@ -39,7 +41,6 @@
#include <log/log.h>
#include <utils/misc.h>
#include <utils/Log.h>
-#include <suspend/autosuspend.h>
using android::hardware::Return;
using android::hardware::Void;
@@ -49,6 +50,8 @@
using android::hardware::power::V1_1::PowerStateSubsystem;
using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
using android::hardware::hidl_vec;
+using android::system::suspend::V1_0::ISystemSuspend;
+using android::system::suspend::V1_0::ISystemSuspendCallback;
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
using IPowerV1_0 = android::hardware::power::V1_0::IPower;
@@ -63,6 +66,7 @@
extern sp<IPowerV1_0> getPowerHalV1_0();
extern sp<IPowerV1_1> getPowerHalV1_1();
extern bool processPowerHalReturn(const Return<void> &ret, const char* functionName);
+extern sp<ISystemSuspend> getSuspendHal();
// Java methods used in getLowPowerStats
static jmethodID jgetAndUpdatePlatformState = NULL;
@@ -70,16 +74,19 @@
static jmethodID jputVoter = NULL;
static jmethodID jputState = NULL;
-static void wakeup_callback(bool success)
-{
- ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
- int ret = sem_post(&wakeup_sem);
- if (ret < 0) {
- char buf[80];
- strerror_r(errno, buf, sizeof(buf));
- ALOGE("Error posting wakeup sem: %s\n", buf);
+class WakeupCallback : public ISystemSuspendCallback {
+public:
+ Return<void> notifyWakeup(bool success) override {
+ ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted");
+ int ret = sem_post(&wakeup_sem);
+ if (ret < 0) {
+ char buf[80];
+ strerror_r(errno, buf, sizeof(buf));
+ ALOGE("Error posting wakeup sem: %s\n", buf);
+ }
+ return Void();
}
-}
+};
static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf)
{
@@ -101,11 +108,14 @@
return -1;
}
ALOGV("Registering callback...");
- autosuspend_set_wakeup_callback(&wakeup_callback);
+ sp<ISystemSuspend> suspendHal = getSuspendHal();
+ suspendHal->registerCallback(new WakeupCallback());
}
// Wait for wakeup.
ALOGV("Waiting for wakeup...");
+ // TODO(b/116747600): device can suspend and wakeup after sem_wait() finishes and before wakeup
+ // reason is recorded, i.e. BatteryStats might occasionally miss wakeup events.
int ret = sem_wait(&wakeup_sem);
if (ret < 0) {
char buf[80];
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index b2d35d4..0c9b5f4 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -19,6 +19,7 @@
//#define LOG_NDEBUG 0
#include <android/hardware/power/1.1/IPower.h>
+#include <android/system/suspend/1.0/ISystemSuspend.h>
#include <nativehelper/JNIHelp.h>
#include "jni.h"
@@ -35,7 +36,7 @@
#include <utils/Log.h>
#include <hardware/power.h>
#include <hardware_legacy/power.h>
-#include <suspend/autosuspend.h>
+#include <hidl/ServiceManagement.h>
#include "com_android_server_power_PowerManagerService.h"
@@ -44,6 +45,9 @@
using android::hardware::power::V1_0::PowerHint;
using android::hardware::power::V1_0::Feature;
using android::String8;
+using android::system::suspend::V1_0::ISystemSuspend;
+using android::system::suspend::V1_0::IWakeLock;
+using android::system::suspend::V1_0::WakeLockType;
using IPowerV1_1 = android::hardware::power::V1_1::IPower;
using IPowerV1_0 = android::hardware::power::V1_0::IPower;
@@ -171,6 +175,46 @@
}
}
+static sp<ISystemSuspend> gSuspendHal = nullptr;
+static sp<IWakeLock> gSuspendBlocker = nullptr;
+static std::mutex gSuspendMutex;
+
+// Assume SystemSuspend HAL is always alive.
+// TODO: Force device to restart if SystemSuspend HAL dies.
+sp<ISystemSuspend> getSuspendHal() {
+ static std::once_flag suspendHalFlag;
+ std::call_once(suspendHalFlag, [](){
+ ::android::hardware::details::waitForHwService(ISystemSuspend::descriptor, "default");
+ gSuspendHal = ISystemSuspend::getService();
+ assert(gSuspendHal != nullptr);
+ });
+ return gSuspendHal;
+}
+
+void enableAutoSuspend() {
+ static bool enabled = false;
+
+ std::lock_guard<std::mutex> lock(gSuspendMutex);
+ if (!enabled) {
+ sp<ISystemSuspend> suspendHal = getSuspendHal();
+ suspendHal->enableAutosuspend();
+ enabled = true;
+ }
+ if (gSuspendBlocker) {
+ gSuspendBlocker->release();
+ gSuspendBlocker.clear();
+ }
+}
+
+void disableAutoSuspend() {
+ std::lock_guard<std::mutex> lock(gSuspendMutex);
+ if (!gSuspendBlocker) {
+ sp<ISystemSuspend> suspendHal = getSuspendHal();
+ gSuspendBlocker = suspendHal->acquireWakeLock(WakeLockType::PARTIAL,
+ "PowerManager.SuspendLockout");
+ }
+}
+
// ----------------------------------------------------------------------------
static void nativeInit(JNIEnv* env, jobject obj) {
@@ -207,13 +251,13 @@
static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
if (enable) {
android::base::Timer t;
- autosuspend_enable();
+ enableAutoSuspend();
if (t.duration() > 100ms) {
ALOGD("Excessive delay in autosuspend_enable() while turning screen off");
}
} else {
android::base::Timer t;
- autosuspend_disable();
+ disableAutoSuspend();
if (t.duration() > 100ms) {
ALOGD("Excessive delay in autosuspend_disable() while turning screen on");
}
diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java
index f7bf393..5a73a4e 100644
--- a/services/net/java/android/net/util/SharedLog.java
+++ b/services/net/java/android/net/util/SharedLog.java
@@ -17,6 +17,7 @@
package android.net.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -92,10 +93,17 @@
}
/**
- * Log an error due to an exception, with the exception stacktrace.
+ * Log an error due to an exception, with the exception stacktrace if provided.
+ *
+ * <p>The error and exception message appear in the shared log, but the stacktrace is only
+ * logged in general log output (logcat).
*/
- public void e(@NonNull String msg, @NonNull Throwable e) {
- Log.e(mTag, record(Category.ERROR, msg + ": " + e.getMessage()), e);
+ public void e(@NonNull String msg, @Nullable Throwable exception) {
+ if (exception == null) {
+ e(msg);
+ return;
+ }
+ Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
}
public void i(String msg) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 096cf37..08bc9bc 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -141,6 +141,8 @@
* The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to
* Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_REQUEST_HANDOVER =
"android.telecom.event.REQUEST_HANDOVER";
@@ -149,6 +151,8 @@
* Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the
* {@link PhoneAccountHandle} to which a call should be handed over to.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE =
"android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE";
@@ -161,6 +165,8 @@
* {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and
* {@link VideoProfile#STATE_TX_ENABLED}.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EXTRA_HANDOVER_VIDEO_STATE =
"android.telecom.extra.HANDOVER_VIDEO_STATE";
@@ -176,6 +182,8 @@
* {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}
* is called to initate the handover.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS";
@@ -186,6 +194,8 @@
* <p>
* A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_HANDOVER_COMPLETE =
"android.telecom.event.HANDOVER_COMPLETE";
@@ -198,6 +208,8 @@
* <p>
* A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED =
"android.telecom.event.HANDOVER_SOURCE_DISCONNECTED";
@@ -209,6 +221,8 @@
* <p>
* A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_HANDOVER_FAILED =
"android.telecom.event.HANDOVER_FAILED";
@@ -434,8 +448,15 @@
*/
public static final int PROPERTY_RTT = 0x00000400;
+ /**
+ * Indicates that the call has been identified as the network as an emergency call. This
+ * property may be set for both incoming and outgoing calls which the network identifies as
+ * emergency calls.
+ */
+ public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800;
+
//******************************************************************************************
- // Next PROPERTY value: 0x00000800
+ // Next PROPERTY value: 0x00001000
//******************************************************************************************
private final String mTelecomCallId;
@@ -601,6 +622,9 @@
if(hasProperty(properties, PROPERTY_ASSISTED_DIALING_USED)) {
builder.append(" PROPERTY_ASSISTED_DIALING_USED");
}
+ if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
+ builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL");
+ }
builder.append("]");
return builder.toString();
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 330db28..ee1ca5f 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -413,6 +413,13 @@
*/
public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9;
+ /**
+ * Set by the framework to indicate that the network has identified a Connection as an emergency
+ * call.
+ * @hide
+ */
+ public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1 << 10;
+
//**********************************************************************************************
// Next PROPERTY value: 1<<10
//**********************************************************************************************
@@ -586,6 +593,8 @@
* {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has
* successfully completed.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_HANDOVER_COMPLETE =
"android.telecom.event.HANDOVER_COMPLETE";
@@ -595,6 +604,8 @@
* {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed
* to complete.
* @hide
+ * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated
+ * APIs instead.
*/
public static final String EVENT_HANDOVER_FAILED =
"android.telecom.event.HANDOVER_FAILED";
@@ -802,6 +813,10 @@
builder.append(isLong ? " PROPERTY_IS_RTT" : " rtt");
}
+ if (can(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) {
+ builder.append(isLong ? " PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL" : " ecall");
+ }
+
builder.append("]");
return builder.toString();
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index b747dce3..8c37a21 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1884,6 +1884,27 @@
}
}
+ /**
+ * Determines if there is an ongoing emergency call. This can be either an outgoing emergency
+ * call, as identified by the dialed number, or because a call was identified by the network
+ * as an emergency call.
+ * @return {@code true} if there is an ongoing emergency call, {@code false} otherwise.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public boolean isInEmergencyCall() {
+ try {
+ if (isServiceConnected()) {
+ return getTelecomService().isInEmergencyCall();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException isInEmergencyCall: " + e);
+ return false;
+ }
+ return false;
+ }
+
private ITelecomService getTelecomService() {
if (mTelecomServiceOverride != null) {
return mTelecomServiceOverride;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index b4e7d56..38247bc 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -279,4 +279,9 @@
* @see TelecomServiceImpl#acceptHandover
*/
void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
+
+ /**
+ * @see TelecomServiceImpl#isInEmergencyCall
+ */
+ boolean isInEmergencyCall();
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 2d1b6ad..82808fc 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -271,6 +271,14 @@
KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
/**
+ * Do only allow auto selection in Advanced Network Settings when in home network.
+ * Manual selection is allowed when in roaming network.
+ * @hide
+ */
+ public static final String
+ KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network";
+
+ /**
* Control whether users receive a simplified network settings UI and improved network
* selection.
*/
@@ -2116,6 +2124,16 @@
public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING =
"call_redirection_service_component_name_string";
+ /**
+ * Flag specifying whether to show notification(call blocking disabled) when Enhanced Call
+ * Blocking(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL) is enabled and making emergency call.
+ * When true, notification is shown always.
+ * When false, notification is shown only when any setting of "Enhanced Blocked number" is
+ * enabled.
+ */
+ public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL =
+ "show_call_blocking_disabled_notification_always_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -2172,6 +2190,7 @@
sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true);
sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false);
+ sDefaults.putBoolean(KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL, false);
sDefaults.putBoolean(KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false);
@@ -2454,6 +2473,7 @@
});
sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "");
sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false);
+ sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false);
}
/**
diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java
new file mode 100644
index 0000000..e373797
--- /dev/null
+++ b/telephony/java/android/telephony/MbmsGroupCallSession.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2018 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.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.mbms.GroupCall;
+import android.telephony.mbms.GroupCallCallback;
+import android.telephony.mbms.InternalGroupCallCallback;
+import android.telephony.mbms.InternalGroupCallSessionCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsGroupCallSessionCallback;
+import android.telephony.mbms.MbmsUtils;
+import android.telephony.mbms.vendor.IMbmsGroupCallService;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * This class provides functionality for accessing group call functionality over MBMS.
+ */
+public class MbmsGroupCallSession implements AutoCloseable {
+ private static final String LOG_TAG = "MbmsGroupCallSession";
+
+ /**
+ * Service action which must be handled by the middleware implementing the MBMS group call
+ * interface.
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String MBMS_GROUP_CALL_SERVICE_ACTION =
+ "android.telephony.action.EmbmsGroupCall";
+
+ /**
+ * Metadata key that specifies the component name of the service to bind to for group calls.
+ * @hide
+ */
+ @TestApi
+ public static final String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA =
+ "mbms-group-call-service-override";
+
+ private static AtomicBoolean sIsInitialized = new AtomicBoolean(false);
+
+ private AtomicReference<IMbmsGroupCallService> mService = new AtomicReference<>(null);
+ private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ sIsInitialized.set(false);
+ mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Received death notification");
+ }
+ };
+
+ private InternalGroupCallSessionCallback mInternalCallback;
+ private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>();
+
+ private final Context mContext;
+ private int mSubscriptionId;
+
+ /** @hide */
+ private MbmsGroupCallSession(Context context, Executor executor, int subscriptionId,
+ MbmsGroupCallSessionCallback callback) {
+ mContext = context;
+ mSubscriptionId = subscriptionId;
+ mInternalCallback = new InternalGroupCallSessionCallback(callback, executor);
+ }
+
+ /**
+ * Create a new {@link MbmsGroupCallSession} using the given subscription ID.
+ *
+ * You may only have one instance of {@link MbmsGroupCallSession} per UID. If you call this
+ * method while there is an active instance of {@link MbmsGroupCallSession} in your process
+ * (in other words, one that has not had {@link #close()} called on it), this method will
+ * throw an {@link IllegalStateException}. If you call this method in a different process
+ * running under the same UID, an error will be indicated via
+ * {@link MbmsGroupCallSessionCallback#onError(int, String)}.
+ *
+ * Note that initialization may fail asynchronously. If you wish to try again after you
+ * receive such an asynchronous error, you must call {@link #close()} on the instance of
+ * {@link MbmsGroupCallSession} that you received before calling this method again.
+ *
+ * @param context The {@link Context} to use.
+ * @param executor The executor on which you wish to execute callbacks.
+ * @param subscriptionId The subscription ID to use.
+ * @param callback A callback object on which you wish to receive results of asynchronous
+ * operations.
+ * @return An instance of {@link MbmsGroupCallSession}, or null if an error occurred.
+ */
+ public static @Nullable MbmsGroupCallSession create(@NonNull Context context,
+ @NonNull Executor executor, int subscriptionId,
+ final @NonNull MbmsGroupCallSessionCallback callback) {
+ if (!sIsInitialized.compareAndSet(false, true)) {
+ throw new IllegalStateException("Cannot create two instances of MbmsGroupCallSession");
+ }
+ MbmsGroupCallSession session = new MbmsGroupCallSession(context, executor,
+ subscriptionId, callback);
+
+ final int result = session.bindAndInitialize();
+ if (result != MbmsErrors.SUCCESS) {
+ sIsInitialized.set(false);
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(result, null);
+ }
+ });
+ return null;
+ }
+ return session;
+ }
+
+ /**
+ * Create a new {@link MbmsGroupCallSession} using the system default data subscription ID.
+ * See {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)}.
+ */
+ public static MbmsGroupCallSession create(@NonNull Context context,
+ @NonNull Executor executor, @NonNull MbmsGroupCallSessionCallback callback) {
+ return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback);
+ }
+
+ /**
+ * Terminates this instance. Also terminates
+ * any group calls spawned from this instance as if
+ * {@link GroupCall#close()} had been called on them. After this method returns,
+ * no further callbacks originating from the middleware will be enqueued on the provided
+ * instance of {@link MbmsGroupCallSessionCallback}, but callbacks that have already been
+ * enqueued will still be delivered.
+ *
+ * It is safe to call {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)} to
+ * obtain another instance of {@link MbmsGroupCallSession} immediately after this method
+ * returns.
+ *
+ * May throw an {@link IllegalStateException}
+ */
+ public void close() {
+ try {
+ IMbmsGroupCallService groupCallService = mService.get();
+ if (groupCallService == null) {
+ // Ignore and return, assume already disposed.
+ return;
+ }
+ groupCallService.dispose(mSubscriptionId);
+ for (GroupCall s : mKnownActiveGroupCalls) {
+ s.getCallback().stop();
+ }
+ mKnownActiveGroupCalls.clear();
+ } catch (RemoteException e) {
+ // Ignore for now
+ } finally {
+ mService.set(null);
+ sIsInitialized.set(false);
+ mInternalCallback.stop();
+ }
+ }
+
+ /**
+ * Starts the requested group call, reporting status to the indicated callback.
+ * Returns an object used to control that call.
+ *
+ * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+ *
+ * Asynchronous errors through the callback include any of the errors in
+ * {@link MbmsErrors.GeneralErrors}.
+ *
+ * @param executor The executor on which you wish to execute callbacks for this stream.
+ * @param tmgi The TMGI, an identifier for the group call you want to join.
+ * @param saiArray An array of SAIs for the group call that should be negotiated separately with
+ * the carrier.
+ * @param frequencyArray An array of frequencies for the group call that should be negotiated
+ * separately with the carrier.
+ * @param callback The callback that you want to receive information about the call on.
+ * @return An instance of {@link GroupCall} through which the call can be controlled.
+ * May be {@code null} if an error occurred.
+ */
+ public @Nullable GroupCall startGroupCall(@NonNull Executor executor, long tmgi, int[] saiArray,
+ int[] frequencyArray, @NonNull GroupCallCallback callback) {
+ IMbmsGroupCallService groupCallService = mService.get();
+ if (groupCallService == null) {
+ throw new IllegalStateException("Middleware not yet bound");
+ }
+
+ InternalGroupCallCallback serviceCallback = new InternalGroupCallCallback(
+ callback, executor);
+
+ GroupCall serviceForApp = new GroupCall(mSubscriptionId,
+ groupCallService, this, tmgi, serviceCallback);
+ mKnownActiveGroupCalls.add(serviceForApp);
+
+ try {
+ int returnCode = groupCallService.startGroupCall(
+ mSubscriptionId, tmgi, saiArray, frequencyArray, serviceCallback);
+ if (returnCode == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return an unknown error code");
+ }
+ if (returnCode != MbmsErrors.SUCCESS) {
+ mInternalCallback.onError(returnCode, null);
+ return null;
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Remote process died");
+ mService.set(null);
+ sIsInitialized.set(false);
+ mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+ return null;
+ }
+
+ return serviceForApp;
+ }
+
+ /** @hide */
+ public void onGroupCallStopped(GroupCall service) {
+ mKnownActiveGroupCalls.remove(service);
+ }
+
+ private int bindAndInitialize() {
+ return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION,
+ new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IMbmsGroupCallService groupCallService =
+ IMbmsGroupCallService.Stub.asInterface(service);
+ int result;
+ try {
+ result = groupCallService.initialize(mInternalCallback,
+ mSubscriptionId);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Service died before initialization");
+ mInternalCallback.onError(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Runtime exception during initialization");
+ mInternalCallback.onError(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ }
+ if (result == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return"
+ + " an unknown error code");
+ }
+ if (result != MbmsErrors.SUCCESS) {
+ mInternalCallback.onError(result,
+ "Error returned during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ try {
+ groupCallService.asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware lost during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ mService.set(groupCallService);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ sIsInitialized.set(false);
+ mService.set(null);
+ }
+ });
+ }
+}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 8e99518..5e4518f 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -32,7 +32,11 @@
/**
* Represents the neighboring cell information, including
* Received Signal Strength and Cell ID location.
+ *
+ * @deprecated This class should not be used by anyone targeting SDK level 29 (Q) or higher.
+ * Instead callers should use {@Link android.telephony.CellInfo}.
*/
+@Deprecated
public class NeighboringCellInfo implements Parcelable
{
/**
diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java
index 7c7d7a0..202da68 100644
--- a/telephony/java/android/telephony/NetworkScan.java
+++ b/telephony/java/android/telephony/NetworkScan.java
@@ -16,11 +16,10 @@
package android.telephony;
+import android.annotation.IntDef;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.annotation.IntDef;
-import android.util.Log;
import com.android.internal.telephony.ITelephony;
@@ -113,6 +112,8 @@
}
try {
telephony.stopNetworkScan(mSubId, mScanId);
+ } catch (IllegalArgumentException ex) {
+ Rlog.d(TAG, "stopNetworkScan - no active scan for ScanID=" + mScanId);
} catch (RemoteException ex) {
Rlog.e(TAG, "stopNetworkScan RemoteException", ex);
} catch (RuntimeException ex) {
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index ec26622..22c1e58 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -33,11 +33,13 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* A Parcelable class for Subscription Information.
@@ -552,11 +554,49 @@
String cardIdToPrint = givePrintableIccid(mCardId);
return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
+ " displayName=" + mDisplayName + " carrierName=" + mCarrierName
- + " nameSource=" + mNameSource + " iconTint=" + mIconTint
+ + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber
+ " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
- + " mnc " + mMnc + " isEmbedded " + mIsEmbedded
+ + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
+ " accessRules " + Arrays.toString(mAccessRules)
+ " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
+ " parentSubId=" + mParentSubId + "}";
}
-}
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
+ mIsOpportunistic, mParentSubId, mIccId, mNumber, mMcc, mMnc, mCountryIso,
+ mCardId, mDisplayName, mCarrierName, mAccessRules);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (obj == this) return true;
+
+ SubscriptionInfo toCompare;
+ try {
+ toCompare = (SubscriptionInfo) obj;
+ } catch (ClassCastException ex) {
+ return false;
+ }
+
+ return mId == toCompare.mId
+ && mSimSlotIndex == toCompare.mSimSlotIndex
+ && mNameSource == toCompare.mNameSource
+ && mIconTint == toCompare.mIconTint
+ && mDataRoaming == toCompare.mDataRoaming
+ && mIsEmbedded == toCompare.mIsEmbedded
+ && mIsOpportunistic == toCompare.mIsOpportunistic
+ && mParentSubId == toCompare.mParentSubId
+ && Objects.equals(mIccId, toCompare.mIccId)
+ && Objects.equals(mNumber, toCompare.mNumber)
+ && Objects.equals(mMcc, toCompare.mMcc)
+ && Objects.equals(mMnc, toCompare.mMnc)
+ && Objects.equals(mCountryIso, toCompare.mCountryIso)
+ && Objects.equals(mCardId, toCompare.mCardId)
+ && TextUtils.equals(mDisplayName, toCompare.mDisplayName)
+ && TextUtils.equals(mCarrierName, toCompare.mCarrierName)
+ && Arrays.equals(mAccessRules, toCompare.mAccessRules);
+ }
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 8f7993c..3ef80c2 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1847,6 +1847,19 @@
}
/**
+ * Checks if the supplied subscription ID corresponds to an active subscription.
+ *
+ * @param subscriptionId the subscription ID.
+ * @return {@code true} if the supplied subscription ID corresponds to an active subscription;
+ * {@code false} if it does not correspond to an active subscription; or throw a
+ * SecurityException if the caller hasn't got the right permission.
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ public boolean isActiveSubscriptionId(int subscriptionId) {
+ return isActiveSubId(subscriptionId);
+ }
+
+ /**
* @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription
* and the SIM providing the subscription is present in a slot and in "LOADED" state.
* @hide
@@ -1856,7 +1869,7 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- return iSub.isActiveSubId(subId);
+ return iSub.isActiveSubId(subId, mContext.getOpPackageName());
}
} catch (RemoteException ex) {
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3ef5a4a..f83ea68 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,6 +16,8 @@
package android.telephony;
+import static android.content.Context.TELECOM_SERVICE;
+
import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.IntDef;
@@ -1577,6 +1579,7 @@
*
* @return List of NeighboringCellInfo or null if info unavailable.
*
+ * @removed
* @deprecated Use {@link #getAllCellInfo} which returns a superset of the information
* from NeighboringCellInfo, including LTE cell information.
*/
@@ -2089,10 +2092,37 @@
/** Max network type number. Update as new types are added. Don't add negative types. {@hide} */
public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_LTE_CA;
+
+ /** @hide */
+ @IntDef({
+ NETWORK_TYPE_UNKNOWN,
+ NETWORK_TYPE_GPRS,
+ NETWORK_TYPE_EDGE,
+ NETWORK_TYPE_UMTS,
+ NETWORK_TYPE_CDMA,
+ NETWORK_TYPE_EVDO_0,
+ NETWORK_TYPE_EVDO_A,
+ NETWORK_TYPE_1xRTT,
+ NETWORK_TYPE_HSDPA,
+ NETWORK_TYPE_HSUPA,
+ NETWORK_TYPE_HSPA,
+ NETWORK_TYPE_IDEN,
+ NETWORK_TYPE_EVDO_B,
+ NETWORK_TYPE_LTE,
+ NETWORK_TYPE_EHRPD,
+ NETWORK_TYPE_HSPAP,
+ NETWORK_TYPE_GSM,
+ NETWORK_TYPE_TD_SCDMA,
+ NETWORK_TYPE_IWLAN,
+ NETWORK_TYPE_LTE_CA,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NetworkType{}
+
/**
* @return the NETWORK_TYPE_xxxx for current data connection.
*/
- public int getNetworkType() {
+ public @NetworkType int getNetworkType() {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
@@ -2137,24 +2167,24 @@
* @hide
*/
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- @UnsupportedAppUsage
- public int getNetworkType(int subId) {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName());
- } else {
- // This can happen when the ITelephony interface is not up yet.
- return NETWORK_TYPE_UNKNOWN;
- }
- } catch(RemoteException ex) {
- // This shouldn't happen in the normal case
- return NETWORK_TYPE_UNKNOWN;
- } catch (NullPointerException ex) {
- // This could happen before phone restarts due to crashing
- return NETWORK_TYPE_UNKNOWN;
- }
- }
+ @UnsupportedAppUsage
+ public int getNetworkType(int subId) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName());
+ } else {
+ // This can happen when the ITelephony interface is not up yet.
+ return NETWORK_TYPE_UNKNOWN;
+ }
+ } catch (RemoteException ex) {
+ // This shouldn't happen in the normal case
+ return NETWORK_TYPE_UNKNOWN;
+ } catch (NullPointerException ex) {
+ // This could happen before phone restarts due to crashing
+ return NETWORK_TYPE_UNKNOWN;
+ }
+ }
/**
* Returns a constant indicating the radio technology (network type)
@@ -2187,7 +2217,7 @@
*/
@SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- public int getDataNetworkType() {
+ public @NetworkType int getDataNetworkType() {
return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
}
@@ -2227,7 +2257,7 @@
*/
@SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- public int getVoiceNetworkType() {
+ public @NetworkType int getVoiceNetworkType() {
return getVoiceNetworkType(getSubId());
}
@@ -4139,11 +4169,16 @@
}
/**
- * Returns the IMS home network domain name that was loaded from the ISIM.
- * @return the IMS domain name, or null if not present or not loaded
+ * Returns the IMS home network domain name that was loaded from the ISIM {@see #APPTYPE_ISIM}.
+ * @return the IMS domain name. Returns {@code null} if ISIM hasn't been loaded or IMS domain
+ * hasn't been loaded or isn't present on the ISIM.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getIsimDomain() {
try {
IPhoneSubInfo info = getSubscriberInfo();
@@ -4371,7 +4406,7 @@
* @hide
*/
private ITelecomService getTelecomService() {
- return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
+ return ITelecomService.Stub.asInterface(ServiceManager.getService(TELECOM_SERVICE));
}
private ITelephonyRegistry getTelephonyRegistry() {
@@ -5397,7 +5432,19 @@
}
}
- // ICC SIM Application Types
+ /**
+ * UICC SIM Application Types
+ * @hide
+ */
+ @IntDef(prefix = { "APPTYPE_" }, value = {
+ APPTYPE_SIM,
+ APPTYPE_USIM,
+ APPTYPE_RUIM,
+ APPTYPE_CSIM,
+ APPTYPE_ISIM
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UiccAppType{}
/** UICC application type is SIM */
public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM;
/** UICC application type is USIM */
@@ -5408,6 +5455,7 @@
public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM;
/** UICC application type is ISIM */
public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM;
+
// authContext (parameter P2) when doing UICC challenge,
// per 3GPP TS 31.102 (Section 7.1.2)
/** Authentication type for UICC challenge is EAP SIM. See RFC 4186 for details. */
@@ -5674,6 +5722,203 @@
}
}
+ /** @hide */
+ @IntDef(prefix = { "NETWORK_MODE_" }, value = {
+ NETWORK_MODE_WCDMA_PREF,
+ NETWORK_MODE_GSM_ONLY,
+ NETWORK_MODE_WCDMA_ONLY,
+ NETWORK_MODE_GSM_UMTS,
+ NETWORK_MODE_CDMA_EVDO,
+ NETWORK_MODE_CDMA_NO_EVDO,
+ NETWORK_MODE_EVDO_NO_CDMA,
+ NETWORK_MODE_GLOBAL,
+ NETWORK_MODE_LTE_CDMA_EVDO,
+ NETWORK_MODE_LTE_GSM_WCDMA,
+ NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA,
+ NETWORK_MODE_LTE_ONLY,
+ NETWORK_MODE_LTE_WCDMA,
+ NETWORK_MODE_TDSCDMA_ONLY,
+ NETWORK_MODE_TDSCDMA_WCDMA,
+ NETWORK_MODE_LTE_TDSCDMA,
+ NETWORK_MODE_TDSCDMA_GSM,
+ NETWORK_MODE_LTE_TDSCDMA_GSM,
+ NETWORK_MODE_TDSCDMA_GSM_WCDMA,
+ NETWORK_MODE_LTE_TDSCDMA_WCDMA,
+ NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA,
+ NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA,
+ NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PrefNetworkMode{}
+
+ /**
+ * network mode is GSM/WCDMA (WCDMA preferred).
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF;
+
+ /**
+ * network mode is GSM only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY;
+
+ /**
+ * network mode is WCDMA only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY;
+
+ /**
+ * network mode is GSM/WCDMA (auto mode, according to PRL).
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS;
+
+ /**
+ * network mode is CDMA and EvDo (auto mode, according to PRL).
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA;
+
+ /**
+ * network mode is CDMA only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO;
+
+ /**
+ * network mode is EvDo only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA;
+
+ /**
+ * network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL).
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL;
+
+ /**
+ * network mode is LTE, CDMA and EvDo.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO;
+
+ /**
+ * preferred network mode is LTE, GSM/WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA;
+
+ /**
+ * network mode is LTE, CDMA, EvDo, GSM/WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA =
+ RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA;
+
+ /**
+ * network mode is LTE Only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY;
+
+ /**
+ * network mode is LTE/WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA only.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY;
+
+ /**
+ * network mode is TD-SCDMA and WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA and LTE.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA;
+
+ /**
+ * network mode is TD-SCDMA and GSM.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM;
+
+ /**
+ * network mode is TD-SCDMA,GSM and LTE.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_TDSCDMA_GSM =
+ RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM;
+
+ /**
+ * network mode is TD-SCDMA, GSM/WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA =
+ RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA, WCDMA and LTE.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA =
+ RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA, GSM/WCDMA and LTE.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA =
+ RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
+ RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+
+ /**
+ * network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo.
+ * @hide
+ */
+ @SystemApi
+ public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA =
+ RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA;
+
/**
* Get the preferred network type.
* Used for device configuration by some CDMA operators.
@@ -5682,11 +5927,12 @@
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
- * @return the preferred network type, defined in RILConstants.java.
+ * @return the preferred network type.
* @hide
*/
- @UnsupportedAppUsage
- public int getPreferredNetworkType(int subId) {
+ @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
+ @SystemApi
+ public @PrefNetworkMode int getPreferredNetworkType(int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null)
@@ -6268,7 +6514,7 @@
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead.
+ * @removed Use {@link android.telecom.TelecomManager#endCall()} instead.
* @hide
* @removed
*/
@@ -6280,7 +6526,7 @@
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
+ * @removed Use {@link android.telecom.TelecomManager#acceptRingingCall} instead
* @hide
* @removed
*/
@@ -6288,26 +6534,22 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void answerRingingCall() {
-
+ // No-op
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#silenceRinger} instead
+ * @removed Use {@link android.telecom.TelecomManager#silenceRinger} instead
* @hide
*/
@Deprecated
@SystemApi
@SuppressLint("Doclava125")
public void silenceRinger() {
- try {
- getTelecomService().silenceRinger(getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecomService#silenceRinger", e);
- }
+ // No-op
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead
+ * @removed Use {@link android.telecom.TelecomManager#isInCall} instead
* @hide
*/
@Deprecated
@@ -6317,18 +6559,11 @@
android.Manifest.permission.READ_PHONE_STATE
})
public boolean isOffhook() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.isOffhook(getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#isOffhook", e);
- }
return false;
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#isRinging} instead
+ * @removed Use {@link android.telecom.TelecomManager#isRinging} instead
* @hide
*/
@Deprecated
@@ -6338,18 +6573,11 @@
android.Manifest.permission.READ_PHONE_STATE
})
public boolean isRinging() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.isRinging(getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#isRinging", e);
- }
return false;
}
/**
- * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead
+ * @removed Use {@link android.telecom.TelecomManager#isInCall} instead
* @hide
*/
@Deprecated
@@ -6359,13 +6587,6 @@
android.Manifest.permission.READ_PHONE_STATE
})
public boolean isIdle() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- return telephony.isIdle(getOpPackageName());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#isIdle", e);
- }
return true;
}
@@ -7851,26 +8072,23 @@
}
/**
- * Return the application ID for the app type like {@link APPTYPE_CSIM}.
+ * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}.
+ * All uicc applications are uniquely identified by application ID. See ETSI 102.221 and 101.220
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
*
- * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
- *
- * @param appType the uicc app type like {@link APPTYPE_CSIM}
- * @return Application ID for specificied app type or null if no uicc or error.
+ * @param appType the uicc app type.
+ * @return Application ID for specified app type or {@code null} if no uicc or error.
* @hide
*/
- public String getAidForAppType(int appType) {
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public String getAidForAppType(@UiccAppType int appType) {
return getAidForAppType(getSubId(), appType);
}
/**
- * Return the application ID for the app type like {@link APPTYPE_CSIM}.
- *
- * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission
- *
- * @param subId the subscription ID that this request applies to.
- * @param appType the uicc app type, like {@link APPTYPE_CSIM}
- * @return Application ID for specificied app type or null if no uicc or error.
+ * same as {@link #getAidForAppType(int)}
* @hide
*/
public String getAidForAppType(int subId, int appType) {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index df7bd3e..5d6a8c1 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -118,7 +118,9 @@
*/
public static final String EXTRA_CONFERENCE = "conference";
/**
- * @hide
+ * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an
+ * emergency call. The {@link ImsService} sets this on a call to indicate that the network has
+ * identified the call as an emergency call.
*/
public static final String EXTRA_E_CALL = "e_call";
/**
diff --git a/telephony/java/android/telephony/mbms/GroupCall.java b/telephony/java/android/telephony/mbms/GroupCall.java
new file mode 100644
index 0000000..9aca18e
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/GroupCall.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+import android.annotation.IntDef;
+import android.os.RemoteException;
+import android.telephony.MbmsGroupCallSession;
+import android.telephony.mbms.vendor.IMbmsGroupCallService;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Class used to represent a single MBMS group call. After a call has been started with
+ * {@link MbmsGroupCallSession#startGroupCall},
+ * this class is used to hold information about the call and control it.
+ */
+public class GroupCall implements AutoCloseable {
+ private static final String LOG_TAG = "MbmsGroupCall";
+
+ /**
+ * The state of a group call, reported via
+ * {@link GroupCallCallback#onGroupCallStateChanged(int, int)}
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED})
+ public @interface GroupCallState {}
+ public static final int STATE_STOPPED = 1;
+ public static final int STATE_STARTED = 2;
+ public static final int STATE_STALLED = 3;
+
+ /**
+ * The reason for a call state change, reported via
+ * {@link GroupCallCallback#onGroupCallStateChanged(int, int)}
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "REASON_" },
+ value = {REASON_BY_USER_REQUEST, REASON_FREQUENCY_CONFLICT,
+ REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE,
+ REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE})
+ public @interface GroupCallStateChangeReason {}
+
+ /**
+ * Indicates that the middleware does not have a reason to provide for the state change.
+ */
+ public static final int REASON_NONE = 0;
+
+ /**
+ * State changed due to a call to {@link #close()} or
+ * {@link MbmsGroupCallSession#startGroupCall}
+ */
+ public static final int REASON_BY_USER_REQUEST = 1;
+
+ // 2 is unused to match up with streaming.
+
+ /**
+ * State changed due to a frequency conflict with another requested call.
+ */
+ public static final int REASON_FREQUENCY_CONFLICT = 3;
+
+ /**
+ * State changed due to the middleware running out of memory
+ */
+ public static final int REASON_OUT_OF_MEMORY = 4;
+
+ /**
+ * State changed due to the device leaving the home carrier's LTE network.
+ */
+ public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5;
+
+ /**
+ * State changed due to the device leaving the area where this call is being broadcast.
+ */
+ public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6;
+
+ private final int mSubscriptionId;
+ private final long mTmgi;
+ private final MbmsGroupCallSession mParentSession;
+ private final InternalGroupCallCallback mCallback;
+ private IMbmsGroupCallService mService;
+
+ /**
+ * @hide
+ */
+ public GroupCall(int subscriptionId,
+ IMbmsGroupCallService service,
+ MbmsGroupCallSession session,
+ long tmgi,
+ InternalGroupCallCallback callback) {
+ mSubscriptionId = subscriptionId;
+ mParentSession = session;
+ mService = service;
+ mTmgi = tmgi;
+ mCallback = callback;
+ }
+
+ /**
+ * Retrieve the TMGI (Temporary Mobile Group Identity) corresponding to this call.
+ */
+ public long getTmgi() {
+ return mTmgi;
+ }
+
+ /**
+ * Send an update to the middleware when the SAI (Service Area Identifier) list and frequency
+ * information of the group call has * changed. Callers must obtain this information from the
+ * wireless carrier independently.
+ * @param saiArray New array of SAIs that the call is available on.
+ * @param frequencyArray New array of frequencies that the call is available on.
+ */
+ public void updateGroupCall(int[] saiArray, int[] frequencyArray) {
+ if (mService == null) {
+ throw new IllegalStateException("No group call service attached");
+ }
+
+ try {
+ mService.updateGroupCall(mSubscriptionId, mTmgi, saiArray, frequencyArray);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Remote process died");
+ mService = null;
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+ } finally {
+ mParentSession.onGroupCallStopped(this);
+ }
+ }
+
+ /**
+ * Stop this group call. Further operations on this object will fail with an
+ * {@link IllegalStateException}.
+ *
+ * May throw an {@link IllegalStateException}
+ */
+ @Override
+ public void close() {
+ if (mService == null) {
+ throw new IllegalStateException("No group call service attached");
+ }
+
+ try {
+ mService.stopGroupCall(mSubscriptionId, mTmgi);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Remote process died");
+ mService = null;
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null);
+ } finally {
+ mParentSession.onGroupCallStopped(this);
+ }
+ }
+
+ /** @hide */
+ public InternalGroupCallCallback getCallback() {
+ return mCallback;
+ }
+
+ private void sendErrorToApp(int errorCode, String message) {
+ mCallback.onError(errorCode, message);
+ }
+}
+
diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java
new file mode 100644
index 0000000..001bb02
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A callback class for use when the application is in a group call. The middleware
+ * will provide updates on the status of the call via this callback.
+ */
+public class GroupCallCallback {
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE,
+ MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND,
+ MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+ MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY,
+ MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+ MbmsErrors.GeneralErrors.ERROR_IN_E911,
+ MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+ MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+ MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" })
+ private @interface GroupCallError{}
+
+ /**
+ * Indicates broadcast signal strength is not available for this call.
+ *
+ * This may be due to the call no longer being available due to geography
+ * or timing (end of service)
+ */
+ public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1;
+
+ /**
+ * Called by the middleware when it has detected an error condition in this group call. The
+ * possible error codes are listed in {@link MbmsErrors}.
+ * @param errorCode The error code.
+ * @param message A human-readable message generated by the middleware for debugging purposes.
+ */
+ public void onError(@GroupCallError int errorCode, @Nullable String message) {
+ // default implementation empty
+ }
+
+ /**
+ * Called to indicate this call has changed state.
+ *
+ * See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED}
+ * and {@link GroupCall#STATE_STALLED}.
+ */
+ public void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
+ @GroupCall.GroupCallStateChangeReason int reason) {
+ // default implementation empty
+ }
+
+ /**
+ * Broadcast Signal Strength updated.
+ *
+ * This signal strength is the BROADCAST signal strength which,
+ * depending on technology in play and it's deployment, may be
+ * stronger or weaker than the traditional UNICAST signal
+ * strength. It a simple int from 0-4 for valid levels or
+ * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
+ * for this call due to timing, geography or popularity.
+ */
+ public void onBroadcastSignalStrengthUpdated(int signalStrength) {
+ // default implementation empty
+ }
+}
diff --git a/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl
new file mode 100755
index 0000000..844b634
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+/**
+ * @hide
+ */
+oneway interface IGroupCallCallback {
+ void onError(int errorCode, String message);
+ void onGroupCallStateChanged(int state, int reason);
+ void onBroadcastSignalStrengthUpdated(int signalStrength);
+}
diff --git a/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl
new file mode 100755
index 0000000..1a1c7f8
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl
@@ -0,0 +1,33 @@
+/*
+** Copyright 2018, 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.mbms;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+oneway interface IMbmsGroupCallSessionCallback
+{
+ void onError(int errorCode, String message);
+
+ void onAvailableSaisUpdated(in List currentSai, in List availableSais);
+
+ void onServiceInterfaceAvailable(String interfaceName, int index);
+
+ void onMiddlewareReady();
+}
diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java
new file mode 100644
index 0000000..2910bb3
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+import android.os.Binder;
+
+import java.util.concurrent.Executor;
+
+/** @hide */
+public class InternalGroupCallCallback extends IGroupCallCallback.Stub {
+ private final GroupCallCallback mAppCallback;
+ private final Executor mExecutor;
+ private volatile boolean mIsStopped = false;
+
+ public InternalGroupCallCallback(GroupCallCallback appCallback,
+ Executor executor) {
+ mAppCallback = appCallback;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onError(final int errorCode, final String message) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onError(errorCode, message);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onGroupCallStateChanged(final int state, final int reason) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onGroupCallStateChanged(state, reason);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onBroadcastSignalStrengthUpdated(final int signalStrength) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ /** Prevents this callback from calling the app */
+ public void stop() {
+ mIsStopped = true;
+ }
+}
diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java
new file mode 100644
index 0000000..4c9cf4d
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+import android.os.Binder;
+
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** @hide */
+public class InternalGroupCallSessionCallback extends IMbmsGroupCallSessionCallback.Stub {
+ private final Executor mExecutor;
+ private final MbmsGroupCallSessionCallback mAppCallback;
+ private volatile boolean mIsStopped = false;
+
+ public InternalGroupCallSessionCallback(MbmsGroupCallSessionCallback appCallback,
+ Executor executor) {
+ mAppCallback = appCallback;
+ mExecutor = executor;
+ }
+
+ @Override
+ public void onError(final int errorCode, final String message) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onError(errorCode, message);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onAvailableSaisUpdated(final List currentSais, final List availableSais) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onAvailableSaisUpdated(currentSais, availableSais);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onServiceInterfaceAvailable(final String interfaceName, final int index) {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onServiceInterfaceAvailable(interfaceName, index);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onMiddlewareReady() {
+ if (mIsStopped) {
+ return;
+ }
+
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ long token = Binder.clearCallingIdentity();
+ try {
+ mAppCallback.onMiddlewareReady();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+ });
+ }
+
+ /** Prevents this callback from calling the app */
+ public void stop() {
+ mIsStopped = true;
+ }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
new file mode 100644
index 0000000..7da734e
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 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.mbms;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.telephony.MbmsGroupCallSession;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * A callback class that is used to receive information from the middleware on MBMS group-call
+ * services. An instance of this object should be passed into
+ * {@link MbmsGroupCallSession#create(Context, Executor, int, MbmsGroupCallSessionCallback)}.
+ */
+public class MbmsGroupCallSessionCallback {
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE,
+ MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND,
+ MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED,
+ MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE,
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
+ MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY,
+ MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
+ MbmsErrors.GeneralErrors.ERROR_IN_E911,
+ MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
+ MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
+ MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" })
+ private @interface GroupCallError{}
+
+ /**
+ * Called by the middleware when it has detected an error condition. The possible error codes
+ * are listed in {@link MbmsErrors}.
+ * @param errorCode The error code.
+ * @param message A human-readable message generated by the middleware for debugging purposes.
+ */
+ public void onError(@GroupCallError int errorCode, @Nullable String message) {
+ }
+
+ /**
+ * Indicates that the list of currently available SAIs has been updated. The app may use this
+ * information to filter the list of group calls when displaying available group calls to
+ * the user by matching the SAIs with a list of group calls separately negotiated with the
+ * carrier. The app may also report the aggregate list of SAIs to the group call application
+ * server so that a network entity can determine when, and where to activate the broadcast of
+ * particular group calls.
+ * @param currentSais The available SAIs on the current cell.
+ * @param availableSais A list of lists of available SAIS in neighboring cells, where each list
+ * contains the available SAIs in an individual cell.
+ */
+ public void onAvailableSaisUpdated(List<Integer> currentSais,
+ List<List<Integer>> availableSais) {
+ }
+
+ /**
+ * Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied
+ * via this callback may be used to establish a data-link interface with the modem before the
+ * middleware is ready.
+ * Note that this method may be called before {@link #onMiddlewareReady()}.
+ *
+ * @param interfaceName The interface name for the data link.
+ * @param index The index for the data link.
+ */
+ public void onServiceInterfaceAvailable(String interfaceName, int index) {
+ }
+
+ /**
+ * Called to indicate that the middleware has been initialized and is ready.
+ *
+ * Before this method is called, calling any method on an instance of
+ * {@link MbmsGroupCallSession} will result in an {@link IllegalStateException} or an error
+ * delivered via {@link #onError(int, String)} with error code
+ * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
+ */
+ public void onMiddlewareReady() {
+ }
+}
diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java
index 06b2120..95b4d37 100644
--- a/telephony/java/android/telephony/mbms/MbmsUtils.java
+++ b/telephony/java/android/telephony/mbms/MbmsUtils.java
@@ -23,6 +23,7 @@
import android.content.pm.*;
import android.content.pm.ServiceInfo;
import android.telephony.MbmsDownloadSession;
+import android.telephony.MbmsGroupCallSession;
import android.telephony.MbmsStreamingSession;
import android.util.Log;
@@ -59,6 +60,9 @@
case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION:
metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA;
break;
+ case MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_ACTION:
+ metaDataKey = MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA;
+ break;
}
if (metaDataKey == null) {
return null;
diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl
new file mode 100755
index 0000000..721256a
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl
@@ -0,0 +1,39 @@
+/*
+** Copyright 2017, 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.mbms.vendor;
+
+import android.net.Uri;
+import android.telephony.mbms.IMbmsGroupCallSessionCallback;
+import android.telephony.mbms.IGroupCallCallback;
+
+/**
+ * @hide
+ */
+interface IMbmsGroupCallService
+{
+ int initialize(IMbmsGroupCallSessionCallback callback, int subId);
+
+ void stopGroupCall(int subId, long tmgi);
+
+ void updateGroupCall(int subscriptionId, long tmgi, in int[] saiArray,
+ in int[] frequencyArray);
+
+ int startGroupCall(int subscriptionId, long tmgi, in int[] saiArray,
+ in int[] frequencyArray, IGroupCallCallback callback);
+
+ void dispose(int subId);
+}
diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
new file mode 100644
index 0000000..3734ca7
--- /dev/null
+++ b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2018 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.mbms.vendor;
+
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.mbms.GroupCallCallback;
+import android.telephony.mbms.IGroupCallCallback;
+import android.telephony.mbms.IMbmsGroupCallSessionCallback;
+import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.MbmsGroupCallSessionCallback;
+import android.telephony.mbms.vendor.IMbmsGroupCallService.Stub;
+
+import java.util.List;
+
+/**
+ * Base class for MBMS group-call services. The middleware should override this class to implement
+ * its {@link Service} for group calls
+ * Subclasses should call this class's {@link #onBind} method to obtain an {@link IBinder} if they
+ * override {@link #onBind}.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class MbmsGroupCallServiceBase extends Service {
+ private final IBinder mInterface = new Stub() {
+ @Override
+ public int initialize(final IMbmsGroupCallSessionCallback callback,
+ final int subscriptionId) throws RemoteException {
+ if (callback == null) {
+ throw new NullPointerException("Callback must not be null");
+ }
+
+ final int uid = Binder.getCallingUid();
+
+ int result = MbmsGroupCallServiceBase.this.initialize(
+ new MbmsGroupCallSessionCallback() {
+ @Override
+ public void onError(final int errorCode, final String message) {
+ try {
+ if (errorCode == MbmsErrors.UNKNOWN) {
+ throw new IllegalArgumentException(
+ "Middleware cannot send an unknown error.");
+ }
+ callback.onError(errorCode, message);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+
+ @Override
+ public void onAvailableSaisUpdated(final List currentSais,
+ final List availableSais) {
+ try {
+ callback.onAvailableSaisUpdated(currentSais, availableSais);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+
+ @Override
+ public void onServiceInterfaceAvailable(final String interfaceName,
+ final int index) {
+ try {
+ callback.onServiceInterfaceAvailable(interfaceName, index);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+
+ @Override
+ public void onMiddlewareReady() {
+ try {
+ callback.onMiddlewareReady();
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+ }, subscriptionId);
+
+ if (result == MbmsErrors.SUCCESS) {
+ callback.asBinder().linkToDeath(new DeathRecipient() {
+ @Override
+ public void binderDied() {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }, 0);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void stopGroupCall(int subId, long tmgi) {
+ MbmsGroupCallServiceBase.this.stopGroupCall(subId, tmgi);
+ }
+
+ @Override
+ public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray,
+ int[] frequencyArray) {
+ MbmsGroupCallServiceBase.this.updateGroupCall(
+ subscriptionId, tmgi, saiArray, frequencyArray);
+ }
+
+ @Override
+ public int startGroupCall(final int subscriptionId, final long tmgi, final int[] saiArray,
+ final int[] frequencyArray, final IGroupCallCallback callback)
+ throws RemoteException {
+ if (callback == null) {
+ throw new NullPointerException("Callback must not be null");
+ }
+
+ final int uid = Binder.getCallingUid();
+
+ int result = MbmsGroupCallServiceBase.this.startGroupCall(
+ subscriptionId, tmgi, saiArray, frequencyArray, new GroupCallCallback() {
+ @Override
+ public void onError(final int errorCode, final String message) {
+ try {
+ if (errorCode == MbmsErrors.UNKNOWN) {
+ throw new IllegalArgumentException(
+ "Middleware cannot send an unknown error.");
+ }
+ callback.onError(errorCode, message);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+
+ public void onGroupCallStateChanged(int state, int reason) {
+ try {
+ callback.onGroupCallStateChanged(state, reason);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+
+ public void onBroadcastSignalStrengthUpdated(int signalStrength) {
+ try {
+ callback.onBroadcastSignalStrengthUpdated(signalStrength);
+ } catch (RemoteException e) {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }
+ });
+
+ if (result == MbmsErrors.SUCCESS) {
+ callback.asBinder().linkToDeath(new DeathRecipient() {
+ @Override
+ public void binderDied() {
+ onAppCallbackDied(uid, subscriptionId);
+ }
+ }, 0);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void dispose(int subId) throws RemoteException {
+ MbmsGroupCallServiceBase.this.dispose(subId);
+ }
+ };
+
+ /**
+ * Initialize the group call service for this app and subscription ID, registering the callback.
+ *
+ * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which
+ * will be intercepted and passed to the app as
+ * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE}
+ *
+ * May return any value from {@link MbmsErrors.InitializationErrors}
+ * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via
+ * {@link IMbmsGroupCallSessionCallback#onError(int, String)}.
+ *
+ * @param callback The callback to use to communicate with the app.
+ * @param subscriptionId The subscription ID to use.
+ */
+ public int initialize(MbmsGroupCallSessionCallback callback, int subscriptionId)
+ throws RemoteException {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Starts a particular group call. This method may perform asynchronous work. When
+ * the call is ready for consumption, the middleware should inform the app via
+ * {@link IGroupCallCallback#onGroupCallStateChanged(int, int)}.
+ *
+ * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException}
+ *
+ * @param subscriptionId The subscription id to use.
+ * @param tmgi The TMGI, an identifier for the group call.
+ * @param saiArray An array of SAIs for the group call.
+ * @param frequencyArray An array of frequencies for the group call.
+ * @param callback The callback object on which the app wishes to receive updates.
+ * @return Any error in {@link MbmsErrors.GeneralErrors}
+ */
+ public int startGroupCall(int subscriptionId, long tmgi, int[] saiArray, int[] frequencyArray,
+ GroupCallCallback callback) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Stop the group call identified by {@code tmgi}.
+ *
+ * The callback provided via {@link #startGroupCall} should no longer be
+ * used after this method has called by the app.
+ *
+ * May throw an {@link IllegalStateException}
+ *
+ * @param subscriptionId The subscription id to use.
+ * @param tmgi The TMGI for the call to stop.
+ */
+ public void stopGroupCall(int subscriptionId, long tmgi) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Called when the app receives new SAI and frequency information for the group call identified
+ * by {@code tmgi}.
+ * @param saiArray New array of SAIs that the call is available on.
+ * @param frequencyArray New array of frequencies that the call is available on.
+ */
+ public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray,
+ int[] frequencyArray) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Signals that the app wishes to dispose of the session identified by the
+ * {@code subscriptionId} argument and the caller's uid. No notification back to the
+ * app is required for this operation, and the corresponding callback provided via
+ * {@link #initialize} should no longer be used
+ * after this method has been called by the app.
+ *
+ * May throw an {@link IllegalStateException}
+ *
+ * @param subscriptionId The subscription id to use.
+ */
+ public void dispose(int subscriptionId) throws RemoteException {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ /**
+ * Indicates that the app identified by the given UID and subscription ID has died.
+ * @param uid the UID of the app, as returned by {@link Binder#getCallingUid()}.
+ * @param subscriptionId The subscription ID the app is using.
+ */
+ public void onAppCallbackDied(int uid, int subscriptionId) {
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mInterface;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 6521f0b..0ccd748 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -232,5 +232,5 @@
*/
int getSimStateForSlotIndex(int slotIndex);
- boolean isActiveSubId(int subId);
+ boolean isActiveSubId(int subId, String callingPackage);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index afb1d82..627dfaa 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -75,116 +75,6 @@
void call(String callingPackage, String number);
/**
- * End call if there is a call in progress, otherwise does nothing.
- *
- * @return whether it hung up
- */
- boolean endCall();
-
- /**
- * End call on particular subId or go to the Home screen
- * @param subId user preferred subId.
- * @return whether it hung up
- */
- boolean endCallForSubscriber(int subId);
-
- /**
- * Answer the currently-ringing call.
- *
- * If there's already a current active call, that call will be
- * automatically put on hold. If both lines are currently in use, the
- * current active call will be ended.
- *
- * TODO: provide a flag to let the caller specify what policy to use
- * if both lines are in use. (The current behavior is hardwired to
- * "answer incoming, end ongoing", which is how the CALL button
- * is specced to behave.)
- *
- * TODO: this should be a oneway call (especially since it's called
- * directly from the key queue thread).
- */
- void answerRingingCall();
-
- /**
- * Answer the currently-ringing call on particular subId .
- *
- * If there's already a current active call, that call will be
- * automatically put on hold. If both lines are currently in use, the
- * current active call will be ended.
- *
- * TODO: provide a flag to let the caller specify what policy to use
- * if both lines are in use. (The current behavior is hardwired to
- * "answer incoming, end ongoing", which is how the CALL button
- * is specced to behave.)
- *
- * TODO: this should be a oneway call (especially since it's called
- * directly from the key queue thread).
- */
- void answerRingingCallForSubscriber(int subId);
-
- /**
- * Silence the ringer if an incoming call is currently ringing.
- * (If vibrating, stop the vibrator also.)
- *
- * It's safe to call this if the ringer has already been silenced, or
- * even if there's no incoming call. (If so, this method will do nothing.)
- *
- * TODO: this should be a oneway call too (see above).
- * (Actually *all* the methods here that return void can
- * probably be oneway.)
- */
- void silenceRinger();
-
- /**
- * Check if we are in either an active or holding call
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is OFFHOOK.
- */
- boolean isOffhook(String callingPackage);
-
- /**
- * Check if a particular subId has an active or holding call
- *
- * @param subId user preferred subId.
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is OFFHOOK.
- */
- boolean isOffhookForSubscriber(int subId, String callingPackage);
-
- /**
- * Check if an incoming phone call is ringing or call waiting
- * on a particular subId.
- *
- * @param subId user preferred subId.
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is RINGING.
- */
- boolean isRingingForSubscriber(int subId, String callingPackage);
-
- /**
- * Check if an incoming phone call is ringing or call waiting.
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is RINGING.
- */
- boolean isRinging(String callingPackage);
-
- /**
- * Check if the phone is idle.
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is IDLE.
- */
- boolean isIdle(String callingPackage);
-
- /**
- * Check if the phone is idle on a particular subId.
- *
- * @param subId user preferred subId.
- * @param callingPackage the name of the package making the call.
- * @return true if the phone state is IDLE.
- */
- boolean isIdleForSubscriber(int subId, String callingPackage);
-
- /**
* Check to see if the radio is on or not.
* @param callingPackage the name of the package making the call.
* @return returns true if the radio is on.
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 6ce66f0..639ed7d 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -245,8 +245,14 @@
mIterationCycle = false;
// In the "applaunch.txt" file, trail launches is referenced using
// "TRIAL_LAUNCH"
- String appPkgName = mNameToIntent.get(launch.getApp())
- .getComponent().getPackageName();
+ Intent startIntent = mNameToIntent.get(launch.getApp());
+ if (startIntent == null) {
+ Log.w(TAG, "App does not exist: " + launch.getApp());
+ mResult.putString(mNameToResultKey.get(launch.getApp()),
+ "App does not exist");
+ continue;
+ }
+ String appPkgName = startIntent.getComponent().getPackageName();
if (SPEED_PROFILE_FILTER.equals(launch.getCompilerFilter())) {
assertTrue(String.format("Not able to compile the app : %s", appPkgName),
compileApp(VERIFY_FILTER, appPkgName));
diff --git a/tests/DexLoggerIntegrationTests/AndroidManifest.xml b/tests/DexLoggerIntegrationTests/AndroidManifest.xml
index a847e8f..a9f01ed 100644
--- a/tests/DexLoggerIntegrationTests/AndroidManifest.xml
+++ b/tests/DexLoggerIntegrationTests/AndroidManifest.xml
@@ -17,10 +17,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.dexloggertest">
- <!-- Tests feature introduced in P (27) -->
+ <!-- Tests feature introduced in P (28) -->
<uses-sdk
- android:minSdkVersion="27"
- android:targetSdkVersion="27" />
+ android:minSdkVersion="28"
+ android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.READ_LOGS" />
diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
index 39ecb7e5a..122edba 100644
--- a/tests/net/java/android/net/netlink/InetDiagSocketTest.java
+++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
@@ -69,17 +69,12 @@
private ConnectivityManager mCm;
private Context mContext;
private final static int SOCKET_TIMEOUT_MS = 100;
- private boolean mInetDiagUdpEnabled;
@Before
public void setUp() throws Exception {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
mContext = instrumentation.getTargetContext();
mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- int expectedUid = Process.myUid();
- UdpConnection udp = new UdpConnection("127.0.0.1", "127.0.0.2");
- int uid = mCm.getConnectionOwnerUid(udp.protocol, udp.local, udp.remote);
- mInetDiagUdpEnabled = (uid == expectedUid);
}
private class Connection {
@@ -188,11 +183,6 @@
tcp.close();
/**
- * TODO: STOPSHIP: Always test for UDP, do not allow opt-out.
- */
- if (!mInetDiagUdpEnabled) return;
-
- /**
* For UDP connections, either a complete match {protocol, local, remote} or a
* partial match {protocol, local} should return a valid UID.
*/
diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java
index d46facf..8604860 100644
--- a/tests/net/java/android/net/util/SharedLogTest.java
+++ b/tests/net/java/android/net/util/SharedLogTest.java
@@ -44,6 +44,8 @@
final SharedLog logLevel2a = logTop.forSubComponent("twoA");
final SharedLog logLevel2b = logTop.forSubComponent("twoB");
logLevel2b.e("2b or not 2b");
+ logLevel2b.e("No exception", null);
+ logLevel2b.e("Wait, here's one", new Exception("Test"));
logLevel2a.w("second post?");
final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
@@ -54,6 +56,9 @@
final String[] expected = {
" - MARK first post!",
" - [twoB] ERROR 2b or not 2b",
+ " - [twoB] ERROR No exception",
+ // No stacktrace in shared log, only in logcat
+ " - [twoB] ERROR Wait, here's one: Test",
" - [twoA] WARN second post?",
" - still logging",
" - [twoA.three] 3 >> 2",
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e3db7e8..1a05305 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -79,6 +79,7 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -248,7 +249,7 @@
@Spy private Resources mResources;
private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();
- MockContext(Context base) {
+ MockContext(Context base, ContentProvider settingsProvider) {
super(base);
mResources = spy(base.getResources());
@@ -260,7 +261,7 @@
});
mContentResolver = new MockContentResolver();
- mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider);
}
@Override
@@ -1048,7 +1049,9 @@
Looper.prepare();
}
- mServiceContext = new MockContext(InstrumentationRegistry.getContext());
+ FakeSettingsProvider.clearSettingsProvider();
+ mServiceContext = new MockContext(InstrumentationRegistry.getContext(),
+ new FakeSettingsProvider());
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
LocalServices.addService(
NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
@@ -1086,6 +1089,7 @@
mEthernetNetworkAgent.disconnect();
mEthernetNetworkAgent = null;
}
+ FakeSettingsProvider.clearSettingsProvider();
}
private static int transportToLegacyType(int transport) {
@@ -4532,4 +4536,78 @@
mCellNetworkAgent.disconnect();
mCm.unregisterNetworkCallback(networkCallback);
}
+
+ @Test
+ public void testDataActivityTracking() throws RemoteException {
+ final TestNetworkCallback networkCallback = new TestNetworkCallback();
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ mCm.registerNetworkCallback(networkRequest, networkCallback);
+
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ final LinkProperties cellLp = new LinkProperties();
+ cellLp.setInterfaceName(MOBILE_IFNAME);
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ reset(mNetworkManagementService);
+ mCellNetworkAgent.connect(true);
+ networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
+ eq(ConnectivityManager.TYPE_MOBILE));
+
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ final LinkProperties wifiLp = new LinkProperties();
+ wifiLp.setInterfaceName(WIFI_IFNAME);
+ mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+
+ // Network switch
+ reset(mNetworkManagementService);
+ mWiFiNetworkAgent.connect(true);
+ networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+ networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
+ eq(ConnectivityManager.TYPE_WIFI));
+ verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
+
+ // Disconnect wifi and switch back to cell
+ reset(mNetworkManagementService);
+ mWiFiNetworkAgent.disconnect();
+ networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+ assertNoCallbacks(networkCallback);
+ verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+ verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
+ eq(ConnectivityManager.TYPE_MOBILE));
+
+ // reconnect wifi
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ wifiLp.setInterfaceName(WIFI_IFNAME);
+ mWiFiNetworkAgent.sendLinkProperties(wifiLp);
+ mWiFiNetworkAgent.connect(true);
+ networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+ networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+
+ // Disconnect cell
+ reset(mNetworkManagementService);
+ mCellNetworkAgent.disconnect();
+ networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+ // LOST callback is triggered earlier than removing idle timer. Broadcast should also be
+ // sent as network being switched. Ensure rule removal for cell will not be triggered
+ // unexpectedly before network being removed.
+ waitForIdle();
+ verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
+ verify(mNetworkManagementService, times(1)).removeNetwork(
+ eq(mCellNetworkAgent.getNetwork().netId));
+
+ // Disconnect wifi
+ ConditionVariable cv = waitForConnectivityBroadcasts(1);
+ reset(mNetworkManagementService);
+ mWiFiNetworkAgent.disconnect();
+ waitFor(cv);
+ verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+
+ // Clean up
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
}
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 40d5544..a6ed9f2 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -33,6 +33,7 @@
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
+import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -75,6 +76,8 @@
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.RouteInfo;
+import android.net.dhcp.DhcpServer;
+import android.net.dhcp.DhcpServingParams;
import android.net.ip.IpServer;
import android.net.ip.RouterAdvertisementDaemon;
import android.net.util.InterfaceParams;
@@ -85,6 +88,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.INetworkManagementService;
+import android.os.Looper;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.test.TestLooper;
@@ -146,6 +150,7 @@
@Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor;
@Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator;
@Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon;
+ @Mock private DhcpServer mDhcpServer;
@Mock private INetd mNetd;
private final MockTetheringDependencies mTetheringDependencies =
@@ -240,6 +245,12 @@
public INetd getNetdService() {
return mNetd;
}
+
+ @Override
+ public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+ DhcpServingParams params, SharedLog log) {
+ return mDhcpServer;
+ }
};
}
@@ -333,6 +344,7 @@
mServiceContext = new MockContext(mContext);
mContentResolver = new MockContentResolver(mServiceContext);
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
mIntents = new Vector<>();
mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -343,12 +355,16 @@
mServiceContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(ACTION_TETHER_STATE_CHANGED));
mTetheringDependencies.reset();
- mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
- mLooper.getLooper(), mSystemProperties,
- mTetheringDependencies);
+ mTethering = makeTethering();
verify(mNMService).registerTetheringStatsProvider(any(), anyString());
}
+ private Tethering makeTethering() {
+ return new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
+ mLooper.getLooper(), mSystemProperties,
+ mTetheringDependencies);
+ }
+
@After
public void tearDown() {
mServiceContext.unregisterReceiver(mBroadcastReceiver);
@@ -597,6 +613,18 @@
sendIPv6TetherUpdates(upstreamState);
verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull());
+ verify(mDhcpServer, times(1)).start();
+ }
+
+ @Test
+ public void workingMobileUsbTethering_IPv4LegacyDhcp() {
+ Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
+ mTethering = makeTethering();
+ final NetworkState upstreamState = buildMobileIPv4UpstreamState();
+ runUsbTethering(upstreamState);
+ sendIPv6TetherUpdates(upstreamState);
+
+ verify(mDhcpServer, never()).start();
}
@Test
@@ -620,6 +648,7 @@
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
verify(mRouterAdvertisementDaemon, times(1)).start();
+ verify(mDhcpServer, times(1)).start();
sendIPv6TetherUpdates(upstreamState);
verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull());
@@ -633,6 +662,7 @@
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME);
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+ verify(mDhcpServer, times(1)).start();
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME,
TEST_XLAT_MOBILE_IFNAME);
@@ -649,6 +679,7 @@
runUsbTethering(upstreamState);
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+ verify(mDhcpServer, times(1)).start();
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
// Then 464xlat comes up
@@ -671,6 +702,8 @@
// Forwarding was not re-added for v6 (still times(1))
verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME);
+ // DHCP not restarted on downstream (still times(1))
+ verify(mDhcpServer, times(1)).start();
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
index bb31230..5217784 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -225,13 +225,4 @@
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
assertFalse(cfg.enableLegacyDhcpServer);
}
-
- @Test
- public void testNewDhcpServerDefault() {
- Settings.Global.putString(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, null);
-
- final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
- // TODO: change to false when new server is promoted to default
- assertTrue(cfg.enableLegacyDhcpServer);
- }
}
diff --git a/tools/aapt2/io/FileStream_test.cpp b/tools/aapt2/io/FileStream_test.cpp
index c0eaa8e..7872738 100644
--- a/tools/aapt2/io/FileStream_test.cpp
+++ b/tools/aapt2/io/FileStream_test.cpp
@@ -41,46 +41,46 @@
ASSERT_FALSE(in.HadError());
EXPECT_THAT(in.ByteCount(), Eq(0u));
- const char* buffer;
+ const void* buffer;
size_t size;
- ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError();
+ ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError();
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
EXPECT_THAT(in.ByteCount(), Eq(10u));
- EXPECT_THAT(StringPiece(buffer, size), Eq("this is a "));
+ EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a "));
- ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+ ASSERT_TRUE(in.Next(&buffer, &size));
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
EXPECT_THAT(in.ByteCount(), Eq(20u));
- EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
+ EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
in.BackUp(5u);
EXPECT_THAT(in.ByteCount(), Eq(15u));
- ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+ ASSERT_TRUE(in.Next(&buffer, &size));
ASSERT_THAT(size, Eq(5u));
ASSERT_THAT(buffer, NotNull());
ASSERT_THAT(in.ByteCount(), Eq(20u));
- EXPECT_THAT(StringPiece(buffer, size), Eq("strin"));
+ EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin"));
// Backup 1 more than possible. Should clamp.
in.BackUp(11u);
EXPECT_THAT(in.ByteCount(), Eq(10u));
- ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+ ASSERT_TRUE(in.Next(&buffer, &size));
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
ASSERT_THAT(in.ByteCount(), Eq(20u));
- EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
+ EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
- ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+ ASSERT_TRUE(in.Next(&buffer, &size));
ASSERT_THAT(size, Eq(1u));
ASSERT_THAT(buffer, NotNull());
ASSERT_THAT(in.ByteCount(), Eq(21u));
- EXPECT_THAT(StringPiece(buffer, size), Eq("g"));
+ EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g"));
- EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
+ EXPECT_FALSE(in.Next(&buffer, &size));
EXPECT_FALSE(in.HadError());
}
@@ -93,25 +93,25 @@
ASSERT_FALSE(out.HadError());
EXPECT_THAT(out.ByteCount(), Eq(0u));
- char* buffer;
+ void* buffer;
size_t size;
- ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+ ASSERT_TRUE(out.Next(&buffer, &size));
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
EXPECT_THAT(out.ByteCount(), Eq(10u));
- memcpy(buffer, input.c_str(), size);
+ memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size);
- ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+ ASSERT_TRUE(out.Next(&buffer, &size));
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
EXPECT_THAT(out.ByteCount(), Eq(20u));
- memcpy(buffer, input.c_str() + 10u, size);
+ memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size);
- ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
+ ASSERT_TRUE(out.Next(&buffer, &size));
ASSERT_THAT(size, Eq(10u));
ASSERT_THAT(buffer, NotNull());
EXPECT_THAT(out.ByteCount(), Eq(30u));
- buffer[0] = input[20u];
+ reinterpret_cast<char*>(buffer)[0] = input[20u];
out.BackUp(size - 1);
EXPECT_THAT(out.ByteCount(), Eq(21u));