Merge "Framework: Ensure image heap string literals for Patterns"
diff --git a/api/current.txt b/api/current.txt
index 0c202401..38e05a0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18725,6 +18725,8 @@
field public static final int SHORT_COMMONLY_USED = 6; // 0x6
field public static final int SHORT_GENERIC = 2; // 0x2
field public static final int SHORT_GMT = 4; // 0x4
+ field public static final int TIMEZONE_ICU = 0; // 0x0
+ field public static final int TIMEZONE_JDK = 1; // 0x1
field public static final android.icu.util.TimeZone UNKNOWN_ZONE;
field public static final java.lang.String UNKNOWN_ZONE_ID = "Etc/Unknown";
}
@@ -23642,6 +23644,7 @@
method public void reportNetworkConnectivity(android.net.Network, boolean);
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -23689,6 +23692,7 @@
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
method public void onLost(android.net.Network);
+ method public void onUnavailable();
}
public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -37014,9 +37018,9 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConference(android.telecom.Connection, android.telecom.Connection);
method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateIncomingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateOutgoingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
diff --git a/api/system-current.txt b/api/system-current.txt
index d6b6ad4a..51ef55c 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -19939,6 +19939,8 @@
field public static final int SHORT_COMMONLY_USED = 6; // 0x6
field public static final int SHORT_GENERIC = 2; // 0x2
field public static final int SHORT_GMT = 4; // 0x4
+ field public static final int TIMEZONE_ICU = 0; // 0x0
+ field public static final int TIMEZONE_JDK = 1; // 0x1
field public static final android.icu.util.TimeZone UNKNOWN_ZONE;
field public static final java.lang.String UNKNOWN_ZONE_ID = "Etc/Unknown";
}
@@ -25429,6 +25431,7 @@
method public void reportNetworkConnectivity(android.net.Network, boolean);
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -25482,6 +25485,7 @@
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
method public void onLost(android.net.Network);
+ method public void onUnavailable();
}
public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -39999,9 +40003,9 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConference(android.telecom.Connection, android.telecom.Connection);
method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateIncomingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateOutgoingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
diff --git a/api/test-current.txt b/api/test-current.txt
index 7aaab5ba..eda0860 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -18742,6 +18742,8 @@
field public static final int SHORT_COMMONLY_USED = 6; // 0x6
field public static final int SHORT_GENERIC = 2; // 0x2
field public static final int SHORT_GMT = 4; // 0x4
+ field public static final int TIMEZONE_ICU = 0; // 0x0
+ field public static final int TIMEZONE_JDK = 1; // 0x1
field public static final android.icu.util.TimeZone UNKNOWN_ZONE;
field public static final java.lang.String UNKNOWN_ZONE_ID = "Etc/Unknown";
}
@@ -23715,6 +23717,7 @@
method public void reportNetworkConnectivity(android.net.Network, boolean);
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -23762,6 +23765,7 @@
method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
method public void onLosing(android.net.Network, int);
method public void onLost(android.net.Network);
+ method public void onUnavailable();
}
public static abstract interface ConnectivityManager.OnNetworkActiveListener {
@@ -37096,9 +37100,9 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConference(android.telecom.Connection, android.telecom.Connection);
method public android.telecom.Connection onCreateIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateIncomingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateIncomingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public android.telecom.Connection onCreateOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
- method public void onCreateOutgoingConnectionFailed(android.telecom.ConnectionRequest);
+ method public void onCreateOutgoingConnectionFailed(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public void onRemoteConferenceAdded(android.telecom.RemoteConference);
method public void onRemoteExistingConnectionAdded(android.telecom.RemoteConnection);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.ConnectionService";
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 397e683..11d247b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1052,26 +1052,6 @@
}
/**
- * Request that this callback be invoked at ConnectivityService's earliest
- * convenience with the current satisfying network's LinkProperties.
- * If no such network exists no callback invocation is performed.
- *
- * The callback must have been registered with #requestNetwork() or
- * #registerDefaultNetworkCallback(); callbacks registered with
- * registerNetworkCallback() are not specific to any particular Network so
- * do not cause any updates.
- *
- * @hide
- */
- public void requestLinkProperties(NetworkCallback networkCallback) {
- try {
- mService.requestLinkProperties(networkCallback.networkRequest);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Get the {@link android.net.NetworkCapabilities} for the given {@link Network}. This
* will return {@code null} if the network is unknown.
* <p>This method requires the caller to hold the permission
@@ -1089,26 +1069,6 @@
}
/**
- * Request that this callback be invoked at ConnectivityService's earliest
- * convenience with the current satisfying network's NetworkCapabilities.
- * If no such network exists no callback invocation is performed.
- *
- * The callback must have been registered with #requestNetwork() or
- * #registerDefaultNetworkCallback(); callbacks registered with
- * registerNetworkCallback() are not specific to any particular Network so
- * do not cause any updates.
- *
- * @hide
- */
- public void requestNetworkCapabilities(NetworkCallback networkCallback) {
- try {
- mService.requestNetworkCapabilities(networkCallback.networkRequest);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Gets the URL that should be used for resolving whether a captive portal is present.
* 1. This URL should respond with a 204 response to a GET request to indicate no captive
* portal is present.
@@ -2647,10 +2607,12 @@
public void onLost(Network network) {}
/**
- * Called if no network is found in the given timeout time. If no timeout is given,
- * this will not be called. The associated {@link NetworkRequest} will have already
- * been removed and released, as if {@link #unregisterNetworkCallback} had been called.
- * @hide
+ * Called if no network is found in the timeout time specified in
+ * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)} call. This callback is not
+ * called for the version of {@link #requestNetwork(NetworkRequest, NetworkCallback)}
+ * without timeout. When this callback is invoked the associated
+ * {@link NetworkRequest} will have already been removed and released, as if
+ * {@link #unregisterNetworkCallback(NetworkCallback)} had been called.
*/
public void onUnavailable() {}
@@ -2884,14 +2846,11 @@
if (callback == null) {
throw new IllegalArgumentException("null NetworkCallback");
}
- if ((need == null) && (action != REQUEST)) {
+ if (need == null && action != REQUEST) {
throw new IllegalArgumentException("null NetworkCapabilities");
}
- final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
- if ((targetSdk > VERSION_CODES.N_MR1) && (callback.networkRequest != null)) {
- // http://b/20701525
- throw new IllegalArgumentException("NetworkCallback already registered");
- }
+ // TODO: throw an exception if callback.networkRequest is not null.
+ // http://b/20701525
final NetworkRequest request;
try {
synchronized(sCallbacks) {
@@ -2936,7 +2895,9 @@
* Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
*
* This {@link NetworkRequest} will live until released via
- * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits.
+ * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
+ * version of the method which takes a timeout is
+ * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
* Status of the request can be followed by listening to the various
* callbacks described in {@link NetworkCallback}. The {@link Network}
* can be used to direct traffic to the network.
@@ -2969,7 +2930,9 @@
* Request a network to satisfy a set of {@link android.net.NetworkCapabilities}.
*
* This {@link NetworkRequest} will live until released via
- * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits.
+ * {@link #unregisterNetworkCallback(NetworkCallback)} or the calling application exits. A
+ * version of the method which takes a timeout is
+ * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)}.
* Status of the request can be followed by listening to the various
* callbacks described in {@link NetworkCallback}. The {@link Network}
* can be used to direct traffic to the network.
@@ -3003,13 +2966,25 @@
}
/**
+ * Note: this is a deprecated version of
+ * {@link #requestNetwork(NetworkRequest, int, NetworkCallback)} - please transition code to use
+ * the unhidden version of the function.
+ * TODO: replace all callers with the new version of the API
+ *
* Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
* by a timeout.
*
- * This function behaves identically to the non-timedout version, but if a suitable
- * network is not found within the given time (in milliseconds) the
- * {@link NetworkCallback#onUnavailable()} callback is called. The request must
- * still be released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)}.
+ * This function behaves identically to the non-timed-out version
+ * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
+ * is not found within the given time (in milliseconds) the
+ * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
+ * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
+ * not have to be released if timed-out (it is automatically released). Unregistering a
+ * request that timed out is not an error.
+ *
+ * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
+ * timeout) - the {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
+ * for that purpose. Calling this method will attempt to bring up the requested network.
*
* <p>This method requires the caller to hold either the
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
@@ -3017,15 +2992,56 @@
* {@link android.provider.Settings.System#canWrite}.</p>
*
* @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
- * The callback is invoked on the default internal Handler.
+ * @param networkCallback The callbacks to be utilized for this request. Note
+ * the callbacks must not be shared - they uniquely specify
+ * this request.
* @param timeoutMs The time in milliseconds to attempt looking for a suitable network
- * before {@link NetworkCallback#onUnavailable()} is called.
+ * before {@link NetworkCallback#onUnavailable()} is called. The timeout must
+ * be a positive value (i.e. >0).
* @hide
*/
public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
int timeoutMs) {
+ if (timeoutMs <= 0) {
+ throw new IllegalArgumentException("Non-positive timeoutMs: " + timeoutMs);
+ }
+ int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
+ requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
+ }
+
+ /**
+ * Request a network to satisfy a set of {@link android.net.NetworkCapabilities}, limited
+ * by a timeout.
+ *
+ * This function behaves identically to the non-timed-out version
+ * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, but if a suitable network
+ * is not found within the given time (in milliseconds) the
+ * {@link NetworkCallback#onUnavailable()} callback is called. The request can still be
+ * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
+ * not have to be released if timed-out (it is automatically released). Unregistering a
+ * request that timed out is not an error.
+ *
+ * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
+ * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
+ * for that purpose. Calling this method will attempt to bring up the requested network.
+ *
+ * <p>This method requires the caller to hold either the
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
+ * or the ability to modify system settings as determined by
+ * {@link android.provider.Settings.System#canWrite}.</p>
+ *
+ * @param request {@link NetworkRequest} describing this request.
+ * @param timeoutMs The time in milliseconds to attempt looking for a suitable network
+ * before {@link NetworkCallback#onUnavailable()} is called. The timeout must
+ * be a positive value (i.e. >0).
+ * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
+ * the callback must not be shared - it uniquely specifies this request.
+ */
+ public void requestNetwork(NetworkRequest request, int timeoutMs,
+ NetworkCallback networkCallback) {
+ if (timeoutMs <= 0) {
+ throw new IllegalArgumentException("Non-positive timeoutMs: " + timeoutMs);
+ }
int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
requestNetwork(request, networkCallback, timeoutMs, legacyType, getDefaultHandler());
}
@@ -3037,8 +3053,14 @@
*
* This function behaves identically to the non-timedout version, but if a suitable
* network is not found within the given time (in milliseconds) the
- * {@link NetworkCallback#onUnavailable} callback is called. The request must
- * still be released normally by calling {@link unregisterNetworkCallback(NetworkCallback)}.
+ * {@link NetworkCallback#onUnavailable} callback is called. The request can still be
+ * released normally by calling {@link #unregisterNetworkCallback(NetworkCallback)} but does
+ * not have to be released if timed-out (it is automatically released). Unregistering a
+ * request that timed out is not an error.
+ *
+ * <p>Do not use this method to poll for the existence of specific networks (e.g. with a small
+ * timeout) - {@link #registerNetworkCallback(NetworkRequest, NetworkCallback)} is provided
+ * for that purpose. Calling this method will attempt to bring up the requested network.
*
* <p>This method requires the caller to hold either the
* {@link android.Manifest.permission#CHANGE_NETWORK_STATE} permission
@@ -3046,16 +3068,19 @@
* {@link android.provider.Settings.System#canWrite}.</p>
*
* @param request {@link NetworkRequest} describing this request.
- * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
- * the callback must not be shared - it uniquely specifies this request.
* @param timeoutMs The time in milliseconds to attempt looking for a suitable network
* before {@link NetworkCallback#onUnavailable} is called.
+ * @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
+ * the callback must not be shared - it uniquely specifies this request.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
*
* @hide
*/
- public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback,
- int timeoutMs, Handler handler) {
+ public void requestNetwork(NetworkRequest request, int timeoutMs,
+ NetworkCallback networkCallback, Handler handler) {
+ if (timeoutMs <= 0) {
+ throw new IllegalArgumentException("Non-positive timeoutMs");
+ }
int legacyType = inferLegacyTypeForNetworkCapabilities(request.networkCapabilities);
CallbackHandler cbHandler = new CallbackHandler(handler);
requestNetwork(request, networkCallback, timeoutMs, legacyType, cbHandler);
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 4aabda9..b123c28 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -156,8 +156,6 @@
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation);
- void requestLinkProperties(in NetworkRequest networkRequest);
- void requestNetworkCapabilities(in NetworkRequest networkRequest);
void releaseNetworkRequest(in NetworkRequest networkRequest);
void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index bd32314..2c9ce3f 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -839,7 +839,7 @@
if (cf && !inChunk) {
// first chunk
- if (typeLength == 0) {
+ if (typeLength == 0 && tnf != NdefRecord.TNF_UNKNOWN) {
throw new FormatException("expected non-zero type length in first chunk");
}
chunks.clear();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a9ca12b..6986732 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -218,6 +218,8 @@
LOCAL_STATIC_LIBRARIES := \
libseccomp_policy \
+ libselinux \
+ libcrypto \
LOCAL_SHARED_LIBRARIES := \
libmemtrack \
diff --git a/core/jni/android_os_seccomp.cpp b/core/jni/android_os_seccomp.cpp
index dd5622d..4502371 100644
--- a/core/jni/android_os_seccomp.cpp
+++ b/core/jni/android_os_seccomp.cpp
@@ -17,9 +17,16 @@
#include "core_jni_helpers.h"
#include "JniConstants.h"
#include "utils/Log.h"
+#include <selinux/selinux.h>
+
#include "seccomp_policy.h"
static void Seccomp_setPolicy(JNIEnv* /*env*/) {
+ if (security_getenforce() == 0) {
+ ALOGI("seccomp disabled by setenforce 0");
+ return;
+ }
+
if (!set_seccomp_filter()) {
ALOGE("Failed to set seccomp policy - killing");
exit(1);
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index a734401..ce13ebc 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -685,7 +685,9 @@
SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
AutoMutex _lock(mSyncMutex);
mRenderThread.queue(&syncTask);
- mSyncCondition.wait(mSyncMutex);
+ while (!syncTask.hasRun()) {
+ mSyncCondition.wait(mSyncMutex);
+ }
return retval;
}
diff --git a/libs/hwui/renderthread/RenderTask.cpp b/libs/hwui/renderthread/RenderTask.cpp
index b14f580..928a4ef 100644
--- a/libs/hwui/renderthread/RenderTask.cpp
+++ b/libs/hwui/renderthread/RenderTask.cpp
@@ -26,6 +26,7 @@
void SignalingRenderTask::run() {
mTask->run();
mLock->lock();
+ mHasRun = true;
mSignal->signal();
mLock->unlock();
}
diff --git a/libs/hwui/renderthread/RenderTask.h b/libs/hwui/renderthread/RenderTask.h
index 9ea671b..a7acf91 100644
--- a/libs/hwui/renderthread/RenderTask.h
+++ b/libs/hwui/renderthread/RenderTask.h
@@ -60,13 +60,15 @@
public:
// Takes ownership of task, caller owns lock and signal
SignalingRenderTask(RenderTask* task, Mutex* lock, Condition* signal)
- : mTask(task), mLock(lock), mSignal(signal) {}
+ : mTask(task), mLock(lock), mSignal(signal), mHasRun(false) {}
virtual void run() override;
+ bool hasRun() const { return mHasRun; }
private:
RenderTask* mTask;
Mutex* mLock;
Condition* mSignal;
+ bool mHasRun;
};
typedef void* (*RunnableMethod)(void* data);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 9c10c4f..f383adc 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -345,7 +345,9 @@
AutoMutex _lock(mutex);
queue(&syncTask);
- condition.wait(mutex);
+ while (!syncTask.hasRun()) {
+ condition.wait(mutex);
+ }
}
void RenderThread::queueAtFront(RenderTask* task) {
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 9d2f750..667bf71 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -1071,7 +1071,6 @@
mSize += mElements[ct].mSize * mArraySizes[ct];
}
updateVisibleSubElements();
- guard.open("destroy");
}
Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
@@ -1091,7 +1090,6 @@
mKind = dk;
mNormalized = norm;
mVectorSize = size;
- guard.open("destroy");
}
Element(long id, RenderScript rs) {
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index 9252898..dc23785 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -227,7 +227,6 @@
Type(long id, RenderScript rs) {
super(id, rs);
- guard.open("destroy");
}
@Override
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 66576b5..5e9cf74 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -81,6 +81,8 @@
private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID="bluetooth_addr_valid";
private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address";
private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name";
+ private static final String REASON_AIRPLANE_MODE = "airplane mode";
+ private static final String REASON_SYSTEM_BOOT = "system boot";
private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
private static final int TIMEOUT_SAVE_MS = 500; //Maximum msec to wait for a save
//Maximum msec to wait for service restart
@@ -194,19 +196,6 @@
private final boolean mPermissionReviewRequired;
- private void registerForAirplaneMode(IntentFilter filter) {
- final ContentResolver resolver = mContext.getContentResolver();
- final String airplaneModeRadios = Settings.Global.getString(resolver,
- Settings.Global.AIRPLANE_MODE_RADIOS);
- final String toggleableRadios = Settings.Global.getString(resolver,
- Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
- boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true :
- airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH);
- if (mIsAirplaneSensitive) {
- filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- }
- }
-
private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
@Override
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
@@ -239,6 +228,62 @@
}
};
+ private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
+ @Override
+ public void onChange(boolean unused) {
+ synchronized(this) {
+ if (isBluetoothPersistedStateOn()) {
+ if (isAirplaneModeOn()) {
+ persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
+ } else {
+ persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
+ }
+ }
+
+ int st = BluetoothAdapter.STATE_OFF;
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null) {
+ st = mBluetooth.getState();
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to call getState", e);
+ return;
+ } finally {
+ mBluetoothLock.readLock().unlock();
+ }
+
+ Slog.d(TAG, "Airplane Mode change - current state: " +
+ BluetoothAdapter.nameForState(st));
+
+ if (isAirplaneModeOn()) {
+ // Clear registered LE apps to force shut-off
+ clearBleApps();
+
+ // If state is BLE_ON make sure we trigger disableBLE
+ if (st == BluetoothAdapter.STATE_BLE_ON) {
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth != null) {
+ mBluetooth.onBrEdrDown();
+ mEnable = false;
+ mEnableExternal = false;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG,"Unable to call onBrEdrDown", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
+ }
+ } else if (st == BluetoothAdapter.STATE_ON){
+ sendDisableMsg(REASON_AIRPLANE_MODE);
+ }
+ } else if (mEnableExternal) {
+ sendEnableMsg(mQuietEnableExternal, REASON_AIRPLANE_MODE);
+ }
+ }
+ }
+ };
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -249,57 +294,6 @@
if (newName != null) {
storeNameAndAddress(newName, null);
}
- } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
- synchronized(mReceiver) {
- if (isBluetoothPersistedStateOn()) {
- if (isAirplaneModeOn()) {
- persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE);
- } else {
- persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
- }
- }
-
- int st = BluetoothAdapter.STATE_OFF;
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null) {
- st = mBluetooth.getState();
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to call getState", e);
- } finally {
- mBluetoothLock.readLock().unlock();
- }
- Slog.d(TAG, "State " + BluetoothAdapter.nameForState(st));
-
- if (isAirplaneModeOn()) {
- // Clear registered LE apps to force shut-off
- clearBleApps();
- if (st == BluetoothAdapter.STATE_BLE_ON) {
- //if state is BLE_ON make sure you trigger disableBLE part
- try {
- mBluetoothLock.readLock().lock();
- if (mBluetooth != null) {
- mBluetooth.onBrEdrDown();
- mEnable = false;
- mEnableExternal = false;
- }
- } catch (RemoteException e) {
- Slog.e(TAG,"Unable to call onBrEdrDown", e);
- } finally {
- mBluetoothLock.readLock().unlock();
- }
- } else if (st == BluetoothAdapter.STATE_ON){
- // disable without persisting the setting
- Slog.d(TAG, "Calling disable");
- sendDisableMsg("airplane mode");
- }
- } else if (mEnableExternal) {
- // enable without persisting the setting
- Slog.d(TAG, "Calling enable");
- sendEnableMsg(mQuietEnableExternal, "airplane mode");
- }
- }
}
}
};
@@ -332,7 +326,6 @@
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
- registerForAirplaneMode(filter);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(mReceiver, filter);
loadStoredNameAndAddress();
@@ -340,6 +333,15 @@
mEnableExternal = true;
}
+ String airplaneModeRadios = Settings.Global.getString(mContentResolver,
+ Settings.Global.AIRPLANE_MODE_RADIOS);
+ if (airplaneModeRadios == null ||
+ airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH)) {
+ mContentResolver.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
+ true, mAirplaneModeObserver);
+ }
+
int systemUiUid = -1;
try {
systemUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui",
@@ -636,6 +638,9 @@
if (appCount == 0 && mEnable) {
disableBleScanMode();
}
+ if (appCount == 0 && !mEnableExternal) {
+ sendBrEdrDownCallback();
+ }
return appCount;
}
@@ -691,7 +696,14 @@
return;
}
- if (isBleAppPresent() == false) {
+ if (isBleAppPresent()) {
+ // Need to stay at BLE ON. Disconnect all Gatt connections
+ try {
+ mBluetoothGatt.unregAll();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to disconnect all apps.", e);
+ }
+ } else {
try {
mBluetoothLock.readLock().lock();
if (mBluetooth != null) mBluetooth.onBrEdrDown();
@@ -700,14 +712,8 @@
} finally {
mBluetoothLock.readLock().unlock();
}
- } else {
- // Need to stay at BLE ON. Disconnect all Gatt connections
- try {
- mBluetoothGatt.unregAll();
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to disconnect all apps.", e);
- }
}
+
}
public boolean enableNoAutoConnect(String packageName)
@@ -958,7 +964,7 @@
}
if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth.");
- sendEnableMsg(mQuietEnableExternal, "system boot");
+ sendEnableMsg(mQuietEnableExternal, REASON_SYSTEM_BOOT);
} else if (!isNameAndAddressSet()) {
if (DBG) Slog.d(TAG, "Getting adapter name and address");
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 954a94e..f58cdba 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -395,16 +395,6 @@
*/
private static final int EVENT_REGISTER_NETWORK_LISTENER_WITH_INTENT = 31;
- /**
- * Indicates a caller has requested to have its callback invoked with
- * the latest LinkProperties or NetworkCapabilities.
- *
- * arg1 = UID of caller
- * obj = NetworkRequest
- */
- private static final int EVENT_REQUEST_LINKPROPERTIES = 32;
- private static final int EVENT_REQUEST_NETCAPABILITIES = 33;
-
/** Handler thread used for both of the handlers below. */
@VisibleForTesting
protected final HandlerThread mHandlerThread;
@@ -2574,34 +2564,6 @@
return nri;
}
- private void handleRequestCallbackUpdate(NetworkRequest request, int callingUid,
- String description, int callbackType) {
- final NetworkRequestInfo nri = getNriForAppRequest(request, callingUid, description);
- if (nri == null) return;
-
- final NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
- // The network that is satisfying this request may have changed since
- // the application requested the update.
- //
- // - If the request is no longer satisfied, don't send any updates.
- // - If the request is satisfied by a different network, it is the
- // caller's responsibility to check that the Network object in the
- // callback matches the network that was returned in the last
- // onAvailable() callback for this request.
- if (nai == null) return;
- callCallbackForRequest(nri, nai, callbackType, 0);
- }
-
- private void handleRequestLinkProperties(NetworkRequest request, int callingUid) {
- handleRequestCallbackUpdate(request, callingUid,
- "request LinkProperties", ConnectivityManager.CALLBACK_IP_CHANGED);
- }
-
- private void handleRequestNetworkCapabilities(NetworkRequest request, int callingUid) {
- handleRequestCallbackUpdate(request, callingUid,
- "request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
-
private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
if (mNetworkRequests.get(nri.request) != null && mNetworkForRequestId.get(
nri.request.requestId) == null) {
@@ -2983,12 +2945,6 @@
handleMobileDataAlwaysOn();
break;
}
- case EVENT_REQUEST_LINKPROPERTIES:
- handleRequestLinkProperties((NetworkRequest) msg.obj, msg.arg1);
- break;
- case EVENT_REQUEST_NETCAPABILITIES:
- handleRequestNetworkCapabilities((NetworkRequest) msg.obj, msg.arg1);
- break;
// Sent by KeepaliveTracker to process an app request on the state machine thread.
case NetworkAgent.CMD_START_PACKET_KEEPALIVE: {
mKeepaliveTracker.handleStartKeepalive(msg);
@@ -4349,22 +4305,6 @@
}
@Override
- public void requestLinkProperties(NetworkRequest networkRequest) {
- ensureNetworkRequestHasType(networkRequest);
- if (networkRequest.type == NetworkRequest.Type.LISTEN) return;
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_REQUEST_LINKPROPERTIES, getCallingUid(), 0, networkRequest));
- }
-
- @Override
- public void requestNetworkCapabilities(NetworkRequest networkRequest) {
- ensureNetworkRequestHasType(networkRequest);
- if (networkRequest.type == NetworkRequest.Type.LISTEN) return;
- mHandler.sendMessage(mHandler.obtainMessage(
- EVENT_REQUEST_NETCAPABILITIES, getCallingUid(), 0, networkRequest));
- }
-
- @Override
public void releaseNetworkRequest(NetworkRequest networkRequest) {
ensureNetworkRequestHasType(networkRequest);
mHandler.sendMessage(mHandler.obtainMessage(
@@ -4856,7 +4796,7 @@
if (!nr.isListen()) continue;
if (nai.satisfies(nr) && !nai.isSatisfyingRequest(nr.requestId)) {
nai.addRequest(nr);
- notifyNetworkCallback(nai, nri);
+ notifyNetworkAvailable(nai, nri);
}
}
}
@@ -5038,7 +4978,7 @@
// do this after the default net is switched, but
// before LegacyTypeTracker sends legacy broadcasts
- for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri);
+ for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
// Linger any networks that are no longer needed. This should be done after sending the
// available callback for newNetwork.
@@ -5201,7 +5141,7 @@
}
private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) {
- NetworkInfo.State state = newInfo.getState();
+ final NetworkInfo.State state = newInfo.getState();
NetworkInfo oldInfo = null;
final int oldScore = networkAgent.getCurrentScore();
synchronized (networkAgent) {
@@ -5328,15 +5268,27 @@
sendUpdatedScoreToFactories(nai);
}
- // notify only this one new request of the current state
- protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) {
- int notifyType = ConnectivityManager.CALLBACK_AVAILABLE;
+ // Notify only this one new request of the current state. Transfer all the
+ // current state by calling NetworkCapabilities and LinkProperties callbacks
+ // so that callers can be guaranteed to have as close to atomicity in state
+ // transfer as can be supported by this current API.
+ protected void notifyNetworkAvailable(NetworkAgentInfo nai, NetworkRequestInfo nri) {
mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri);
- if (nri.mPendingIntent == null) {
- callCallbackForRequest(nri, nai, notifyType, 0);
- } else {
- sendPendingIntentForRequest(nri, nai, notifyType);
+ if (nri.mPendingIntent != null) {
+ sendPendingIntentForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE);
+ // Attempt no subsequent state pushes where intents are involved.
+ return;
}
+
+ callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
+ // Whether a network is currently suspended is also an important
+ // element of state to be transferred (it would not otherwise be
+ // delivered by any currently available mechanism).
+ if (nai.networkInfo.getState() == NetworkInfo.State.SUSPENDED) {
+ callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_SUSPENDED, 0);
+ }
+ callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_CAP_CHANGED, 0);
+ callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_IP_CHANGED, 0);
}
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 1da5e69..dfd647c 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -76,6 +76,7 @@
import com.android.server.connectivity.tethering.IControlsTethering;
import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
import com.android.server.connectivity.tethering.IPv6TetheringInterfaceServices;
+import com.android.server.connectivity.tethering.OffloadController;
import com.android.server.connectivity.tethering.TetheringConfiguration;
import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
@@ -145,6 +146,7 @@
.getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
private final StateMachine mTetherMasterSM;
+ private final OffloadController mOffloadController;
private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
private String mCurrentUpstreamIface;
@@ -175,6 +177,7 @@
mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
mTetherMasterSM.start();
+ mOffloadController = new OffloadController(mTetherMasterSM.getHandler());
mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
mContext, mTetherMasterSM, TetherMasterSM.EVENT_UPSTREAM_CALLBACK);
@@ -1203,6 +1206,8 @@
protected void handleNewUpstreamNetworkState(NetworkState ns) {
mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
+ mOffloadController.setUpstreamLinkProperties(
+ (ns != null) ? ns.linkProperties : null);
}
}
@@ -1364,12 +1369,14 @@
class TetherModeAliveState extends TetherMasterUtilState {
final SimChangeListener simChange = new SimChangeListener(mContext);
boolean mTryCell = true;
+
@Override
public void enter() {
// TODO: examine if we should check the return value.
turnOnMasterTetherSettings(); // may transition us out
simChange.startListening();
mUpstreamNetworkMonitor.start();
+ mOffloadController.start();
// Better try something first pass or crazy tests cases will fail.
chooseUpstreamType(true);
@@ -1378,6 +1385,7 @@
@Override
public void exit() {
+ mOffloadController.stop();
unrequestUpstreamMobileConnection();
mUpstreamNetworkMonitor.stop();
simChange.stopListening();
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
new file mode 100644
index 0000000..220e751
--- /dev/null
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 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 com.android.server.connectivity.tethering;
+
+import android.net.LinkProperties;
+import android.os.Handler;
+import android.util.Log;
+
+/**
+ * A wrapper around hardware offload interface.
+ *
+ * @hide
+ */
+public class OffloadController {
+ private static final String TAG = OffloadController.class.getSimpleName();
+
+ private final Handler mHandler;
+ private LinkProperties mUpstreamLinkProperties;
+
+ public OffloadController(Handler h) {
+ mHandler = h;
+ }
+
+ public void start() {
+ // TODO: initOffload() and configure callbacks to be handled on our
+ // preferred Handler.
+ Log.d(TAG, "tethering offload not supported");
+ }
+
+ public void stop() {
+ // TODO: stopOffload().
+ mUpstreamLinkProperties = null;
+ }
+
+ public void setUpstreamLinkProperties(LinkProperties lp) {
+ // TODO: setUpstreamParameters().
+ mUpstreamLinkProperties = lp;
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 6106093..6209929 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -186,6 +186,7 @@
switch (callbackType) {
case CALLBACK_LISTEN_ALL:
break;
+
case CALLBACK_TRACK_DEFAULT:
if (mDefaultNetworkCallback == null) {
// The callback was unregistered in the interval between
@@ -198,11 +199,9 @@
// These request*() calls can be deleted post oag/339444.
return;
}
-
- cm().requestNetworkCapabilities(mDefaultNetworkCallback);
- cm().requestLinkProperties(mDefaultNetworkCallback);
mCurrentDefault = network;
break;
+
case CALLBACK_MOBILE_REQUEST:
if (mMobileNetworkCallback == null) {
// The callback was unregistered in the interval between
@@ -211,13 +210,8 @@
//
// Clean-up of this network entry is deferred to the
// handling of onLost() by other callbacks.
- //
- // These request*() calls can be deleted post oag/339444.
return;
}
-
- cm().requestNetworkCapabilities(mMobileNetworkCallback);
- cm().requestLinkProperties(mMobileNetworkCallback);
break;
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index e939b2e..98f7ccb 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1007,6 +1007,7 @@
private int mState;
private List<String> mCannedTextResponses = null;
private String mCallingPackage;
+ private int mTargetSdkVersion;
private String mRemainingPostDialSequence;
private VideoCallImpl mVideoCallImpl;
private RttCall mRttCall;
@@ -1540,22 +1541,25 @@
}
/** {@hide} */
- Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage) {
+ Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, String callingPackage,
+ int targetSdkVersion) {
mPhone = phone;
mTelecomCallId = telecomCallId;
mInCallAdapter = inCallAdapter;
mState = STATE_NEW;
mCallingPackage = callingPackage;
+ mTargetSdkVersion = targetSdkVersion;
}
/** {@hide} */
Call(Phone phone, String telecomCallId, InCallAdapter inCallAdapter, int state,
- String callingPackage) {
+ String callingPackage, int targetSdkVersion) {
mPhone = phone;
mTelecomCallId = telecomCallId;
mInCallAdapter = inCallAdapter;
mState = state;
mCallingPackage = callingPackage;
+ mTargetSdkVersion = targetSdkVersion;
}
/** {@hide} */
@@ -1581,7 +1585,8 @@
cannedTextResponsesChanged = true;
}
- VideoCallImpl newVideoCallImpl = parcelableCall.getVideoCallImpl(mCallingPackage);
+ VideoCallImpl newVideoCallImpl = parcelableCall.getVideoCallImpl(mCallingPackage,
+ mTargetSdkVersion);
boolean videoCallChanged = parcelableCall.isVideoCallProviderChanged() &&
!Objects.equals(mVideoCallImpl, newVideoCallImpl);
if (videoCallChanged) {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 3e690b9..417fa3bf 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -23,6 +23,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.Notification;
+import android.content.Intent;
import android.hardware.camera2.CameraManager;
import android.net.Uri;
import android.os.Binder;
@@ -1005,7 +1007,7 @@
try {
onSetCamera((String) args.arg1);
onSetCamera((String) args.arg1, (String) args.arg2, args.argi1,
- args.argi2);
+ args.argi2, args.argi3);
} finally {
args.recycle();
}
@@ -1065,7 +1067,9 @@
MSG_REMOVE_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
}
- public void setCamera(String cameraId, String callingPackageName) {
+ public void setCamera(String cameraId, String callingPackageName,
+ int targetSdkVersion) {
+
SomeArgs args = SomeArgs.obtain();
args.arg1 = cameraId;
// Propagate the calling package; originally determined in
@@ -1077,6 +1081,9 @@
// check to see if the calling app is able to use the camera.
args.argi1 = Binder.getCallingUid();
args.argi2 = Binder.getCallingPid();
+ // Pass along the target SDK version of the calling InCallService. This is used to
+ // maintain backwards compatibility of the API for older callers.
+ args.argi3 = targetSdkVersion;
mMessageHandler.obtainMessage(MSG_SET_CAMERA, args).sendToTarget();
}
@@ -1179,10 +1186,11 @@
* @param callingPackageName The AppOpps package name of the caller.
* @param callingUid The UID of the caller.
* @param callingPid The PID of the caller.
+ * @param targetSdkVersion The target SDK version of the caller.
* @hide
*/
public void onSetCamera(String cameraId, String callingPackageName, int callingUid,
- int callingPid) {}
+ int callingPid, int targetSdkVersion) {}
/**
* Sets the surface to be used for displaying a preview of what the user's camera is
@@ -2592,6 +2600,41 @@
* regular {@link ConnectionService}, the Telecom framework will display its own incoming call
* user interface to allow the user to choose whether to answer the new incoming call and
* disconnect other ongoing calls, or to reject the new incoming call.
+ * <p>
+ * You should trigger the display of the incoming call user interface for your application by
+ * showing a {@link Notification} with a full-screen {@link Intent} specified.
+ * For example:
+ * <pre><code>
+ * // Create an intent which triggers your fullscreen incoming call user interface.
+ * Intent intent = new Intent(Intent.ACTION_MAIN, null);
+ * intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
+ * intent.setClass(context, YourIncomingCallActivity.class);
+ * PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
+ *
+ * // Build the notification as an ongoing high priority item; this ensures it will show as
+ * // a heads up notification which slides down over top of the current content.
+ * final Notification.Builder builder = new Notification.Builder(context);
+ * builder.setOngoing(true);
+ * builder.setPriority(Notification.PRIORITY_HIGH);
+ *
+ * // Set notification content intent to take user to fullscreen UI if user taps on the
+ * // notification body.
+ * builder.setContentIntent(pendingIntent);
+ * // Set full screen intent to trigger display of the fullscreen UI when the notification
+ * // manager deems it appropriate.
+ * builder.setFullScreenIntent(pendingIntent, true);
+ *
+ * // Setup notification content.
+ * builder.setSmallIcon( yourIconResourceId );
+ * builder.setContentTitle("Your notification title");
+ * builder.setContentText("Your notification content.");
+ *
+ * // Use builder.addAction(..) to add buttons to answer or reject the call.
+ *
+ * NotificationManager notificationManager = mContext.getSystemService(
+ * NotificationManager.class);
+ * notificationManager.notify(YOUR_TAG, YOUR_ID, builder.build());
+ * </code></pre>
*/
public void onShowIncomingCallUi() {}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 6e10029..79f085c 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -214,6 +214,7 @@
@Override
public void createConnectionFailed(
+ PhoneAccountHandle connectionManagerPhoneAccount,
String callId,
ConnectionRequest request,
boolean isIncoming,
@@ -224,6 +225,7 @@
args.arg1 = callId;
args.arg2 = request;
args.arg3 = Log.createSubsession();
+ args.arg4 = connectionManagerPhoneAccount;
args.argi1 = isIncoming ? 1 : 0;
mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
} finally {
@@ -581,6 +583,8 @@
final String id = (String) args.arg1;
final ConnectionRequest request = (ConnectionRequest) args.arg2;
final boolean isIncoming = args.argi1 == 1;
+ final PhoneAccountHandle connectionMgrPhoneAccount =
+ (PhoneAccountHandle) args.arg4;
if (!mAreAccountsInitialized) {
Log.d(this, "Enqueueing pre-init request %s", id);
mPreInitializationConnectionRequests.add(
@@ -589,12 +593,14 @@
null /*lock*/) {
@Override
public void loggedRun() {
- createConnectionFailed(id, request, isIncoming);
+ createConnectionFailed(connectionMgrPhoneAccount, id,
+ request, isIncoming);
}
}.prepare());
} else {
Log.i(this, "createConnectionFailed %s", id);
- createConnectionFailed(id, request, isIncoming);
+ createConnectionFailed(connectionMgrPhoneAccount, id, request,
+ isIncoming);
}
} finally {
args.recycle();
@@ -1225,14 +1231,15 @@
}
}
- private void createConnectionFailed(final String callId, final ConnectionRequest request,
- boolean isIncoming) {
+ private void createConnectionFailed(final PhoneAccountHandle callManagerAccount,
+ final String callId, final ConnectionRequest request,
+ boolean isIncoming) {
Log.i(this, "createConnectionFailed %s", callId);
if (isIncoming) {
- onCreateIncomingConnectionFailed(request);
+ onCreateIncomingConnectionFailed(callManagerAccount, request);
} else {
- onCreateOutgoingConnectionFailed(request);
+ onCreateOutgoingConnectionFailed(callManagerAccount, request);
}
}
@@ -1682,9 +1689,12 @@
* <p>
* See {@link TelecomManager#isIncomingCallPermitted(PhoneAccountHandle)} for more information.
*
+ * @param connectionManagerPhoneAccount See description at
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
* @param request The incoming connection request.
*/
- public void onCreateIncomingConnectionFailed(ConnectionRequest request) {
+ public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request) {
}
/**
@@ -1698,9 +1708,12 @@
* <p>
* See {@link TelecomManager#isOutgoingCallPermitted(PhoneAccountHandle)} for more information.
*
+ * @param connectionManagerPhoneAccount See description at
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
* @param request The outgoing connection request.
*/
- public void onCreateOutgoingConnectionFailed(ConnectionRequest request) {
+ public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request) {
}
/**
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 4bc64c0..c4f5ffc 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -89,7 +89,8 @@
switch (msg.what) {
case MSG_SET_IN_CALL_ADAPTER:
String callingPackage = getApplicationContext().getOpPackageName();
- mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj), callingPackage);
+ mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj), callingPackage,
+ getApplicationContext().getApplicationInfo().targetSdkVersion);
mPhone.addListener(mPhoneListener);
onPhoneCreated(mPhone);
break;
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 975aa5a..85a92d1 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -193,13 +193,16 @@
/**
* Returns an object for remotely communicating through the video call provider's binder.
-
+ *
+ * @param callingPackageName the package name of the calling InCallService.
+ * @param targetSdkVersion the target SDK version of the calling InCallService.
* @return The video call.
*/
- public VideoCallImpl getVideoCallImpl(String callingPackageName) {
+ public VideoCallImpl getVideoCallImpl(String callingPackageName, int targetSdkVersion) {
if (mVideoCall == null && mVideoCallProvider != null) {
try {
- mVideoCall = new VideoCallImpl(mVideoCallProvider, callingPackageName);
+ mVideoCall = new VideoCallImpl(mVideoCallProvider, callingPackageName,
+ targetSdkVersion);
} catch (RemoteException ignored) {
// Ignore RemoteException.
}
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index ebd04c7..524dc70 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -127,14 +127,20 @@
private final String mCallingPackage;
- Phone(InCallAdapter adapter, String callingPackage) {
+ /**
+ * The Target SDK version of the InCallService implementation.
+ */
+ private final int mTargetSdkVersion;
+
+ Phone(InCallAdapter adapter, String callingPackage, int targetSdkVersion) {
mInCallAdapter = adapter;
mCallingPackage = callingPackage;
+ mTargetSdkVersion = targetSdkVersion;
}
final void internalAddCall(ParcelableCall parcelableCall) {
Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,
- parcelableCall.getState(), mCallingPackage);
+ parcelableCall.getState(), mCallingPackage, mTargetSdkVersion);
mCallByTelecomCallId.put(parcelableCall.getId(), call);
mCalls.add(call);
checkCallTree(parcelableCall);
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 77e0e54..e121238 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -410,6 +410,8 @@
private final String mCallingPackage;
+ private final int mTargetSdkVersion;
+
/**
* ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
* load factor before resizing, 1 means we only expect a single thread to
@@ -418,9 +420,12 @@
private final Set<Callback> mCallbacks = Collections.newSetFromMap(
new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
- VideoProvider(IVideoProvider videoProviderBinder, String callingPackage) {
+ VideoProvider(IVideoProvider videoProviderBinder, String callingPackage,
+ int targetSdkVersion) {
+
mVideoProviderBinder = videoProviderBinder;
mCallingPackage = callingPackage;
+ mTargetSdkVersion = targetSdkVersion;
try {
mVideoProviderBinder.addVideoCallback(mVideoCallbackServant.getStub().asBinder());
} catch (RemoteException e) {
@@ -455,7 +460,7 @@
*/
public void setCamera(String cameraId) {
try {
- mVideoProviderBinder.setCamera(cameraId, mCallingPackage);
+ mVideoProviderBinder.setCamera(cameraId, mCallingPackage, mTargetSdkVersion);
} catch (RemoteException e) {
}
}
@@ -631,7 +636,7 @@
* @hide
*/
RemoteConnection(String callId, IConnectionService connectionService,
- ParcelableConnection connection, String callingPackage) {
+ ParcelableConnection connection, String callingPackage, int targetSdkVersion) {
mConnectionId = callId;
mConnectionService = connectionService;
mConnected = true;
@@ -643,7 +648,8 @@
mVideoState = connection.getVideoState();
IVideoProvider videoProvider = connection.getVideoProvider();
if (videoProvider != null) {
- mVideoProvider = new RemoteConnection.VideoProvider(videoProvider, callingPackage);
+ mVideoProvider = new RemoteConnection.VideoProvider(videoProvider, callingPackage,
+ targetSdkVersion);
} else {
mVideoProvider = null;
}
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index 60a40f5..b00c0aa 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -286,10 +286,11 @@
String callingPackage = mOurConnectionServiceImpl.getApplicationContext()
.getOpPackageName();
+ int targetSdkVersion = mOurConnectionServiceImpl.getApplicationInfo().targetSdkVersion;
RemoteConnection.VideoProvider remoteVideoProvider = null;
if (videoProvider != null) {
remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider,
- callingPackage);
+ callingPackage, targetSdkVersion);
}
findConnectionForAction(callId, "setVideoProvider")
.setVideoProvider(remoteVideoProvider);
@@ -357,8 +358,11 @@
Session.Info sessionInfo) {
String callingPackage = mOurConnectionServiceImpl.getApplicationContext().
getOpPackageName();
+ int callingTargetSdkVersion = mOurConnectionServiceImpl.getApplicationInfo()
+ .targetSdkVersion;
RemoteConnection remoteConnection = new RemoteConnection(callId,
- mOutgoingConnectionServiceRpc, connection, callingPackage);
+ mOutgoingConnectionServiceRpc, connection, callingPackage,
+ callingTargetSdkVersion);
mConnectionById.put(callId, remoteConnection);
remoteConnection.registerCallback(new RemoteConnection.Callback() {
@Override
diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java
index d8ede5c..429a434 100644
--- a/telecomm/java/android/telecom/VideoCallImpl.java
+++ b/telecomm/java/android/telecom/VideoCallImpl.java
@@ -44,6 +44,7 @@
private int mVideoQuality = VideoProfile.QUALITY_UNKNOWN;
private int mVideoState = VideoProfile.STATE_AUDIO_ONLY;
private final String mCallingPackageName;
+ private final int mTargetSdkVersion;
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
@@ -198,13 +199,15 @@
private Handler mHandler;
- VideoCallImpl(IVideoProvider videoProvider, String callingPackageName) throws RemoteException {
+ VideoCallImpl(IVideoProvider videoProvider, String callingPackageName, int targetSdkVersion)
+ throws RemoteException {
mVideoProvider = videoProvider;
mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0);
mBinder = new VideoCallListenerBinder();
mVideoProvider.addVideoCallback(mBinder);
mCallingPackageName = callingPackageName;
+ mTargetSdkVersion = targetSdkVersion;
}
public void destroy() {
@@ -243,7 +246,7 @@
public void setCamera(String cameraId) {
try {
Log.w(this, "setCamera: cameraId=%s, calling=%s", cameraId, mCallingPackageName);
- mVideoProvider.setCamera(cameraId, mCallingPackageName);
+ mVideoProvider.setCamera(cameraId, mCallingPackageName, mTargetSdkVersion);
} catch (RemoteException e) {
}
}
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 20feba7..6df4067 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -46,8 +46,8 @@
boolean isUnknown,
in Session.Info sessionInfo);
- void createConnectionFailed(String callId, in ConnectionRequest request, boolean isIncoming,
- in Session.Info sessionInfo);
+ void createConnectionFailed(in PhoneAccountHandle connectionManagerPhoneAccount, String callId,
+ in ConnectionRequest request, boolean isIncoming, in Session.Info sessionInfo);
void abort(String callId, in Session.Info sessionInfo);
diff --git a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
index a109e90..272b884 100644
--- a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
+++ b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
@@ -30,7 +30,7 @@
void removeVideoCallback(IBinder videoCallbackBinder);
- void setCamera(String cameraId, in String mCallingPackageName);
+ void setCamera(String cameraId, in String mCallingPackageName, int targetSdkVersion);
void setPreviewSurface(in Surface surface);
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 684a101..b984bbf 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -36,36 +36,21 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.when;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.os.Build.VERSION_CODES;
-import android.net.ConnectivityManager.NetworkCallback;
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
+
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import org.junit.Before;
-import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.junit.Test;
+
+
@RunWith(AndroidJUnit4.class)
@SmallTest
public class ConnectivityManagerTest {
-
- @Mock Context mCtx;
- @Mock IConnectivityManager mService;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- }
-
static NetworkCapabilities verifyNetworkCapabilities(
int legacyType, int transportType, int... capabilities) {
final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
@@ -188,34 +173,4 @@
verifyUnrestrictedNetworkCapabilities(
ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET);
}
-
- @Test
- public void testNoDoubleCallbackRegistration() throws Exception {
- ConnectivityManager manager = new ConnectivityManager(mCtx, mService);
- NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
- NetworkCallback callback = new ConnectivityManager.NetworkCallback();
- ApplicationInfo info = new ApplicationInfo();
- info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
-
- when(mCtx.getApplicationInfo()).thenReturn(info);
- when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request);
-
- manager.requestNetwork(request, callback);
-
- // Callback is already registered, reregistration should fail.
- Class<IllegalArgumentException> wantException = IllegalArgumentException.class;
- expectThrowable(() -> manager.requestNetwork(request, callback), wantException);
- }
-
- static void expectThrowable(Runnable block, Class<? extends Throwable> throwableType) {
- try {
- block.run();
- } catch (Throwable t) {
- if (t.getClass().equals(throwableType)) {
- return;
- }
- fail("expected exception of type " + throwableType + ", but was " + t.getClass());
- }
- fail("expected exception of type " + throwableType);
- }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 52d2b63..b033382 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1170,15 +1170,11 @@
void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended, int timeoutMs) {
expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
-
- final boolean HAS_DATASYNC_ON_AVAILABLE = false;
- if (HAS_DATASYNC_ON_AVAILABLE) {
- if (expectSuspended) {
- expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
- }
- expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
- expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
+ if (expectSuspended) {
+ expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
}
+ expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
+ expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
}
void expectAvailableCallbacks(MockNetworkAgent agent) {
@@ -1190,7 +1186,7 @@
}
void expectAvailableAndValidatedCallbacks(MockNetworkAgent agent) {
- expectAvailableCallbacks(agent, true, TIMEOUT_MS);
+ expectAvailableCallbacks(agent, false, TIMEOUT_MS);
expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
}
@@ -1931,20 +1927,6 @@
dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent);
dfltNetworkCallback.assertNoCallback();
- // Request a NetworkCapabilities update; only the requesting callback is notified.
- // TODO: Delete this together with Connectivity{Manager,Service} code.
- mCm.requestNetworkCapabilities(dfltNetworkCallback);
- dfltNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
- cellNetworkCallback.assertNoCallback();
- dfltNetworkCallback.assertNoCallback();
-
- // Request a LinkProperties update; only the requesting callback is notified.
- // TODO: Delete this together with Connectivity{Manager,Service} code.
- mCm.requestLinkProperties(dfltNetworkCallback);
- dfltNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
- cellNetworkCallback.assertNoCallback();
- dfltNetworkCallback.assertNoCallback();
-
mCm.unregisterNetworkCallback(dfltNetworkCallback);
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 2ba573c..6095c86 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -376,7 +376,9 @@
/**
* Flag indicating if this network is provided by a home Passpoint provider or a roaming
- * Passpoint provider.
+ * Passpoint provider. This flag will be {@code true} if this network is provided by
+ * a home Passpoint provider and {@code false} if is provided by a roaming Passpoint provider
+ * or is a non-Passpoint network.
*/
public boolean isHomeProviderNetwork;