summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp20
-rw-r--r--api/current.txt4
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/os/Binder.java16
-rw-r--r--core/java/com/android/internal/os/BinderInternal.java101
-rw-r--r--core/jni/android_util_Binder.cpp62
-rw-r--r--core/res/res/values-mcc334-mnc03/config.xml20
-rw-r--r--core/res/res/values-mcc334-mnc030/config.xml20
-rw-r--r--core/res/res/values-mcc704-mnc03/config.xml20
-rw-r--r--core/res/res/values-mcc706-mnc04/config.xml20
-rw-r--r--core/res/res/values-mcc712-mnc04/config.xml20
-rw-r--r--core/res/res/values-mcc716-mnc06/config.xml20
-rw-r--r--core/res/res/values-mcc716-mnc10/config.xml20
-rw-r--r--core/res/res/values-mcc716-mnc17/config.xml20
-rw-r--r--core/res/res/values-mcc722-mnc07/config.xml20
-rw-r--r--core/res/res/values-mcc732-mnc123/config.xml20
-rw-r--r--core/res/res/values-mcc740-mnc00/config.xml20
-rw-r--r--core/tests/coretests/Android.mk7
-rw-r--r--core/tests/coretests/AndroidManifest.xml1
-rw-r--r--core/tests/coretests/BinderProxyCountingTestApp/Android.mk28
-rw-r--r--core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml23
-rw-r--r--core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java182
-rw-r--r--core/tests/coretests/BinderProxyCountingTestService/Android.mk28
-rw-r--r--core/tests/coretests/BinderProxyCountingTestService/AndroidManifest.xml25
-rw-r--r--core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java53
-rw-r--r--core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java101
-rw-r--r--core/tests/coretests/aidl/Android.mk22
-rw-r--r--core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBinderProxyCountingService.aidl23
-rw-r--r--core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl21
-rw-r--r--core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestAppCmdService.aidl30
-rw-r--r--core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl26
-rw-r--r--core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestRemoteCallback.aidl20
-rw-r--r--core/tests/coretests/src/android/os/BinderProxyCountingTest.java378
-rw-r--r--libs/hwui/Android.bp5
-rw-r--r--libs/hwui/tests/macrobench/main.cpp2
-rw-r--r--services/Android.bp1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java59
-rw-r--r--telephony/java/android/telephony/CellIdentity.java7
-rw-r--r--telephony/java/android/telephony/CellIdentityTdscdma.java78
-rw-r--r--telephony/java/android/telephony/CellIdentityWcdma.java6
-rw-r--r--telephony/java/android/telephony/CellInfo.java4
-rw-r--r--telephony/java/android/telephony/CellInfoCdma.java2
-rw-r--r--telephony/java/android/telephony/CellInfoGsm.java2
-rw-r--r--telephony/java/android/telephony/CellInfoLte.java2
-rw-r--r--telephony/java/android/telephony/CellInfoTdscdma.java151
-rw-r--r--telephony/java/android/telephony/CellInfoWcdma.java6
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthCdma.java5
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthGsm.java5
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthLte.java5
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthTdscdma.java228
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthWcdma.java34
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationState.java99
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java54
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl14
-rw-r--r--test-base/Android.bp3
-rw-r--r--test-mock/Android.bp2
-rw-r--r--test-runner/Android.bp2
57 files changed, 2074 insertions, 95 deletions
diff --git a/Android.bp b/Android.bp
index f11b6fe0e13c..48757b470f5d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -27,6 +27,7 @@
java_library {
name: "framework",
+ installable: true,
srcs: [
// From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
@@ -672,6 +673,7 @@ gensrcs {
// ============================================================
java_library {
name: "ext",
+ installable: true,
no_framework_libs: true,
static_libs: [
"libphonenumber-platform",
@@ -1050,6 +1052,24 @@ droiddoc {
" -showAnnotation android.annotation.TestApi",
}
+droiddoc {
+ name: "hiddenapi-mappings",
+ defaults: ["framework-docs-default"],
+ arg_files: [
+ "core/res/AndroidManifest.xml",
+ ":api-version-xml",
+ "core/java/overview.html",
+ ":current-support-api",
+ ],
+ dex_mapping_filename: "dex-mapping.txt",
+ args: framework_docs_args +
+ " -referenceonly" +
+ " -nodocs" +
+ " -showUnannotated" +
+ " -showAnnotation android.annotation.SystemApi" +
+ " -showAnnotation android.annotation.TestApi",
+}
+
filegroup {
name: "apache-http-stubs-sources",
srcs: [
diff --git a/api/current.txt b/api/current.txt
index 1ae46d5d8a0e..9ffd50f27c12 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -40832,9 +40832,13 @@ package android.telephony {
method public java.lang.String getIccAuthentication(int, int, java.lang.String);
method public java.lang.String getImei();
method public java.lang.String getImei(int);
+ method public java.lang.String getTypeAllocationCode();
+ method public java.lang.String getTypeAllocationCode(int);
method public java.lang.String getLine1Number();
method public java.lang.String getMeid();
method public java.lang.String getMeid(int);
+ method public java.lang.String getManufacturerCode();
+ method public java.lang.String getManufacturerCode(int);
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public java.lang.String getNai();
diff --git a/api/system-current.txt b/api/system-current.txt
index 9a54ac625b46..cd086c501c60 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4274,8 +4274,8 @@ package android.telephony {
method public int[] getAvailableServices();
method public android.telephony.CellIdentity getCellIdentity();
method public int getDomain();
- method public int getReasonForDenial();
method public int getRegState();
+ method public int getRejectCause();
method public int getTransportType();
method public boolean isEmergencyEnabled();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 5652d6dec8a5..a81d16a6c562 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -536,6 +536,20 @@ public class Binder implements IBinder {
}
/**
+ * Resolves a transaction code to a human readable name.
+ *
+ * <p>Default implementation is a stub that returns null.
+ * <p>AIDL generated code will return the original method name.
+ *
+ * @param transactionCode The code to resolve.
+ * @return A human readable name.
+ * @hide
+ */
+ public @Nullable String getTransactionName(int transactionCode) {
+ return null;
+ }
+
+ /**
* Implemented to call the more convenient version
* {@link #dump(FileDescriptor, PrintWriter, String[])}.
*/
@@ -592,7 +606,7 @@ public class Binder implements IBinder {
/**
* Print the object's state into the given stream.
- *
+ *
* @param fd The raw file descriptor that the dump is being sent to.
* @param fout The file to which you should dump your state. This will be
* closed for you after you return.
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index ea4575aba9c0..5bddd2f98983 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -16,9 +16,15 @@
package com.android.internal.os;
+import android.annotation.NonNull;
+import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.EventLog;
+import android.util.Log;
+import android.util.SparseIntArray;
+
+import com.android.internal.util.Preconditions;
import dalvik.system.VMRuntime;
@@ -31,11 +37,14 @@ import java.util.ArrayList;
* @see IBinder
*/
public class BinderInternal {
+ private static final String TAG = "BinderInternal";
static WeakReference<GcWatcher> sGcWatcher
= new WeakReference<GcWatcher>(new GcWatcher());
static ArrayList<Runnable> sGcWatchers = new ArrayList<>();
static Runnable[] sTmpWatchers = new Runnable[1];
static long sLastGcTime;
+ static final BinderProxyLimitListenerDelegate sBinderProxyLimitListenerDelegate =
+ new BinderProxyLimitListenerDelegate();
static final class GcWatcher {
@Override
@@ -106,4 +115,96 @@ public class BinderInternal {
static void forceBinderGc() {
forceGc("Binder");
}
+
+ /**
+ * Enable/disable Binder Proxy Instance Counting by Uid. While enabled, the set callback will
+ * be called if this process holds too many Binder Proxies on behalf of a Uid.
+ * @param enabled true to enable counting, false to disable
+ */
+ public static final native void nSetBinderProxyCountEnabled(boolean enabled);
+
+ /**
+ * Get the current number of Binder Proxies held for each uid.
+ * @return SparseIntArray mapping uids to the number of Binder Proxies currently held
+ */
+ public static final native SparseIntArray nGetBinderProxyPerUidCounts();
+
+ /**
+ * Get the current number of Binder Proxies held for an individual uid.
+ * @param uid Requested uid for Binder Proxy count
+ * @return int with the number of Binder proxies held for a uid
+ */
+ public static final native int nGetBinderProxyCount(int uid);
+
+ /**
+ * Set the Binder Proxy watermarks. Default high watermark = 2500. Default low watermark = 2000
+ * @param high The limit at which the BinderProxyListener callback will be called.
+ * @param low The threshold a binder count must drop below before the callback
+ * can be called again. (This is to avoid many repeated calls to the
+ * callback in a brief period of time)
+ */
+ public static final native void nSetBinderProxyCountWatermarks(int high, int low);
+
+ /**
+ * Interface for callback invocation when the Binder Proxy limit is reached. onLimitReached will
+ * be called with the uid of the app causing too many Binder Proxies
+ */
+ public interface BinderProxyLimitListener {
+ public void onLimitReached(int uid);
+ }
+
+ /**
+ * Callback used by native code to trigger a callback in java code. The callback will be
+ * triggered when too many binder proxies from a uid hits the allowed limit.
+ * @param uid The uid of the bad behaving app sending too many binders
+ */
+ public static void binderProxyLimitCallbackFromNative(int uid) {
+ sBinderProxyLimitListenerDelegate.notifyClient(uid);
+ }
+
+ /**
+ * Set a callback to be triggered when a uid's Binder Proxy limit is reached for this process.
+ * @param listener OnLimitReached of listener will be called in the thread provided by handler
+ * @param handler must not be null, callback will be posted through the handler;
+ *
+ */
+ public static void setBinderProxyCountCallback(BinderProxyLimitListener listener,
+ @NonNull Handler handler) {
+ Preconditions.checkNotNull(handler,
+ "Must provide NonNull Handler to setBinderProxyCountCallback when setting "
+ + "BinderProxyLimitListener");
+ sBinderProxyLimitListenerDelegate.setListener(listener, handler);
+ }
+
+ /**
+ * Clear the Binder Proxy callback
+ */
+ public static void clearBinderProxyCountCallback() {
+ sBinderProxyLimitListenerDelegate.setListener(null, null);
+ }
+
+ static private class BinderProxyLimitListenerDelegate {
+ private BinderProxyLimitListener mBinderProxyLimitListener;
+ private Handler mHandler;
+
+ void setListener(BinderProxyLimitListener listener, Handler handler) {
+ synchronized (this) {
+ mBinderProxyLimitListener = listener;
+ mHandler = handler;
+ }
+ }
+
+ void notifyClient(final int uid) {
+ synchronized (this) {
+ if (mBinderProxyLimitListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mBinderProxyLimitListener.onLimitReached(uid);
+ }
+ });
+ }
+ }
+ }
+ }
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index a04094099cc2..aa68e75202b4 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -33,6 +33,7 @@
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
+#include <binder/BpBinder.h>
#include <binder/ProcessState.h>
#include <cutils/atomic.h>
#include <log/log.h>
@@ -81,9 +82,17 @@ static struct binderinternal_offsets_t
// Class state.
jclass mClass;
jmethodID mForceGc;
+ jmethodID mProxyLimitCallback;
} gBinderInternalOffsets;
+static struct sparseintarray_offsets_t
+{
+ jclass classObject;
+ jmethodID constructor;
+ jmethodID put;
+} gSparseIntArrayOffsets;
+
// ----------------------------------------------------------------------------
static struct error_offsets_t
@@ -993,6 +1002,43 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
}
+static void android_os_BinderInternal_proxyLimitcallback(int uid)
+{
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
+ gBinderInternalOffsets.mProxyLimitCallback,
+ uid);
+}
+
+static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
+ jboolean enable)
+{
+ BpBinder::setCountByUidEnabled((bool) enable);
+}
+
+static jobject android_os_BinderInternal_getBinderProxyPerUidCounts(JNIEnv* env, jclass clazz)
+{
+ Vector<uint32_t> uids, counts;
+ BpBinder::getCountByUid(uids, counts);
+ jobject sparseIntArray = env->NewObject(gSparseIntArrayOffsets.classObject,
+ gSparseIntArrayOffsets.constructor);
+ for (size_t i = 0; i < uids.size(); i++) {
+ env->CallVoidMethod(sparseIntArray, gSparseIntArrayOffsets.put,
+ static_cast<jint>(uids[i]), static_cast<jint>(counts[i]));
+ }
+ return sparseIntArray;
+}
+
+static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject clazz, jint uid) {
+ return static_cast<jint>(BpBinder::getBinderProxyCount(static_cast<uint32_t>(uid)));
+}
+
+static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
+ jint high, jint low)
+{
+ BpBinder::setBinderProxyCountWatermarks(high, low);
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod gBinderInternalMethods[] = {
@@ -1001,7 +1047,11 @@ static const JNINativeMethod gBinderInternalMethods[] = {
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
- { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
+ { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc },
+ { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
+ { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
+ { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
+ { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
};
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
@@ -1012,6 +1062,16 @@ static int int_register_android_os_BinderInternal(JNIEnv* env)
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
+ gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
+
+ jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
+ gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
+ gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
+ "<init>", "()V");
+ gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
+ "(II)V");
+
+ BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
diff --git a/core/res/res/values-mcc334-mnc03/config.xml b/core/res/res/values-mcc334-mnc03/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc334-mnc03/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc334-mnc030/config.xml b/core/res/res/values-mcc334-mnc030/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc334-mnc030/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc704-mnc03/config.xml b/core/res/res/values-mcc704-mnc03/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc704-mnc03/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc706-mnc04/config.xml b/core/res/res/values-mcc706-mnc04/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc706-mnc04/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc712-mnc04/config.xml b/core/res/res/values-mcc712-mnc04/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc712-mnc04/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc716-mnc06/config.xml b/core/res/res/values-mcc716-mnc06/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc716-mnc06/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc716-mnc10/config.xml b/core/res/res/values-mcc716-mnc10/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc716-mnc10/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc716-mnc17/config.xml b/core/res/res/values-mcc716-mnc17/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc716-mnc17/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc722-mnc07/config.xml b/core/res/res/values-mcc722-mnc07/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc722-mnc07/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc732-mnc123/config.xml b/core/res/res/values-mcc732-mnc123/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc732-mnc123/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/res/res/values-mcc740-mnc00/config.xml b/core/res/res/values-mcc740-mnc00/config.xml
new file mode 100644
index 000000000000..c0d2b3598f82
--- /dev/null
+++ b/core/res/res/values-mcc740-mnc00/config.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+ <bool name="config_showAreaUpdateInfoSettings">true</bool>
+</resources>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index a97e79bda4ab..b99006848dc3 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -19,7 +19,12 @@ LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
$(call all-Iaidl-files-under, src) \
$(call all-java-files-under, DisabledTestApp/src) \
- $(call all-java-files-under, EnabledTestApp/src)
+ $(call all-java-files-under, EnabledTestApp/src) \
+ $(call all-java-files-under, BinderProxyCountingTestApp/src) \
+ $(call all-java-files-under, BinderProxyCountingTestService/src) \
+ $(call all-Iaidl-files-under, aidl)
+
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/aidl
LOCAL_DX_FLAGS := --core-library
LOCAL_JACK_FLAGS := --multi-dex native
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index c0a8acda628e..cfb235999029 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -86,6 +86,7 @@
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.KILL_UID" />
<!-- location test permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/Android.mk b/core/tests/coretests/BinderProxyCountingTestApp/Android.mk
new file mode 100644
index 000000000000..c3af6bd123b8
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestApp/Android.mk
@@ -0,0 +1,28 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := coretests-aidl
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := BinderProxyCountingTestApp
+LOCAL_SDK_VERSION := current
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml
new file mode 100644
index 000000000000..a971730f389d
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.binderproxycountingtestapp">
+
+ <application>
+ <service android:name=".BpcTestAppCmdService"
+ android:exported="true"/>
+ </application>
+</manifest>
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java
new file mode 100644
index 000000000000..5aae1203e559
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java
@@ -0,0 +1,182 @@
+/*
+ * 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.frameworks.coretests.binderproxycountingtestapp;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.frameworks.coretests.aidl.IBinderProxyCountingService;
+import com.android.frameworks.coretests.aidl.IBpcTestAppCmdService;
+import com.android.frameworks.coretests.aidl.ITestRemoteCallback;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class BpcTestAppCmdService extends Service {
+ private static final String TAG = BpcTestAppCmdService.class.getSimpleName();
+
+ private static final String TEST_SERVICE_PKG =
+ "com.android.frameworks.coretests.binderproxycountingtestservice";
+ private static final String TEST_SERVICE_CLASS =
+ TEST_SERVICE_PKG + ".BinderProxyCountingService";
+ private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
+
+ private static ServiceConnection mServiceConnection;
+ private static IBinderProxyCountingService mBpcService;
+
+ private IBpcTestAppCmdService.Stub mBinder = new IBpcTestAppCmdService.Stub() {
+
+ private ArrayList<BroadcastReceiver> mBrList = new ArrayList();
+ private ArrayList<ITestRemoteCallback> mTrcList = new ArrayList();
+
+ @Override
+ public void createSystemBinders(int count) {
+ int i = 0;
+ while (i++ < count) {
+ BroadcastReceiver br = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ }
+ };
+ IntentFilter filt = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
+ synchronized (mBrList) {
+ mBrList.add(br);
+ }
+ registerReceiver(br, filt);
+ }
+ }
+
+ @Override
+ public void releaseSystemBinders(int count) {
+ int i = 0;
+ while (i++ < count) {
+ BroadcastReceiver br;
+ synchronized (mBrList) {
+ br = mBrList.remove(0);
+ }
+ unregisterReceiver(br);
+ }
+ }
+
+ @Override
+ public void createTestBinders(int count) {
+ int i = 0;
+ while (i++ < count) {
+ ITestRemoteCallback cb = new ITestRemoteCallback.Stub() {};
+ synchronized (mTrcList) {
+ mTrcList.add(cb);
+ }
+ try {
+ mBpcService.registerCallback(cb);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException caught! " + e);
+ }
+ }
+ }
+
+ @Override
+ public void releaseTestBinders(int count) {
+ int i = 0;
+ while (i++ < count) {
+
+ ITestRemoteCallback cb;
+ synchronized (mTrcList) {
+ cb = mTrcList.remove(0);
+ }
+ try {
+ mBpcService.unregisterCallback(cb);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException caught! " + e);
+ }
+ }
+ }
+
+ @Override
+ public void releaseAllBinders() {
+ synchronized (mBrList) {
+ while (mBrList.size() > 0) {
+ unregisterReceiver(mBrList.remove(0));
+ }
+ }
+ synchronized (mTrcList) {
+ while (mTrcList.size() > 0) {
+ try {
+ mBpcService.unregisterCallback(mTrcList.remove(0));
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException caught! " + e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String bindToTestService() {
+ try {
+ final CountDownLatch bindLatch = new CountDownLatch(1);
+ mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.i(TAG, "Service connected");
+ mBpcService = IBinderProxyCountingService.Stub.asInterface(service);
+ bindLatch.countDown();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.i(TAG, "Service disconnected");
+ }
+ };
+ final Intent intent = new Intent()
+ .setComponent(new ComponentName(TEST_SERVICE_PKG, TEST_SERVICE_CLASS));
+ bindService(intent, mServiceConnection,
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_ALLOW_OOM_MANAGEMENT
+ | Context.BIND_NOT_FOREGROUND);
+ if (!bindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ throw new RuntimeException("Failed to bind to " + TEST_SERVICE_CLASS);
+ }
+ } catch (Exception e) {
+ unbindFromTestService();
+ Log.e(TAG, e.toString());
+ return e.toString();
+ }
+ return null;
+ }
+
+ @Override
+ public void unbindFromTestService() {
+ if (mBpcService != null) {
+ unbindService(mServiceConnection);
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+} \ No newline at end of file
diff --git a/core/tests/coretests/BinderProxyCountingTestService/Android.mk b/core/tests/coretests/BinderProxyCountingTestService/Android.mk
new file mode 100644
index 000000000000..34016ed633b1
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestService/Android.mk
@@ -0,0 +1,28 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := coretests-aidl
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := BinderProxyCountingTestService
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
diff --git a/core/tests/coretests/BinderProxyCountingTestService/AndroidManifest.xml b/core/tests/coretests/BinderProxyCountingTestService/AndroidManifest.xml
new file mode 100644
index 000000000000..777bd20db212
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestService/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.binderproxycountingtestservice">
+
+ <application>
+ <service android:name=".BpcTestServiceCmdService"
+ android:exported="true" />
+ <service android:name=".BinderProxyCountingService"
+ android:exported="true" />
+ </application>
+</manifest>
diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.java
new file mode 100644
index 000000000000..41b4c69232f4
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BinderProxyCountingService.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.frameworks.coretests.binderproxycountingtestservice;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteCallbackList;
+
+import com.android.frameworks.coretests.aidl.IBinderProxyCountingService;
+import com.android.frameworks.coretests.aidl.ITestRemoteCallback;
+
+public class BinderProxyCountingService extends Service {
+ private static final String TAG = BinderProxyCountingService.class.getSimpleName();
+
+ private IBinderProxyCountingService.Stub mBinder = new IBinderProxyCountingService.Stub() {
+
+ final RemoteCallbackList<ITestRemoteCallback> mTestCallbacks = new RemoteCallbackList<>();
+
+ @Override
+ public void registerCallback(ITestRemoteCallback callback) {
+ synchronized (this) {
+ mTestCallbacks.register(callback);
+ }
+ }
+
+ @Override
+ public void unregisterCallback(ITestRemoteCallback callback) {
+ synchronized (this) {
+ mTestCallbacks.unregister(callback);
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+} \ No newline at end of file
diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java
new file mode 100644
index 000000000000..6bed2a2ec53f
--- /dev/null
+++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java
@@ -0,0 +1,101 @@
+/*
+ * 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.frameworks.coretests.binderproxycountingtestservice;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.frameworks.coretests.aidl.IBpcCallbackObserver;
+import com.android.frameworks.coretests.aidl.IBpcTestServiceCmdService;
+import com.android.internal.os.BinderInternal;
+
+public class BpcTestServiceCmdService extends Service {
+ private static final String TAG = BpcTestServiceCmdService.class.getSimpleName();
+
+ //ServiceThread mHandlerThread;
+ Handler mHandler;
+ HandlerThread mHandlerThread;
+
+ private IBpcTestServiceCmdService.Stub mBinder = new IBpcTestServiceCmdService.Stub() {
+ IBpcCallbackObserver mCallbackObserver;
+
+ @Override
+ public void forceGc() {
+ int gcCount = Integer.parseInt(Debug.getRuntimeStat("art.gc.gc-count"));
+ int i = 20;
+ while (gcCount == Integer.parseInt(Debug.getRuntimeStat("art.gc.gc-count")) && i > 0) {
+ System.gc();
+ System.runFinalization();
+ i--;
+ }
+ }
+
+ @Override
+ public int getBinderProxyCount(int uid) {
+ return BinderInternal.nGetBinderProxyCount(uid);
+ }
+
+ @Override
+ public void setBinderProxyWatermarks(int high, int low) {
+ BinderInternal.nSetBinderProxyCountWatermarks(high, low);
+ }
+
+ @Override
+ public void enableBinderProxyLimit(boolean enable) {
+ BinderInternal.nSetBinderProxyCountEnabled(enable);
+ }
+
+ @Override
+ public void setBinderProxyCountCallback(IBpcCallbackObserver observer) {
+ if (observer != null) {
+ BinderInternal.setBinderProxyCountCallback(
+ new BinderInternal.BinderProxyLimitListener() {
+ @Override
+ public void onLimitReached(int uid) {
+ try {
+ synchronized (observer) {
+ observer.onCallback(uid);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+ }, mHandler);
+ } else {
+ BinderInternal.clearBinderProxyCountCallback();
+ }
+ }
+ };
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ @Override
+ public void onCreate()
+ {
+ mHandlerThread = new HandlerThread("BinderProxyCountingServiceThread");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ }
+} \ No newline at end of file
diff --git a/core/tests/coretests/aidl/Android.mk b/core/tests/coretests/aidl/Android.mk
new file mode 100644
index 000000000000..86e36b61a5ae
--- /dev/null
+++ b/core/tests/coretests/aidl/Android.mk
@@ -0,0 +1,22 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-subdir-Iaidl-files)
+LOCAL_MODULE := coretests-aidl
+include $(BUILD_STATIC_JAVA_LIBRARY) \ No newline at end of file
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBinderProxyCountingService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBinderProxyCountingService.aidl
new file mode 100644
index 000000000000..a69b0c58233a
--- /dev/null
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBinderProxyCountingService.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.frameworks.coretests.aidl;
+import com.android.frameworks.coretests.aidl.ITestRemoteCallback;
+
+interface IBinderProxyCountingService {
+ void registerCallback(in ITestRemoteCallback callback);
+ void unregisterCallback(in ITestRemoteCallback callback);
+} \ No newline at end of file
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl
new file mode 100644
index 000000000000..c4ebd56bed6c
--- /dev/null
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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.frameworks.coretests.aidl;
+
+interface IBpcCallbackObserver {
+ void onCallback(int uid);
+} \ No newline at end of file
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestAppCmdService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestAppCmdService.aidl
new file mode 100644
index 000000000000..86a0aa0ffc12
--- /dev/null
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestAppCmdService.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.frameworks.coretests.aidl;
+
+interface IBpcTestAppCmdService {
+ void createSystemBinders(int count);
+ void releaseSystemBinders(int count);
+
+ void createTestBinders(int count);
+ void releaseTestBinders(int count);
+
+ void releaseAllBinders();
+
+ String bindToTestService();
+ void unbindFromTestService();
+} \ No newline at end of file
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl
new file mode 100644
index 000000000000..abdab41ce537
--- /dev/null
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.frameworks.coretests.aidl;
+import com.android.frameworks.coretests.aidl.IBpcCallbackObserver;
+
+interface IBpcTestServiceCmdService {
+ void forceGc();
+ int getBinderProxyCount(int uid);
+ void setBinderProxyWatermarks(int high, int low);
+ void enableBinderProxyLimit(boolean enable);
+ void setBinderProxyCountCallback(IBpcCallbackObserver observer);
+} \ No newline at end of file
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestRemoteCallback.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestRemoteCallback.aidl
new file mode 100644
index 000000000000..36bdb6cc9c41
--- /dev/null
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestRemoteCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.frameworks.coretests.aidl;
+
+interface ITestRemoteCallback {
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
new file mode 100644
index 000000000000..6cdb35abce5a
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
@@ -0,0 +1,378 @@
+/*
+ * 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 android.os;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.util.Log;
+
+import com.android.frameworks.coretests.aidl.IBpcCallbackObserver;
+import com.android.frameworks.coretests.aidl.IBpcTestAppCmdService;
+import com.android.frameworks.coretests.aidl.IBpcTestServiceCmdService;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Tests for verifying the Binder Proxy Counting and Limiting.
+ *
+ * To manually build and install relevant test apps
+ *
+ * Build:
+ * mmma frameworks/base/core/tests/coretests/BinderProxyCountingTestApp
+ * mmma frameworks/base/core/tests/coretests/BinderProxyCountingTestService
+ * Install:
+ * adb install -r \
+ * ${ANDROID_PRODUCT_OUT}/data/app/BinderProxyCountingTestApp/BinderProxyCountingTestApp.apk
+ * adb install -r \
+ * ${ANDROID_PRODUCT_OUT}/data/app/BinderProxyCountingTestService/BinderProxyCountingTestService.apk
+ *
+ * To run the tests, use
+ *
+ * Build: m FrameworksCoreTests
+ * Install: adb install -r \
+ * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ * Run: adb shell am instrument -e class android.os.BinderProxyCountingTest -w \
+ * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+ *
+ * or
+ *
+ * bit FrameworksCoreTests:android.os.BinderProxyCountingTest
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class BinderProxyCountingTest {
+ private static final String TAG = BinderProxyCountingTest.class.getSimpleName();
+
+ private static final String TEST_APP_PKG =
+ "com.android.frameworks.coretests.binderproxycountingtestapp";
+ private static final String TEST_APP_CMD_SERVICE = TEST_APP_PKG + ".BpcTestAppCmdService";
+ private static final String TEST_SERVICE_PKG =
+ "com.android.frameworks.coretests.binderproxycountingtestservice";
+ private static final String TEST_SERVICE_CMD_SERVICE =
+ TEST_SERVICE_PKG + ".BpcTestServiceCmdService";
+
+ private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
+ private static final int TOO_MANY_BINDERS_TIMEOUT_SEC = 2;
+
+ // Keep in sync with sBinderProxyCountLimit in BpBinder.cpp
+ private static final int BINDER_PROXY_LIMIT = 2500;
+
+ private static Context sContext;
+ private static UiDevice sUiDevice;
+
+ private static ServiceConnection sTestAppConnection;
+ private static ServiceConnection sTestServiceConnection;
+ private static IBpcTestAppCmdService sBpcTestAppCmdService;
+ private static IBpcTestServiceCmdService sBpcTestServiceCmdService;
+ private static final Intent sTestAppIntent = new Intent()
+ .setComponent(new ComponentName(TEST_APP_PKG, TEST_APP_CMD_SERVICE));
+ private static final Intent sTestServiceIntent = new Intent()
+ .setComponent(new ComponentName(TEST_SERVICE_PKG, TEST_SERVICE_CMD_SERVICE));
+ private static final Consumer<IBinder> sTestAppConsumer = (service) -> {
+ sBpcTestAppCmdService = IBpcTestAppCmdService.Stub.asInterface(service);
+ };
+ private static final Consumer<IBinder> sTestServiceConsumer = (service) -> {
+ sBpcTestServiceCmdService = IBpcTestServiceCmdService.Stub.asInterface(service);
+ };
+ private static int sTestPkgUid;
+
+ /**
+ * Setup any common data for the upcoming tests.
+ */
+ @BeforeClass
+ public static void setUpOnce() throws Exception {
+ sContext = InstrumentationRegistry.getContext();
+ sTestPkgUid = sContext.getPackageManager().getPackageUid(TEST_APP_PKG, 0);
+ ((ActivityManager) sContext.getSystemService(Context.ACTIVITY_SERVICE)).killUid(sTestPkgUid,
+ "Wiping Test Package");
+
+ sUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ }
+
+ private ServiceConnection bindService(final Consumer<IBinder> consumer, Intent intent)
+ throws Exception {
+ final CountDownLatch bindLatch = new CountDownLatch(1);
+ ServiceConnection connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Log.i(TAG, "Service connected");
+ consumer.accept(service);
+ bindLatch.countDown();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.i(TAG, "Service disconnected");
+ }
+ };
+ sContext.bindService(intent, connection,
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_ALLOW_OOM_MANAGEMENT
+ | Context.BIND_NOT_FOREGROUND);
+ if (!bindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for the service to bind in " + sTestPkgUid);
+ }
+ return connection;
+ }
+
+
+ private void unbindService(ServiceConnection service) {
+ if (service != null) {
+ sContext.unbindService(service);
+ }
+ }
+
+ private void bindTestAppToTestService() throws Exception {
+ if (sBpcTestAppCmdService != null) {
+ String errorMessage = sBpcTestAppCmdService.bindToTestService();
+ if (errorMessage != null) {
+ fail(errorMessage);
+ }
+ }
+ }
+
+ private void unbindTestAppFromTestService() throws Exception {
+ if (sBpcTestAppCmdService != null) {
+ sBpcTestAppCmdService.unbindFromTestService();
+ }
+ }
+
+ private CountDownLatch createBinderLimitLatch() throws RemoteException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ sBpcTestServiceCmdService.setBinderProxyCountCallback(
+ new IBpcCallbackObserver.Stub() {
+ @Override
+ public void onCallback(int uid) {
+ if (uid == sTestPkgUid) {
+ latch.countDown();
+ }
+ }
+ });
+ return latch;
+ }
+
+ /**
+ * Get the Binder Proxy count held by SYSTEM for a given uid
+ */
+ private int getSystemBinderCount(int uid) throws Exception {
+ return Integer.parseInt(sUiDevice.executeShellCommand(
+ "dumpsys activity binder-proxies " + uid).trim());
+ }
+
+ @Test
+ public void testBinderProxyCount() throws Exception {
+ // Arbitrary list of Binder create and release
+ // Should cumulatively equal 0 and must never add up past the binder limit at any point
+ int[] testValues = {223, -103, -13, 25, 90, -222};
+ try {
+ sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
+ // Get the baseline of binders naturally held by the test Package
+ int expectedBinderCount = getSystemBinderCount(sTestPkgUid);
+
+ for (int testValue : testValues) {
+ if (testValue > 0) {
+ sBpcTestAppCmdService.createSystemBinders(testValue);
+ } else {
+ sBpcTestAppCmdService.releaseSystemBinders(-testValue);
+ }
+ expectedBinderCount += testValue;
+ int currentBinderCount = getSystemBinderCount(sTestPkgUid);
+ assertEquals("Current Binder Count (" + currentBinderCount
+ + ") does not equal expected Binder Count (" + expectedBinderCount
+ + ")", expectedBinderCount, currentBinderCount);
+ }
+ } finally {
+ unbindService(sTestAppConnection);
+ }
+ }
+
+ @Test
+ public void testBinderProxyLimitBoundary() throws Exception {
+ final int binderProxyLimit = 2000;
+ final int rearmThreshold = 1800;
+ try {
+ sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
+ sTestServiceConnection = bindService(sTestServiceConsumer, sTestServiceIntent);
+ bindTestAppToTestService();
+ sBpcTestServiceCmdService.enableBinderProxyLimit(true);
+
+ sBpcTestServiceCmdService.forceGc();
+ // Get the baseline of binders naturally held by the test Package
+ int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+
+ final CountDownLatch binderLimitLatch = createBinderLimitLatch();
+ sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold);
+
+ // Create Binder Proxies up to the limit
+ sBpcTestAppCmdService.createTestBinders(binderProxyLimit - baseBinderCount);
+ if (binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
+ + " when proxy limit should not have been reached");
+ }
+
+ // Create one more Binder to cross the limit
+ sBpcTestAppCmdService.createTestBinders(1);
+ if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
+ }
+
+ sBpcTestAppCmdService.releaseAllBinders();
+ } finally {
+ unbindTestAppFromTestService();
+ unbindService(sTestAppConnection);
+ unbindService(sTestServiceConnection);
+ }
+ }
+
+ @Test
+ public void testSetBinderProxyLimit() throws Exception {
+ int[] testLimits = {1000, 222, 800};
+ try {
+ sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
+ sTestServiceConnection = bindService(sTestServiceConsumer, sTestServiceIntent);
+ bindTestAppToTestService();
+ sBpcTestServiceCmdService.enableBinderProxyLimit(true);
+
+ sBpcTestServiceCmdService.forceGc();
+ int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+ for (int testLimit : testLimits) {
+ final CountDownLatch binderLimitLatch = createBinderLimitLatch();
+ // Change the BinderProxyLimit
+ sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10);
+ // Exceed the new Binder Proxy Limit
+ sBpcTestAppCmdService.createTestBinders(testLimit + 1);
+ if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
+ }
+
+ sBpcTestAppCmdService.releaseTestBinders(testLimit + 1);
+ sBpcTestServiceCmdService.forceGc();
+ }
+ } finally {
+ unbindTestAppFromTestService();
+ unbindService(sTestAppConnection);
+ unbindService(sTestServiceConnection);
+ }
+ }
+
+ @Test
+ public void testRearmCallbackThreshold() throws Exception {
+ final int binderProxyLimit = 2000;
+ final int exceedBinderProxyLimit = binderProxyLimit + 10;
+ final int rearmThreshold = 1800;
+ try {
+ sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
+ sTestServiceConnection = bindService(sTestServiceConsumer, sTestServiceIntent);
+ bindTestAppToTestService();
+ sBpcTestServiceCmdService.enableBinderProxyLimit(true);
+
+ sBpcTestServiceCmdService.forceGc();
+ final CountDownLatch firstBinderLimitLatch = createBinderLimitLatch();
+ sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold);
+ // Exceed the Binder Proxy Limit
+ sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit);
+ if (!firstBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
+ }
+
+ sBpcTestServiceCmdService.forceGc();
+ int currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+ // Drop to the threshold, this should not rearm the callback
+ sBpcTestAppCmdService.releaseTestBinders(currentBinderCount - rearmThreshold);
+
+ sBpcTestServiceCmdService.forceGc();
+ currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+
+ final CountDownLatch secondBinderLimitLatch = createBinderLimitLatch();
+ // Exceed the Binder Proxy limit which should not cause a callback since there has
+ // been no rearm
+ sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount);
+ if (secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
+ + " when the callback has not been rearmed yet");
+ }
+
+ sBpcTestServiceCmdService.forceGc();
+ currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+ // Drop below the rearmThreshold to rearm the BinderProxyLimitCallback
+ sBpcTestAppCmdService.releaseTestBinders(currentBinderCount - rearmThreshold + 1);
+
+ sBpcTestServiceCmdService.forceGc();
+ currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+ // Exceed the Binder Proxy limit for the last time
+ sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount);
+
+ if (!secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
+ }
+ sBpcTestAppCmdService.releaseTestBinders(currentBinderCount);
+ } finally {
+ unbindTestAppFromTestService();
+ unbindService(sTestAppConnection);
+ unbindService(sTestServiceConnection);
+ }
+ }
+
+ @Test
+ public void testKillBadBehavingApp() throws Exception {
+ final CountDownLatch binderDeathLatch = new CountDownLatch(1);
+ final int exceedBinderProxyLimit = BINDER_PROXY_LIMIT + 1;
+
+ try {
+ sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
+ sBpcTestAppCmdService.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ Log.v(TAG, "BpcTestAppCmdService died!");
+ binderDeathLatch.countDown();
+ }
+ }, 0);
+ try {
+ // Exceed the Binder Proxy Limit emulating a bad behaving app
+ sBpcTestAppCmdService.createSystemBinders(exceedBinderProxyLimit);
+ } catch (DeadObjectException doe) {
+ // We are expecting the service to get killed mid call, so a DeadObjectException
+ // is not unexpected
+ }
+
+ if (!binderDeathLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ sBpcTestAppCmdService.releaseSystemBinders(exceedBinderProxyLimit);
+ fail("Timed out waiting for uid " + sTestPkgUid + " to die.");
+ }
+
+ } finally {
+ unbindService(sTestAppConnection);
+ }
+ }
+}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 770a57a5c445..c468038d61c2 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -43,6 +43,11 @@ cc_defaults {
device_uses_hwc2: {
cflags: ["-DUSE_HWC2"],
},
+ eng: {
+ lto: {
+ never: true,
+ },
+ },
},
}
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 616558f29676..648fd35d787c 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -135,8 +135,6 @@ static bool setBenchmarkFormat(const char* format) {
gBenchmarkReporter.reset(new benchmark::ConsoleReporter());
} else if (!strcmp(format, "json")) {
gBenchmarkReporter.reset(new benchmark::JSONReporter());
- } else if (!strcmp(format, "csv")) {
- gBenchmarkReporter.reset(new benchmark::CSVReporter());
} else {
fprintf(stderr, "Unknown format '%s'", format);
return false;
diff --git a/services/Android.bp b/services/Android.bp
index d125adc5fa7d..bea51be321c9 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -2,6 +2,7 @@
// ============================================================
java_library {
name: "services",
+ installable: true,
dex_preopt: {
app_image: true,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1546ec176f39..02d5d26723dc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -380,6 +380,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.BinderInternal;
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
@@ -14366,6 +14367,23 @@ public class ActivityManagerService extends IActivityManager.Stub
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
+
+ BinderInternal.nSetBinderProxyCountEnabled(true);
+ BinderInternal.setBinderProxyCountCallback(
+ new BinderInternal.BinderProxyLimitListener() {
+ @Override
+ public void onLimitReached(int uid) {
+ Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
+ + Process.myUid());
+ if (uid == Process.SYSTEM_UID) {
+ Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
+ } else {
+ killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
+ "Too many Binders sent to SYSTEM");
+ }
+ }
+ }, mHandler);
+
traceLog.traceEnd(); // ActivityManagerStartApps
traceLog.traceEnd(); // PhaseActivityManagerReady
}
@@ -15134,6 +15152,19 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
}
+ } else if ("binder-proxies".equals(cmd)) {
+ if (opti >= args.length) {
+ dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(),
+ "Counts of Binder Proxies held by SYSTEM");
+ } else {
+ String uid = args[opti];
+ opti++;
+ // Ensure Binder Proxy Count is as up to date as possible
+ System.gc();
+ System.runFinalization();
+ System.gc();
+ pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
+ }
} else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
String[] newArgs;
String name;
@@ -15663,6 +15694,34 @@ public class ActivityManagerService extends IActivityManager.Stub
return printed;
}
+ boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) {
+ if(counts != null) {
+ pw.println(header);
+ for (int i = 0; i < counts.size(); i++) {
+ final int uid = counts.keyAt(i);
+ final int binderCount = counts.valueAt(i);
+ pw.print(" UID ");
+ pw.print(uid);
+ pw.print(", binder count = ");
+ pw.print(binderCount);
+ pw.print(", package(s)= ");
+ final String[] pkgNames = mContext.getPackageManager().getPackagesForUid(uid);
+ if (pkgNames != null) {
+ for (int j = 0; j < pkgNames.length; j++) {
+ pw.print(pkgNames[j]);
+ pw.print("; ");
+ }
+ } else {
+ pw.print("NO PACKAGE NAME FOUND");
+ }
+ pw.println();
+ }
+ pw.println();
+ return true;
+ }
+ return false;
+ }
+
void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, String dumpPackage) {
boolean needSep = false;
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 890a6ea7c88e..2a41829dcc2f 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -175,7 +175,10 @@ public abstract class CellIdentity implements Parcelable {
}
CellIdentity o = (CellIdentity) other;
- return TextUtils.equals(mAlphaLong, o.mAlphaLong)
+ return mType == o.mType
+ && TextUtils.equals(mMccStr, o.mMccStr)
+ && TextUtils.equals(mMncStr, o.mMncStr)
+ && TextUtils.equals(mAlphaLong, o.mAlphaLong)
&& TextUtils.equals(mAlphaShort, o.mAlphaShort);
}
@@ -233,4 +236,4 @@ public abstract class CellIdentity implements Parcelable {
protected void log(String s) {
Rlog.w(mTag, s);
}
-} \ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 3070bd149bba..feff238092d4 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -16,8 +16,8 @@
package android.telephony;
+import android.annotation.Nullable;
import android.os.Parcel;
-import android.text.TextUtils;
import java.util.Objects;
@@ -34,6 +34,8 @@ public final class CellIdentityTdscdma extends CellIdentity {
private final int mCid;
// 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown.
private final int mCpid;
+ // 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
+ private final int mUarfcn;
/**
* @hide
@@ -43,6 +45,7 @@ public final class CellIdentityTdscdma extends CellIdentity {
mLac = Integer.MAX_VALUE;
mCid = Integer.MAX_VALUE;
mCpid = Integer.MAX_VALUE;
+ mUarfcn = Integer.MAX_VALUE;
}
/**
@@ -51,28 +54,12 @@ public final class CellIdentityTdscdma extends CellIdentity {
* @param lac 16-bit Location Area Code, 0..65535, INT_MAX if unknown
* @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown
* @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown
+ * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
*
* @hide
*/
- public CellIdentityTdscdma(int mcc, int mnc, int lac, int cid, int cpid) {
- this(String.valueOf(mcc), String.valueOf(mnc), lac, cid, cpid, null, null);
- }
-
- /**
- * @param mcc 3-digit Mobile Country Code in string format
- * @param mnc 2 or 3-digit Mobile Network Code in string format
- * @param lac 16-bit Location Area Code, 0..65535, INT_MAX if unknown
- * @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown
- * @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown
- *
- * FIXME: This is a temporary constructor to facilitate migration.
- * @hide
- */
- public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid) {
- super(TAG, TYPE_TDSCDMA, mcc, mnc, null, null);
- mLac = lac;
- mCid = cid;
- mCpid = cpid;
+ public CellIdentityTdscdma(int mcc, int mnc, int lac, int cid, int cpid, int uarfcn) {
+ this(String.valueOf(mcc), String.valueOf(mnc), lac, cid, cpid, uarfcn, null, null);
}
/**
@@ -81,22 +68,24 @@ public final class CellIdentityTdscdma extends CellIdentity {
* @param lac 16-bit Location Area Code, 0..65535, INT_MAX if unknown
* @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown
* @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown
+ * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
* @param alphal long alpha Operator Name String or Enhanced Operator Name String
* @param alphas short alpha Operator Name String or Enhanced Operator Name String
*
* @hide
*/
- public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid,
+ public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn,
String alphal, String alphas) {
super(TAG, TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
mLac = lac;
mCid = cid;
mCpid = cpid;
+ mUarfcn = uarfcn;
}
private CellIdentityTdscdma(CellIdentityTdscdma cid) {
this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid,
- cid.mCpid, cid.mAlphaLong, cid.mAlphaShort);
+ cid.mCpid, cid.mUarfcn, cid.mAlphaLong, cid.mAlphaShort);
}
CellIdentityTdscdma copy() {
@@ -140,9 +129,32 @@ public final class CellIdentityTdscdma extends CellIdentity {
return mCpid;
}
+ /** @hide */
@Override
- public int hashCode() {
- return Objects.hash(mLac, mCid, mCpid, super.hashCode());
+ public int getChannelNumber() {
+ return mUarfcn;
+ }
+
+ /**
+ * @return The long alpha tag associated with the current scan result (may be the operator
+ * name string or extended operator name string). May be null if unknown.
+ *
+ * @hide
+ */
+ @Nullable
+ public CharSequence getOperatorAlphaLong() {
+ return mAlphaLong;
+ }
+
+ /**
+ * @return The short alpha tag associated with the current scan result (may be the operator
+ * name string or extended operator name string). May be null if unknown.
+ *
+ * @hide
+ */
+ @Nullable
+ public CharSequence getOperatorAlphaShort() {
+ return mAlphaShort;
}
@Override
@@ -156,24 +168,29 @@ public final class CellIdentityTdscdma extends CellIdentity {
}
CellIdentityTdscdma o = (CellIdentityTdscdma) other;
- return TextUtils.equals(mMccStr, o.mMccStr)
- && TextUtils.equals(mMncStr, o.mMncStr)
- && mLac == o.mLac
+ return mLac == o.mLac
&& mCid == o.mCid
&& mCpid == o.mCpid
+ && mUarfcn == o.mUarfcn
&& super.equals(other);
}
@Override
+ public int hashCode() {
+ return Objects.hash(mLac, mCid, mCpid, mUarfcn, super.hashCode());
+ }
+
+ @Override
public String toString() {
return new StringBuilder(TAG)
.append(":{ mMcc=").append(mMccStr)
.append(" mMnc=").append(mMncStr)
+ .append(" mAlphaLong=").append(mAlphaLong)
+ .append(" mAlphaShort=").append(mAlphaShort)
.append(" mLac=").append(mLac)
.append(" mCid=").append(mCid)
.append(" mCpid=").append(mCpid)
- .append(" mAlphaLong=").append(mAlphaLong)
- .append(" mAlphaShort=").append(mAlphaShort)
+ .append(" mUarfcn=").append(mUarfcn)
.append("}").toString();
}
@@ -185,6 +202,7 @@ public final class CellIdentityTdscdma extends CellIdentity {
dest.writeInt(mLac);
dest.writeInt(mCid);
dest.writeInt(mCpid);
+ dest.writeInt(mUarfcn);
}
/** Construct from Parcel, type has already been processed */
@@ -193,7 +211,7 @@ public final class CellIdentityTdscdma extends CellIdentity {
mLac = in.readInt();
mCid = in.readInt();
mCpid = in.readInt();
-
+ mUarfcn = in.readInt();
if (DBG) log(toString());
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index f1167a6d21e8..b7f8fc8cd037 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -34,7 +34,7 @@ public final class CellIdentityWcdma extends CellIdentity {
private final int mCid;
// 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511
private final int mPsc;
- // 16-bit UMTS Absolute RF Channel Number
+ // 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.4
private final int mUarfcn;
/**
@@ -69,7 +69,7 @@ public final class CellIdentityWcdma extends CellIdentity {
* @param lac 16-bit Location Area Code, 0..65535
* @param cid 28-bit UMTS Cell Identity
* @param psc 9-bit UMTS Primary Scrambling Code
- * @param uarfcn 16-bit UMTS Absolute RF Channel Number
+ * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
*
* @hide
*/
@@ -82,7 +82,7 @@ public final class CellIdentityWcdma extends CellIdentity {
* @param lac 16-bit Location Area Code, 0..65535
* @param cid 28-bit UMTS Cell Identity
* @param psc 9-bit UMTS Primary Scrambling Code
- * @param uarfcn 16-bit UMTS Absolute RF Channel Number
+ * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
* @param mccStr 3-digit Mobile Country Code in string format
* @param mncStr 2 or 3-digit Mobile Network Code in string format
* @param alphal long alpha Operator Name String or Enhanced Operator Name String
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 9232ed7167cc..3aab3fc9e199 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -19,6 +19,7 @@ package android.telephony;
import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,6 +37,8 @@ public abstract class CellInfo implements Parcelable {
protected static final int TYPE_LTE = 3;
/** @hide */
protected static final int TYPE_WCDMA = 4;
+ /** @hide */
+ protected static final int TYPE_TDCDMA = 5;
// Type to distinguish where time stamp gets recorded.
@@ -260,6 +263,7 @@ public abstract class CellInfo implements Parcelable {
case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in);
case TYPE_LTE: return CellInfoLte.createFromParcelBody(in);
case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in);
+ case TYPE_TDCDMA: return CellInfoTdscdma.createFromParcelBody(in);
default: throw new RuntimeException("Bad CellInfo Parcel");
}
}
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index 6f2f1f677859..6403bc5a16a1 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -21,7 +21,7 @@ import android.os.Parcelable;
import android.telephony.Rlog;
/**
- * Immutable cell information from a point in time.
+ * A {@link CellInfo} representing a CDMA cell that provides identity and measurement info.
*/
public final class CellInfoCdma extends CellInfo implements Parcelable {
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 1bedddb6b794..a3a9b315241e 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -21,7 +21,7 @@ import android.os.Parcelable;
import android.telephony.Rlog;
/**
- * Immutable cell information from a point in time.
+ * A {@link CellInfo} representing a GSM cell that provides identity and measurement info.
*/
public final class CellInfoGsm extends CellInfo implements Parcelable {
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 287c9f044a07..b892e89a8517 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -21,7 +21,7 @@ import android.os.Parcelable;
import android.telephony.Rlog;
/**
- * Immutable cell information from a point in time.
+ * A {@link CellInfo} representing an LTE cell that provides identity and measurement info.
*/
public final class CellInfoLte extends CellInfo implements Parcelable {
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
new file mode 100644
index 000000000000..7084c51f1b8a
--- /dev/null
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -0,0 +1,151 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * A {@link CellInfo} representing a TD-SCDMA cell that provides identity and measurement info.
+ *
+ * @hide
+ */
+public final class CellInfoTdscdma extends CellInfo implements Parcelable {
+
+ private static final String LOG_TAG = "CellInfoTdscdma";
+ private static final boolean DBG = false;
+
+ private CellIdentityTdscdma mCellIdentityTdscdma;
+ private CellSignalStrengthTdscdma mCellSignalStrengthTdscdma;
+
+ /** @hide */
+ public CellInfoTdscdma() {
+ super();
+ mCellIdentityTdscdma = new CellIdentityTdscdma();
+ mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma();
+ }
+
+ /** @hide */
+ public CellInfoTdscdma(CellInfoTdscdma ci) {
+ super(ci);
+ this.mCellIdentityTdscdma = ci.mCellIdentityTdscdma.copy();
+ this.mCellSignalStrengthTdscdma = ci.mCellSignalStrengthTdscdma.copy();
+ }
+
+ public CellIdentityTdscdma getCellIdentity() {
+ return mCellIdentityTdscdma;
+ }
+ /** @hide */
+ public void setCellIdentity(CellIdentityTdscdma cid) {
+ mCellIdentityTdscdma = cid;
+ }
+
+ public CellSignalStrengthTdscdma getCellSignalStrength() {
+ return mCellSignalStrengthTdscdma;
+ }
+ /** @hide */
+ public void setCellSignalStrength(CellSignalStrengthTdscdma css) {
+ mCellSignalStrengthTdscdma = css;
+ }
+
+ /**
+ * @return hash code
+ */
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), mCellIdentityTdscdma, mCellSignalStrengthTdscdma);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!super.equals(other)) {
+ return false;
+ }
+ try {
+ CellInfoTdscdma o = (CellInfoTdscdma) other;
+ return mCellIdentityTdscdma.equals(o.mCellIdentityTdscdma)
+ && mCellSignalStrengthTdscdma.equals(o.mCellSignalStrengthTdscdma);
+ } catch (ClassCastException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("CellInfoTdscdma:{");
+ sb.append(super.toString());
+ sb.append(" ").append(mCellIdentityTdscdma);
+ sb.append(" ").append(mCellSignalStrengthTdscdma);
+ sb.append("}");
+
+ return sb.toString();
+ }
+
+ /** Implement the Parcelable interface */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags, TYPE_TDCDMA);
+ mCellIdentityTdscdma.writeToParcel(dest, flags);
+ mCellSignalStrengthTdscdma.writeToParcel(dest, flags);
+ }
+
+ /**
+ * Construct a CellInfoTdscdma object from the given parcel
+ * where the token is already been processed.
+ */
+ private CellInfoTdscdma(Parcel in) {
+ super(in);
+ mCellIdentityTdscdma = CellIdentityTdscdma.CREATOR.createFromParcel(in);
+ mCellSignalStrengthTdscdma = CellSignalStrengthTdscdma.CREATOR.createFromParcel(in);
+ }
+
+ /** Implement the Parcelable interface */
+ public static final Creator<CellInfoTdscdma> CREATOR = new Creator<CellInfoTdscdma>() {
+ @Override
+ public CellInfoTdscdma createFromParcel(Parcel in) {
+ in.readInt(); // Skip past token, we know what it is
+ return createFromParcelBody(in);
+ }
+
+ @Override
+ public CellInfoTdscdma[] newArray(int size) {
+ return new CellInfoTdscdma[size];
+ }
+ };
+
+ /** @hide */
+ protected static CellInfoTdscdma createFromParcelBody(Parcel in) {
+ return new CellInfoTdscdma(in);
+ }
+
+ /**
+ * log
+ */
+ private static void log(String s) {
+ Rlog.w(LOG_TAG, s);
+ }
+}
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 06157022de34..005f3d341ec1 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -20,8 +20,10 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;
+import java.util.Objects;
+
/**
- * Immutable cell information from a point in time.
+ * A {@link CellInfo} representing a WCDMA cell that provides identity and measurement info.
*/
public final class CellInfoWcdma extends CellInfo implements Parcelable {
@@ -66,7 +68,7 @@ public final class CellInfoWcdma extends CellInfo implements Parcelable {
*/
@Override
public int hashCode() {
- return super.hashCode() + mCellIdentityWcdma.hashCode() + mCellSignalStrengthWcdma.hashCode();
+ return Objects.hash(super.hashCode(), mCellIdentityWcdma, mCellSignalStrengthWcdma);
}
@Override
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 183f96ddab0b..aa6b207d2f31 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -104,7 +104,10 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements
}
/**
- * Get signal level as an int from 0..4
+ * Retrieve an abstract level value for the overall signal strength.
+ *
+ * @return a single integer from 0 to 4 representing the general signal quality.
+ * 0 represents very poor signal strength while 4 represents a very strong signal strength.
*/
@Override
public int getLevel() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 8687cd1c454b..cff159b991c0 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -82,7 +82,10 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P
}
/**
- * Get signal level as an int from 0..4
+ * Retrieve an abstract level value for the overall signal strength.
+ *
+ * @return a single integer from 0 to 4 representing the general signal quality.
+ * 0 represents very poor signal strength while 4 represents a very strong signal strength.
*/
@Override
public int getLevel() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 2b6928e2e4f1..2f059f412b64 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -86,7 +86,10 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
}
/**
- * Get signal level as an int from 0..4
+ * Retrieve an abstract level value for the overall signal strength.
+ *
+ * @return a single integer from 0 to 4 representing the general signal quality.
+ * 0 represents very poor signal strength while 4 represents a very strong signal strength.
*/
@Override
public int getLevel() {
diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
new file mode 100644
index 000000000000..41859a3e96d9
--- /dev/null
+++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
@@ -0,0 +1,228 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Tdscdma signal strength related information.
+ *
+ * @hide
+ */
+public final class CellSignalStrengthTdscdma extends CellSignalStrength implements Parcelable {
+
+ private static final String LOG_TAG = "CellSignalStrengthTdscdma";
+ private static final boolean DBG = false;
+
+ private static final int TDSCDMA_SIGNAL_STRENGTH_GREAT = 12;
+ private static final int TDSCDMA_SIGNAL_STRENGTH_GOOD = 8;
+ private static final int TDSCDMA_SIGNAL_STRENGTH_MODERATE = 5;
+
+ private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
+ // or Integer.MAX_VALUE if unknown
+ private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
+ // Integer.MAX_VALUE if unknown
+ private int mRscp; // Pilot power (0-96, 255) as defined in TS 27.007 8.69 or Integer.MAX_VALUE
+ // if unknown
+
+ /** @hide */
+ public CellSignalStrengthTdscdma() {
+ setDefaultValues();
+ }
+
+ /** @hide */
+ public CellSignalStrengthTdscdma(int ss, int ber, int rscp) {
+ mSignalStrength = ss;
+ mBitErrorRate = ber;
+ mRscp = rscp;
+ }
+
+ /** @hide */
+ public CellSignalStrengthTdscdma(CellSignalStrengthTdscdma s) {
+ copyFrom(s);
+ }
+
+ /** @hide */
+ protected void copyFrom(CellSignalStrengthTdscdma s) {
+ mSignalStrength = s.mSignalStrength;
+ mBitErrorRate = s.mBitErrorRate;
+ mRscp = s.mRscp;
+ }
+
+ /** @hide */
+ @Override
+ public CellSignalStrengthTdscdma copy() {
+ return new CellSignalStrengthTdscdma(this);
+ }
+
+ /** @hide */
+ @Override
+ public void setDefaultValues() {
+ mSignalStrength = Integer.MAX_VALUE;
+ mBitErrorRate = Integer.MAX_VALUE;
+ mRscp = Integer.MAX_VALUE;
+ }
+
+ /**
+ * Retrieve an abstract level value for the overall signal strength.
+ *
+ * @return a single integer from 0 to 4 representing the general signal quality.
+ * 0 represents very poor signal strength while 4 represents a very strong signal strength.
+ */
+ @Override
+ public int getLevel() {
+ int level;
+
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int asu = mSignalStrength;
+ if (asu <= 2 || asu == 99) {
+ level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GREAT) {
+ level = SIGNAL_STRENGTH_GREAT;
+ } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GOOD) {
+ level = SIGNAL_STRENGTH_GOOD;
+ } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_MODERATE) {
+ level = SIGNAL_STRENGTH_MODERATE;
+ } else {
+ level = SIGNAL_STRENGTH_POOR;
+ }
+ if (DBG) log("getLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the signal strength as dBm
+ */
+ @Override
+ public int getDbm() {
+ int dBm;
+
+ int level = mSignalStrength;
+ int asu = (level == 99 ? Integer.MAX_VALUE : level);
+ if (asu != Integer.MAX_VALUE) {
+ dBm = -113 + (2 * asu);
+ } else {
+ dBm = Integer.MAX_VALUE;
+ }
+ if (DBG) log("getDbm=" + dBm);
+ return dBm;
+ }
+
+ /**
+ * Get the signal level as an asu value between 0..31, 99 is unknown
+ * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ */
+ @Override
+ public int getAsuLevel() {
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int level = mSignalStrength;
+ if (DBG) log("getAsuLevel=" + level);
+ return level;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSignalStrength, mBitErrorRate);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ CellSignalStrengthTdscdma s;
+
+ try {
+ s = (CellSignalStrengthTdscdma) o;
+ } catch (ClassCastException ex) {
+ return false;
+ }
+
+ if (o == null) {
+ return false;
+ }
+
+ return mSignalStrength == s.mSignalStrength
+ && mBitErrorRate == s.mBitErrorRate
+ && mRscp == s.mRscp;
+ }
+
+ /**
+ * @return string representation.
+ */
+ @Override
+ public String toString() {
+ return "CellSignalStrengthTdscdma:"
+ + " ss=" + mSignalStrength
+ + " ber=" + mBitErrorRate
+ + " rscp=" + mRscp;
+ }
+
+ /** Implement the Parcelable interface */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (DBG) log("writeToParcel(Parcel, int): " + toString());
+ dest.writeInt(mSignalStrength);
+ dest.writeInt(mBitErrorRate);
+ dest.writeInt(mRscp);
+ }
+
+ /**
+ * Construct a SignalStrength object from the given parcel
+ * where the token is already been processed.
+ */
+ private CellSignalStrengthTdscdma(Parcel in) {
+ mSignalStrength = in.readInt();
+ mBitErrorRate = in.readInt();
+ mRscp = in.readInt();
+ if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString());
+ }
+
+ /** Implement the Parcelable interface */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface */
+ @SuppressWarnings("hiding")
+ public static final Parcelable.Creator<CellSignalStrengthTdscdma> CREATOR =
+ new Parcelable.Creator<CellSignalStrengthTdscdma>() {
+ @Override
+ public CellSignalStrengthTdscdma createFromParcel(Parcel in) {
+ return new CellSignalStrengthTdscdma(in);
+ }
+
+ @Override
+ public CellSignalStrengthTdscdma[] newArray(int size) {
+ return new CellSignalStrengthTdscdma[size];
+ }
+ };
+
+ /**
+ * log
+ */
+ private static void log(String s) {
+ Rlog.w(LOG_TAG, s);
+ }
+}
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index dd32a960db91..21cf0be96931 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -35,7 +35,13 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
- private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
+ // or Integer.MAX_VALUE if unknown
+ private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
+ // Integer.MAX_VALUE if unknown
+ private int mRscp; // bit error rate (0-96, 255) as defined in TS 27.007 8.69 or
+ // Integer.MAX_VALUE if unknown
+ private int mEcNo; // signal to noise radio (0-49, 255) as defined in TS 27.007 8.69 or
+ // Integer.MAX_VALUE if unknown
/** @hide */
public CellSignalStrengthWcdma() {
@@ -43,9 +49,11 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
}
/** @hide */
- public CellSignalStrengthWcdma(int ss, int ber) {
+ public CellSignalStrengthWcdma(int ss, int ber, int rscp, int ecno) {
mSignalStrength = ss;
mBitErrorRate = ber;
+ mRscp = rscp;
+ mEcNo = ecno;
}
/** @hide */
@@ -57,6 +65,8 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
protected void copyFrom(CellSignalStrengthWcdma s) {
mSignalStrength = s.mSignalStrength;
mBitErrorRate = s.mBitErrorRate;
+ mRscp = s.mRscp;
+ mEcNo = s.mEcNo;
}
/** @hide */
@@ -70,10 +80,15 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
public void setDefaultValues() {
mSignalStrength = Integer.MAX_VALUE;
mBitErrorRate = Integer.MAX_VALUE;
+ mRscp = Integer.MAX_VALUE;
+ mEcNo = Integer.MAX_VALUE;
}
/**
- * Get signal level as an int from 0..4
+ * Retrieve an abstract level value for the overall signal strength.
+ *
+ * @return a single integer from 0 to 4 representing the general signal quality.
+ * 0 represents very poor signal strength while 4 represents a very strong signal strength.
*/
@Override
public int getLevel() {
@@ -145,7 +160,10 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
return false;
}
- return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate;
+ return mSignalStrength == s.mSignalStrength
+ && mBitErrorRate == s.mBitErrorRate
+ && mRscp == s.mRscp
+ && mEcNo == s.mEcNo;
}
/**
@@ -155,7 +173,9 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
public String toString() {
return "CellSignalStrengthWcdma:"
+ " ss=" + mSignalStrength
- + " ber=" + mBitErrorRate;
+ + " ber=" + mBitErrorRate
+ + " rscp=" + mRscp
+ + " ecno=" + mEcNo;
}
/** Implement the Parcelable interface */
@@ -164,6 +184,8 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
if (DBG) log("writeToParcel(Parcel, int): " + toString());
dest.writeInt(mSignalStrength);
dest.writeInt(mBitErrorRate);
+ dest.writeInt(mRscp);
+ dest.writeInt(mEcNo);
}
/**
@@ -173,6 +195,8 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements
private CellSignalStrengthWcdma(Parcel in) {
mSignalStrength = in.readInt();
mBitErrorRate = in.readInt();
+ mRscp = in.readInt();
+ mEcNo = in.readInt();
if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index e881549489a3..c3931557feb3 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.TransportType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -59,15 +60,15 @@ public class NetworkRegistrationState implements Parcelable {
/** Not registered. The device is not currently searching a new operator to register */
public static final int REG_STATE_NOT_REG_NOT_SEARCHING = 0;
/** Registered on home network */
- public static final int REG_STATE_HOME = 1;
+ public static final int REG_STATE_HOME = 1;
/** Not registered. The device is currently searching a new operator to register */
- public static final int REG_STATE_NOT_REG_SEARCHING = 2;
+ public static final int REG_STATE_NOT_REG_SEARCHING = 2;
/** Registration denied */
- public static final int REG_STATE_DENIED = 3;
+ public static final int REG_STATE_DENIED = 3;
/** Registration state is unknown */
- public static final int REG_STATE_UNKNOWN = 4;
+ public static final int REG_STATE_UNKNOWN = 4;
/** Registered on roaming network */
- public static final int REG_STATE_ROAMING = 5;
+ public static final int REG_STATE_ROAMING = 5;
/**
* Supported service type
@@ -79,16 +80,16 @@ public class NetworkRegistrationState implements Parcelable {
SERVICE_TYPE_EMERGENCY})
public @interface ServiceType {}
- public static final int SERVICE_TYPE_VOICE = 1;
- public static final int SERVICE_TYPE_DATA = 2;
- public static final int SERVICE_TYPE_SMS = 3;
- public static final int SERVICE_TYPE_VIDEO = 4;
- public static final int SERVICE_TYPE_EMERGENCY = 5;
+ public static final int SERVICE_TYPE_VOICE = 1;
+ public static final int SERVICE_TYPE_DATA = 2;
+ public static final int SERVICE_TYPE_SMS = 3;
+ public static final int SERVICE_TYPE_VIDEO = 4;
+ public static final int SERVICE_TYPE_EMERGENCY = 5;
@Domain
private final int mDomain;
- /** {@link AccessNetworkConstants.TransportType}*/
+ /** {@link TransportType} */
private final int mTransportType;
@RegState
@@ -96,7 +97,7 @@ public class NetworkRegistrationState implements Parcelable {
private final int mAccessNetworkTechnology;
- private final int mReasonForDenial;
+ private final int mRejectCause;
private final boolean mEmergencyOnly;
@@ -112,22 +113,35 @@ public class NetworkRegistrationState implements Parcelable {
private DataSpecificRegistrationStates mDataSpecificStates;
/**
- * @param domain Network domain. Must be DOMAIN_CS or DOMAIN_PS.
- * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType}
- * @param regState Network registration state.
- * @param accessNetworkTechnology See TelephonyManager NETWORK_TYPE_XXXX.
- * @param reasonForDenial Reason for denial if the registration state is DENIED.
- * @param availableServices The supported service.
- * @param cellIdentity The identity representing a unique cell
+ * @param domain Network domain. Must be a {@link Domain}. For {@link TransportType#WLAN}
+ * transport, this must set to {@link #DOMAIN_PS}.
+ * @param transportType Transport type. Must be one of the{@link TransportType}.
+ * @param regState Network registration state. Must be one of the {@link RegState}. For
+ * {@link TransportType#WLAN} transport, only {@link #REG_STATE_HOME} and
+ * {@link #REG_STATE_NOT_REG_NOT_SEARCHING} are valid states.
+ * @param accessNetworkTechnology Access network technology. Must be one of TelephonyManager
+ * NETWORK_TYPE_XXXX. For {@link TransportType#WLAN} transport, set to
+ * {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
+ * @param rejectCause Reason for denial if the registration state is {@link #REG_STATE_DENIED}.
+ * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
+ * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA. If
+ * the reject cause is not supported or unknown, set it to 0.
+ * // TODO: Add IWLAN reject cause reference
+ * @param emergencyOnly True if this registration is for emergency only.
+ * @param availableServices The list of the supported services. Each element must be one of
+ * the {@link ServiceType}.
+ * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the
+ * information is not available.
*/
- public NetworkRegistrationState(int domain, int transportType, int regState,
- int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
- int[] availableServices, @Nullable CellIdentity cellIdentity) {
+ public NetworkRegistrationState(@Domain int domain, int transportType, @RegState int regState,
+ int accessNetworkTechnology, int rejectCause,
+ boolean emergencyOnly, int[] availableServices,
+ @Nullable CellIdentity cellIdentity) {
mDomain = domain;
mTransportType = transportType;
mRegState = regState;
mAccessNetworkTechnology = accessNetworkTechnology;
- mReasonForDenial = reasonForDenial;
+ mRejectCause = rejectCause;
mAvailableServices = availableServices;
mCellIdentity = cellIdentity;
mEmergencyOnly = emergencyOnly;
@@ -138,11 +152,13 @@ public class NetworkRegistrationState implements Parcelable {
* @hide
*/
public NetworkRegistrationState(int domain, int transportType, int regState,
- int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
- int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported,
- int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) {
- this(domain, transportType, regState, accessNetworkTechnology,
- reasonForDenial, emergencyOnly, availableServices, cellIdentity);
+ int accessNetworkTechnology, int rejectCause,
+ boolean emergencyOnly, int[] availableServices,
+ @Nullable CellIdentity cellIdentity, boolean cssSupported,
+ int roamingIndicator, int systemIsInPrl,
+ int defaultRoamingIndicator) {
+ this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
+ availableServices, cellIdentity);
mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
systemIsInPrl, defaultRoamingIndicator);
@@ -153,10 +169,11 @@ public class NetworkRegistrationState implements Parcelable {
* @hide
*/
public NetworkRegistrationState(int domain, int transportType, int regState,
- int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly,
- int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls) {
- this(domain, transportType, regState, accessNetworkTechnology,
- reasonForDenial, emergencyOnly, availableServices, cellIdentity);
+ int accessNetworkTechnology, int rejectCause,
+ boolean emergencyOnly, int[] availableServices,
+ @Nullable CellIdentity cellIdentity, int maxDataCalls) {
+ this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
+ availableServices, cellIdentity);
mDataSpecificStates = new DataSpecificRegistrationStates(maxDataCalls);
}
@@ -166,7 +183,7 @@ public class NetworkRegistrationState implements Parcelable {
mTransportType = source.readInt();
mRegState = source.readInt();
mAccessNetworkTechnology = source.readInt();
- mReasonForDenial = source.readInt();
+ mRejectCause = source.readInt();
mEmergencyOnly = source.readBoolean();
mAvailableServices = source.createIntArray();
mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
@@ -211,10 +228,10 @@ public class NetworkRegistrationState implements Parcelable {
}
/**
- * @return Reason for denial from network.
+ * @return Network reject cause
*/
- public int getReasonForDenial() {
- return mReasonForDenial;
+ public int getRejectCause() {
+ return mRejectCause;
}
/**
@@ -265,7 +282,7 @@ public class NetworkRegistrationState implements Parcelable {
.append(" regState=").append(regStateToString(mRegState))
.append(" accessNetworkTechnology=")
.append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
- .append(" reasonForDenial=").append(mReasonForDenial)
+ .append(" rejectCause=").append(mRejectCause)
.append(" emergencyEnabled=").append(mEmergencyOnly)
.append(" supportedServices=").append(mAvailableServices)
.append(" cellIdentity=").append(mCellIdentity)
@@ -276,8 +293,8 @@ public class NetworkRegistrationState implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(mTransportType, mDomain, mRegState, mAccessNetworkTechnology,
- mReasonForDenial, mEmergencyOnly, mAvailableServices, mCellIdentity,
+ return Objects.hash(mDomain, mTransportType, mRegState, mAccessNetworkTechnology,
+ mRejectCause, mEmergencyOnly, mAvailableServices, mCellIdentity,
mVoiceSpecificStates, mDataSpecificStates);
}
@@ -294,7 +311,7 @@ public class NetworkRegistrationState implements Parcelable {
&& mTransportType == other.mTransportType
&& mRegState == other.mRegState
&& mAccessNetworkTechnology == other.mAccessNetworkTechnology
- && mReasonForDenial == other.mReasonForDenial
+ && mRejectCause == other.mRejectCause
&& mEmergencyOnly == other.mEmergencyOnly
&& (mAvailableServices == other.mAvailableServices
|| Arrays.equals(mAvailableServices, other.mAvailableServices))
@@ -309,7 +326,7 @@ public class NetworkRegistrationState implements Parcelable {
dest.writeInt(mTransportType);
dest.writeInt(mRegState);
dest.writeInt(mAccessNetworkTechnology);
- dest.writeInt(mReasonForDenial);
+ dest.writeInt(mRejectCause);
dest.writeBoolean(mEmergencyOnly);
dest.writeIntArray(mAvailableServices);
dest.writeParcelable(mCellIdentity, 0);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e0b465d26a4a..3bc7341216e7 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1230,6 +1230,33 @@ public class TelephonyManager {
}
/**
+ * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
+ * available.
+ */
+ public String getTypeAllocationCode() {
+ return getTypeAllocationCode(getSlotIndex());
+ }
+
+ /**
+ * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not
+ * available.
+ *
+ * @param slotIndex of which Type Allocation Code is returned
+ */
+ public String getTypeAllocationCode(int slotIndex) {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) return null;
+
+ try {
+ return telephony.getTypeAllocationCodeForSlot(slotIndex);
+ } catch (RemoteException ex) {
+ return null;
+ } catch (NullPointerException ex) {
+ return null;
+ }
+ }
+
+ /**
* Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
*
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
@@ -1265,6 +1292,33 @@ public class TelephonyManager {
}
/**
+ * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
+ * available.
+ */
+ public String getManufacturerCode() {
+ return getManufacturerCode(getSlotIndex());
+ }
+
+ /**
+ * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not
+ * available.
+ *
+ * @param slotIndex of which Type Allocation Code is returned
+ */
+ public String getManufacturerCode(int slotIndex) {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) return null;
+
+ try {
+ return telephony.getManufacturerCodeForSlot(slotIndex);
+ } catch (RemoteException ex) {
+ return null;
+ } catch (NullPointerException ex) {
+ return null;
+ }
+ }
+
+ /**
* Returns the Network Access Identifier (NAI). Return null if NAI is not available.
*
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 3fd1d04c465a..70354b212f25 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1198,6 +1198,13 @@ interface ITelephony {
String getImeiForSlot(int slotIndex, String callingPackage);
/**
+ * Returns the Type Allocation Code from the IMEI for the given slot.
+ *
+ * @param slotIndex - Which slot to retrieve the Type Allocation Code from.
+ */
+ String getTypeAllocationCodeForSlot(int slotIndex);
+
+ /**
* Returns the MEID for the given slot.
*
* @param slotIndex - device slot.
@@ -1208,6 +1215,13 @@ interface ITelephony {
String getMeidForSlot(int slotIndex, String callingPackage);
/**
+ * Returns the Manufacturer Code from the MEID for the given slot.
+ *
+ * @param slotIndex - Which slot to retrieve the Manufacturer Code from.
+ */
+ String getManufacturerCodeForSlot(int slotIndex);
+
+ /**
* Returns the device software version.
*
* @param slotIndex - device slot.
diff --git a/test-base/Android.bp b/test-base/Android.bp
index a0e39856e9c7..d25b47727c0b 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -21,6 +21,7 @@
// Also contains the com.android.internal.util.Predicate[s] classes.
java_library {
name: "android.test.base",
+ installable: true,
srcs: ["src/**/*.java"],
@@ -42,6 +43,7 @@ java_library {
// Also contains the com.android.internal.util.Predicate[s] classes.
java_library {
name: "legacy-test",
+ installable: true,
sdk_version: "current",
static_libs: ["android.test.base"],
@@ -115,4 +117,5 @@ java_library_static {
},
},
sdk_version: "current",
+ compile_dex: true,
}
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 8fb6fda41f59..d4ecd62d6a19 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -18,6 +18,7 @@
// ===================================
java_library {
name: "android.test.mock",
+ installable: true,
// Needs to be consistent with the repackaged version of this make target.
java_version: "1.8",
@@ -85,4 +86,5 @@ java_library_static {
name: "android.test.mock.stubs",
srcs: [":android.test.mock.docs"],
sdk_version: "current",
+ compile_dex: true,
}
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index 29d7ea9b5e80..e605940804ed 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -18,6 +18,7 @@
// =====================================
java_library {
name: "android.test.runner",
+ installable: true,
// Needs to be consistent with the repackaged version of this make target.
java_version: "1.8",
@@ -108,4 +109,5 @@ java_library_static {
},
},
sdk_version: "current",
+ compile_dex: true,
}