diff options
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, } |