summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp24
-rw-r--r--api/current.txt11
-rw-r--r--api/system-current.txt3
-rw-r--r--core/java/android/os/ServiceManagerNative.java4
-rw-r--r--core/java/android/provider/SettingsStringUtil.java2
-rw-r--r--core/jni/fd_utils.cpp26
-rw-r--r--core/proto/OWNERS2
-rw-r--r--location/lib/Android.bp2
-rw-r--r--media/java/android/media/tv/OWNER5
-rw-r--r--media/jni/audioeffect/Visualizer.h3
-rw-r--r--media/lib/signer/Android.bp2
-rw-r--r--packages/Shell/AndroidManifest.xml27
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java2
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpActivity.java142
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpProvider.java101
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpReceiver.java188
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextController.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java26
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java10
-rw-r--r--services/core/jni/com_android_server_VibratorService.cpp2
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java17
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java4
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java124
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java9
26 files changed, 651 insertions, 91 deletions
diff --git a/Android.bp b/Android.bp
index 7e659247c734..90dca0350a0c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -914,6 +914,7 @@ framework_docs_only_libs = [
]
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
+ "--ignore-classes-on-classpath " +
"--hide-package com.android.okhttp " +
"--hide-package com.android.org.conscrypt --hide-package com.android.server " +
"--error UnhiddenSystemApi " +
@@ -1417,29 +1418,6 @@ droidstubs {
" --show-annotation android.annotation.TestApi ",
}
-filegroup {
- name: "apache-http-stubs-sources",
- srcs: [
- "core/java/org/apache/http/conn/ConnectTimeoutException.java",
- "core/java/org/apache/http/conn/scheme/HostNameResolver.java",
- "core/java/org/apache/http/conn/scheme/LayeredSocketFactory.java",
- "core/java/org/apache/http/conn/scheme/SocketFactory.java",
- "core/java/org/apache/http/conn/ssl/AbstractVerifier.java",
- "core/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java",
- "core/java/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/SSLSocketFactory.java",
- "core/java/org/apache/http/conn/ssl/StrictHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/X509HostnameVerifier.java",
- "core/java/org/apache/http/params/CoreConnectionPNames.java",
- "core/java/org/apache/http/params/HttpConnectionParams.java",
- "core/java/org/apache/http/params/HttpParams.java",
- "core/java/android/net/http/SslCertificate.java",
- "core/java/android/net/http/SslError.java",
- "core/java/com/android/internal/util/HexDump.java",
- ],
-}
-
droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
diff --git a/api/current.txt b/api/current.txt
index 0c60fc16c5c4..8b06719dfad5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44161,6 +44161,7 @@ package android.telephony {
field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT = "opportunistic_network_exit_threshold_rsrp_int";
field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int";
field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
+ field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool";
field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array";
field public static final String KEY_RCS_CONFIG_SERVER_URL_STRING = "rcs_config_server_url_string";
field public static final String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
@@ -44970,6 +44971,7 @@ package android.telephony {
method @Nullable public android.telephony.TelephonyManager createForPhoneAccountHandle(android.telecom.PhoneAccountHandle);
method public android.telephony.TelephonyManager createForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean doesSwitchMultiSimConfigTriggerReboot();
+ method public int getActiveModemCount();
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public java.util.List<android.telephony.CellInfo> getAllCellInfo();
method public int getCallState();
method public int getCardIdForDefaultEuicc();
@@ -45002,7 +45004,7 @@ package android.telephony {
method public String getNetworkOperatorName();
method public String getNetworkSpecifier();
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getNetworkType();
- method public int getPhoneCount();
+ method @Deprecated public int getPhoneCount();
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState();
@@ -45018,6 +45020,7 @@ package android.telephony {
method public int getSimState();
method public int getSimState(int);
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSubscriberId();
+ method public int getSupportedModemCount();
method @Nullable public String getTypeAllocationCode();
method @Nullable public String getTypeAllocationCode(int);
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @NonNull public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
@@ -45070,6 +45073,7 @@ package android.telephony {
method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
+ field public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED";
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45110,6 +45114,7 @@ package android.telephony {
field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
+ field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID";
field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME";
@@ -45120,6 +45125,10 @@ package android.telephony {
field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID";
field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER";
field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU";
+ field public static final int MODEM_COUNT_DUAL_MODEM = 2; // 0x2
+ field public static final int MODEM_COUNT_NO_MODEM = 0; // 0x0
+ field public static final int MODEM_COUNT_SINGLE_MODEM = 1; // 0x1
+ field public static final int MODEM_COUNT_TRI_MODEM = 3; // 0x3
field public static final int MULTISIM_ALLOWED = 0; // 0x0
field public static final int MULTISIM_NOT_SUPPORTED_BY_CARRIER = 2; // 0x2
field public static final int MULTISIM_NOT_SUPPORTED_BY_HARDWARE = 1; // 0x1
diff --git a/api/system-current.txt b/api/system-current.txt
index a9d228971d22..2321e3e78b18 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8149,6 +8149,9 @@ package android.telephony {
public class TelephonyManager {
method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void call(String, String);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionReportDefaultNetworkStatus(int, boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionResetAll(int);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void carrierActionSetRadioEnabled(int, boolean);
method public int checkCarrierPrivilegesForPackage(String);
method public int checkCarrierPrivilegesForPackageAnyPhone(String);
method public void dial(String);
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index f641731fa08f..124b6c6f7377 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -86,6 +86,10 @@ class ServiceManagerProxy implements IServiceManager {
throw new RemoteException();
}
+ public boolean isDeclared(String name) throws RemoteException {
+ throw new RemoteException();
+ }
+
/**
* Same as mServiceManager but used by apps.
*
diff --git a/core/java/android/provider/SettingsStringUtil.java b/core/java/android/provider/SettingsStringUtil.java
index a3dc9471a1d0..9e495dd775dc 100644
--- a/core/java/android/provider/SettingsStringUtil.java
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -126,7 +126,7 @@ public class SettingsStringUtil {
@Override
protected String itemToString(ComponentName item) {
- return item.flattenToString();
+ return item != null ? item.flattenToString() : "null";
}
public static String add(String delimitedElements, ComponentName element) {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index bb5780558bdf..3704ccdfb8ea 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -59,6 +59,10 @@ FileDescriptorWhitelist* FileDescriptorWhitelist::Get() {
return instance_;
}
+static bool IsArtMemfd(const std::string& path) {
+ return android::base::StartsWith(path, "/memfd:/boot-image-methods.art");
+}
+
bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
// Check the static whitelist path.
for (const auto& whitelist_path : kPathWhitelist) {
@@ -87,6 +91,11 @@ bool FileDescriptorWhitelist::IsAllowed(const std::string& path) const {
return true;
}
+ // the in-memory file created by ART through memfd_create is allowed.
+ if (IsArtMemfd(path)) {
+ return true;
+ }
+
// Whitelist files needed for Runtime Resource Overlay, like these:
// /system/vendor/overlay/framework-res.apk
// /system/vendor/overlay-subdir/pg/framework-res.apk
@@ -312,6 +321,11 @@ void FileDescriptorInfo::ReopenOrDetach(fail_fn_t fail_fn) const {
return DetachSocket(fail_fn);
}
+ // Children can directly use the in-memory file created by ART through memfd_create.
+ if (IsArtMemfd(file_path)) {
+ return;
+ }
+
// NOTE: This might happen if the file was unlinked after being opened.
// It's a common pattern in the case of temporary files and the like but
// we should not allow such usage from the zygote.
@@ -531,6 +545,10 @@ FileDescriptorTable::FileDescriptorTable(
}
void FileDescriptorTable::RestatInternal(std::set<int>& open_fds, fail_fn_t fail_fn) {
+ // ART creates a file through memfd for optimization purposes. We make sure
+ // there is at most one being created.
+ bool art_memfd_seen = false;
+
// Iterate through the list of file descriptors we've already recorded
// and check whether :
//
@@ -563,6 +581,14 @@ void FileDescriptorTable::RestatInternal(std::set<int>& open_fds, fail_fn_t fail
// FD.
}
+ if (IsArtMemfd(it->second->file_path)) {
+ if (art_memfd_seen) {
+ fail_fn("ART fd already seen: " + it->second->file_path);
+ } else {
+ art_memfd_seen = true;
+ }
+ }
+
++it;
// Finally, remove the FD from the set of open_fds. We do this last because
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 6ab0fc91d744..74ced8921799 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -3,8 +3,10 @@
# Metrics
joeo@google.com
singhtejinder@google.com
+yanmin@google.com
yaochen@google.com
yro@google.com
+zhouwenjie@google.com
# Settings UI
per-file settings_enums.proto=tmfang@google.com
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index fe0f669508eb..cd45e8e6ffa6 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -17,10 +17,8 @@
java_sdk_library {
name: "com.android.location.provider",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
libs: [
"androidx.annotation_annotation",
- "framework-all",
],
api_packages: ["com.android.location.provider"],
}
diff --git a/media/java/android/media/tv/OWNER b/media/java/android/media/tv/OWNER
new file mode 100644
index 000000000000..64c0bb53e894
--- /dev/null
+++ b/media/java/android/media/tv/OWNER
@@ -0,0 +1,5 @@
+amyjojo@google.com
+nchalko@google.com
+shubang@google.com
+quxiangfang@google.com
+
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index 8078e369ee82..d4672a95c6d8 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -73,7 +73,8 @@ public:
~Visualizer();
- virtual status_t setEnabled(bool enabled);
+ // Declared 'final' because we call this in ~Visualizer().
+ status_t setEnabled(bool enabled) final;
// maximum capture size in samples
static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 6b03e4de57d7..3b2578754087 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -17,7 +17,5 @@
java_sdk_library {
name: "com.android.mediadrm.signer",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
- libs: ["framework-all"],
api_packages: ["com.android.mediadrm.signer"],
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 11b0487a64b2..047ac5984fe3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -173,6 +173,8 @@
<uses-permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED" />
<!-- Permission needed to invoke DynamicSystem (AOT) -->
<uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
+ <!-- Used to clean up heap dumps on boot. -->
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
@@ -201,7 +203,7 @@
<!-- Permission required to test ExplicitHealthCheckServiceImpl. -->
<uses-permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE" />
-
+
<!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
@@ -231,12 +233,25 @@
</intent-filter>
</provider>
+ <provider android:name=".HeapDumpProvider"
+ android:authorities="com.android.shell.heapdump"
+ android:grantUriPermissions="true"
+ android:exported="true" />
+
<activity
android:name=".BugreportWarningActivity"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
android:exported="false" />
+ <activity android:name=".HeapDumpActivity"
+ android:theme="@*android:style/Theme.Translucent.NoTitleBar"
+ android:label="@*android:string/dump_heap_title"
+ android:finishOnCloseSystemDialogs="true"
+ android:noHistory="true"
+ android:excludeFromRecents="true"
+ android:exported="false" />
+
<receiver
android:name=".BugreportReceiver"
android:permission="android.permission.DUMP">
@@ -254,6 +269,16 @@
</intent-filter>
</receiver>
+ <receiver
+ android:name=".HeapDumpReceiver"
+ android:permission="android.permission.DUMP">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="com.android.internal.intent.action.HEAP_DUMP_FINISHED" />
+ <action android:name="com.android.shell.action.DELETE_HEAP_DUMP" />
+ </intent-filter>
+ </receiver>
+
<service
android:name=".BugreportProgressService"
android:exported="false"/>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 857cb2af41f6..29c61ee70f7d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1410,7 +1410,7 @@ public class BugreportProgressService extends Service {
return false;
}
- private static boolean isTv(Context context) {
+ static boolean isTv(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpActivity.java b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
new file mode 100644
index 000000000000..0ff0d3353041
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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.shell;
+
+import static com.android.shell.HeapDumpProvider.makeUri;
+import static com.android.shell.HeapDumpReceiver.ACTION_DELETE_HEAP_DUMP;
+import static com.android.shell.HeapDumpReceiver.EXTRA_IS_USER_INITIATED;
+import static com.android.shell.HeapDumpReceiver.EXTRA_PROCESS_NAME;
+import static com.android.shell.HeapDumpReceiver.EXTRA_REPORT_PACKAGE;
+import static com.android.shell.HeapDumpReceiver.EXTRA_SIZE_BYTES;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.DebugUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+/**
+ * This activity is displayed when the system has collected a heap dump.
+ */
+public class HeapDumpActivity extends Activity {
+ private static final String TAG = "HeapDumpActivity";
+
+ static final String KEY_URI = "uri";
+
+ private AlertDialog mDialog;
+ private Uri mDumpUri;
+ private boolean mHandled = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String process = getIntent().getStringExtra(EXTRA_PROCESS_NAME);
+ long size = getIntent().getLongExtra(EXTRA_SIZE_BYTES, 0);
+ final boolean isUserInitiated = getIntent().getBooleanExtra(EXTRA_IS_USER_INITIATED, false);
+ final int uid = getIntent().getIntExtra(Intent.EXTRA_UID, 0);
+ final boolean isSystemProcess = uid == Process.SYSTEM_UID;
+ mDumpUri = makeUri(process);
+ final String procDisplayName = isSystemProcess
+ ? getString(com.android.internal.R.string.android_system_label)
+ : process;
+
+ final Intent sendIntent = new Intent();
+ ClipData clip = ClipData.newUri(getContentResolver(), "Heap Dump", mDumpUri);
+ sendIntent.setClipData(clip);
+ sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ sendIntent.setType(clip.getDescription().getMimeType(0));
+ sendIntent.putExtra(Intent.EXTRA_STREAM, mDumpUri);
+
+ String directLaunchPackage = getIntent().getStringExtra(EXTRA_REPORT_PACKAGE);
+ if (directLaunchPackage != null) {
+ sendIntent.setAction(ActivityManager.ACTION_REPORT_HEAP_LIMIT);
+ sendIntent.setPackage(directLaunchPackage);
+ try {
+ startActivity(sendIntent);
+ mHandled = true;
+ finish();
+ return;
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Unable to direct launch to " + directLaunchPackage, e);
+ }
+ }
+
+ final int messageId;
+ if (isUserInitiated) {
+ messageId = com.android.internal.R.string.dump_heap_ready_text;
+ } else if (isSystemProcess) {
+ messageId = com.android.internal.R.string.dump_heap_system_text;
+ } else {
+ messageId = com.android.internal.R.string.dump_heap_text;
+ }
+ mDialog = new AlertDialog.Builder(this, android.R.style.Theme_Material_Light_Dialog_Alert)
+ .setTitle(com.android.internal.R.string.dump_heap_title)
+ .setMessage(getString(messageId, procDisplayName,
+ DebugUtils.sizeValueToString(size, null)))
+ .setNegativeButton(android.R.string.cancel, (dialog, which) -> {
+ mHandled = true;
+ finish();
+ })
+ .setNeutralButton(R.string.delete, (dialog, which) -> {
+ mHandled = true;
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ finish();
+ })
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ mHandled = true;
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.setPackage(null);
+ startActivity(Intent.createChooser(sendIntent,
+ getText(com.android.internal.R.string.dump_heap_title)));
+ finish();
+ })
+ .show();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (!isChangingConfigurations()) {
+ if (!mHandled) {
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ }
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpProvider.java b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
new file mode 100644
index 000000000000..3eceb9118b12
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.shell;
+
+import android.annotation.NonNull;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/** ContentProvider to write and access heap dumps. */
+public class HeapDumpProvider extends ContentProvider {
+ private static final String FILENAME_SUFFIX = "_javaheap.bin";
+ private static final Object sLock = new Object();
+
+ private File mRoot;
+
+ @Override
+ public boolean onCreate() {
+ synchronized (sLock) {
+ mRoot = new File(getContext().createCredentialProtectedStorageContext().getFilesDir(),
+ "heapdumps");
+ return mRoot.mkdir();
+ }
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "application/octet-stream";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException("Insert not allowed.");
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ return (new File(mRoot, tag)).delete() ? 1 : 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException("Update not allowed.");
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ final int pMode;
+ if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+ pMode = ParcelFileDescriptor.MODE_CREATE
+ | ParcelFileDescriptor.MODE_TRUNCATE
+ | ParcelFileDescriptor.MODE_WRITE_ONLY;
+ } else {
+ pMode = ParcelFileDescriptor.MODE_READ_ONLY;
+ }
+
+ synchronized (sLock) {
+ return ParcelFileDescriptor.open(new File(mRoot, tag), pMode);
+ }
+ }
+
+ @NonNull
+ static Uri makeUri(@NonNull String procName) {
+ return Uri.parse("content://com.android.shell.heapdump/" + procName + FILENAME_SUFFIX);
+ }
+
+ private String sanitizePath(String path) {
+ return path.replaceAll("[^a-zA-Z0-9_.]", "");
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpReceiver.java b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
new file mode 100644
index 000000000000..858c521eaed5
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2019 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.shell;
+
+import static com.android.shell.BugreportProgressService.isTv;
+
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.FileUtils;
+import android.os.Process;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Receiver that handles finished heap dumps.
+ */
+public class HeapDumpReceiver extends BroadcastReceiver {
+ private static final String TAG = "HeapDumpReceiver";
+
+ /**
+ * Broadcast action to determine when to delete a specific dump heap. Must include a {@link
+ * HeapDumpActivity#KEY_URI} String extra.
+ */
+ static final String ACTION_DELETE_HEAP_DUMP = "com.android.shell.action.DELETE_HEAP_DUMP";
+
+ /** Broadcast sent when heap dump collection has been completed. */
+ private static final String ACTION_HEAP_DUMP_FINISHED =
+ "com.android.internal.intent.action.HEAP_DUMP_FINISHED";
+
+ /** The process we are reporting */
+ static final String EXTRA_PROCESS_NAME = "com.android.internal.extra.heap_dump.PROCESS_NAME";
+
+ /** The size limit the process reached. */
+ static final String EXTRA_SIZE_BYTES = "com.android.internal.extra.heap_dump.SIZE_BYTES";
+
+ /** Whether the user initiated the dump or not. */
+ static final String EXTRA_IS_USER_INITIATED =
+ "com.android.internal.extra.heap_dump.IS_USER_INITIATED";
+
+ /** Optional name of package to directly launch. */
+ static final String EXTRA_REPORT_PACKAGE =
+ "com.android.internal.extra.heap_dump.REPORT_PACKAGE";
+
+ private static final String NOTIFICATION_CHANNEL_ID = "heapdumps";
+ private static final int NOTIFICATION_ID = 2019;
+
+ /**
+ * Always keep heap dumps taken in the last week.
+ */
+ private static final long MIN_KEEP_AGE_MS = DateUtils.WEEK_IN_MILLIS;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive(): " + intent);
+ final String action = intent.getAction();
+ if (action == null) {
+ Log.e(TAG, "null action received");
+ return;
+ }
+ switch (action) {
+ case Intent.ACTION_BOOT_COMPLETED:
+ cleanupOldFiles(context);
+ break;
+ case ACTION_DELETE_HEAP_DUMP:
+ deleteHeapDump(context, intent.getStringExtra(HeapDumpActivity.KEY_URI));
+ break;
+ case ACTION_HEAP_DUMP_FINISHED:
+ showDumpNotification(context, intent);
+ break;
+ }
+ }
+
+ private void cleanupOldFiles(Context context) {
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+ Log.d(TAG, "Deleting from " + new File(context.getFilesDir(), "heapdumps"));
+ FileUtils.deleteOlderFiles(new File(context.getFilesDir(), "heapdumps"), 0,
+ MIN_KEEP_AGE_MS);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Couldn't delete old files", e);
+ }
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void deleteHeapDump(Context context, @Nullable final String uri) {
+ if (uri == null) {
+ Log.e(TAG, "null URI for delete heap dump intent");
+ return;
+ }
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ context.getContentResolver().delete(Uri.parse(uri), null, null);
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void showDumpNotification(Context context, Intent intent) {
+ final boolean isUserInitiated = intent.getBooleanExtra(
+ EXTRA_IS_USER_INITIATED, false);
+ final String procName = intent.getStringExtra(EXTRA_PROCESS_NAME);
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+
+ final String reportPackage = intent.getStringExtra(
+ EXTRA_REPORT_PACKAGE);
+ final long size = intent.getLongExtra(EXTRA_SIZE_BYTES, 0);
+
+ if (procName == null) {
+ Log.e(TAG, "No process name sent over");
+ return;
+ }
+
+ NotificationManager nm = NotificationManager.from(context);
+ nm.createNotificationChannel(
+ new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ "Heap dumps",
+ NotificationManager.IMPORTANCE_DEFAULT));
+
+ final int titleId = isUserInitiated
+ ? com.android.internal.R.string.dump_heap_ready_notification
+ : com.android.internal.R.string.dump_heap_notification;
+ final String procDisplayName = uid == Process.SYSTEM_UID
+ ? context.getString(com.android.internal.R.string.android_system_label)
+ : procName;
+ String text = context.getString(titleId, procDisplayName);
+
+ Intent shareIntent = new Intent();
+ shareIntent.setClassName(context, HeapDumpActivity.class.getName());
+ shareIntent.putExtra(EXTRA_PROCESS_NAME, procName);
+ shareIntent.putExtra(EXTRA_SIZE_BYTES, size);
+ shareIntent.putExtra(EXTRA_IS_USER_INITIATED, isUserInitiated);
+ shareIntent.putExtra(Intent.EXTRA_UID, uid);
+ if (reportPackage != null) {
+ shareIntent.putExtra(EXTRA_REPORT_PACKAGE, reportPackage);
+ }
+ final Notification.Builder builder = new Notification.Builder(context,
+ NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(
+ isTv(context) ? R.drawable.ic_bug_report_black_24dp
+ : com.android.internal.R.drawable.stat_sys_adb)
+ .setLocalOnly(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(text)
+ .setTicker(text)
+ .setAutoCancel(true)
+ .setContentText(context.getText(
+ com.android.internal.R.string.dump_heap_notification_detail))
+ .setContentIntent(PendingIntent.getActivity(context, 2, shareIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT));
+
+ Log.v(TAG, "Creating share heap dump notification");
+ NotificationManager.from(context).notify(NOTIFICATION_ID, builder.build());
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index a15c035fdd3a..0efc5bf411f3 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -172,7 +172,7 @@ public class CarrierTextController {
mSeparator = separator;
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
mSimSlotsNumber = ((TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE)).getMaxPhoneCount();
+ Context.TELEPHONY_SERVICE)).getSupportedModemCount();
mSimErrorState = new boolean[mSimSlotsNumber];
updateDisplayOpportunisticSubscriptionCarrierText(SystemProperties.getBoolean(
TelephonyProperties.DISPLAY_OPPORTUNISTIC_SUBSCRIPTION_CARRIER_TEXT_PROPERTY_NAME,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index e74e955cd7a0..528625ee4dc8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -119,7 +119,7 @@ public class CarrierTextControllerTest extends SysuiTestCase {
mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
new CharSequence[]{}, false, new int[]{});
- when(mTelephonyManager.getMaxPhoneCount()).thenReturn(3);
+ when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true,
mKeyguardUpdateMonitor);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 05b937a34626..d4fb9acdad5e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -82,8 +82,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
-import android.provider.SettingsStringUtil;
-import android.provider.SettingsStringUtil.ComponentNameSet;
import android.provider.SettingsStringUtil.SettingStringHelper;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -2436,12 +2434,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Enables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.add(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.add(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.add(componentName)) {
@@ -2453,12 +2451,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Disables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingsStringUtil.SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.remove(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.remove(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.remove(componentName)) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0269579e3e07..14678884e8e2 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -382,7 +382,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mContext = context;
mBatteryStats = BatteryStatsService.getService();
- int numPhones = TelephonyManager.getDefault().getMaxPhoneCount();
+ int numPhones = TelephonyManager.getDefault().getSupportedModemCount();
if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones);
mNumPhones = numPhones;
mCallState = new int[numPhones];
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index c5c53d8ba4ca..a18a53dfea92 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4112,9 +4112,13 @@ class ActivityStack extends ConfigurationContainer {
final ActivityDisplay display = getDisplay();
final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
final boolean isFloating = r.getConfiguration().windowConfiguration.tasksAreFloating();
-
- if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
- && next != null && !next.nowVisible && !isFloating) {
+ // isNextNotYetVisible is to check if the next activity is invisible, or it has been
+ // requested to be invisible but its windows haven't reported as invisible. If so, it
+ // implied that the current finishing activity should be added into stopping list rather
+ // than destroying it immediately.
+ final boolean isNextNotYetVisible = next != null && (!next.nowVisible || !next.visible);
+ if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible) && isNextNotYetVisible
+ && !isFloating) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */,
"finishCurrentActivityLocked");
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index d5fbd2b316e7..c59e6056b72e 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -151,7 +151,7 @@ static void vibratorSetExternalControl(JNIEnv*, jobject, jboolean enabled) {
}
}
-static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
+static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jlong strength) {
Status status;
uint32_t lengthMs;
auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index fc0c2e84243e..e458ae6b1d3d 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1831,6 +1831,13 @@ public class CarrierConfigManager {
"support_direct_fdn_dialing_bool";
/**
+ * Int indicating the max number length for FDN
+ * @hide
+ */
+ public static final String KEY_FDN_NUMBER_LENGTH_LIMIT_INT =
+ "fdn_number_length_limit_int";
+
+ /**
* Report IMEI as device id even if it's a CDMA/LTE phone.
*
* @hide
@@ -3170,6 +3177,14 @@ public class CarrierConfigManager {
public static final String KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY =
"disconnect_cause_play_busytone_int_array";
+ /**
+ * Flag specifying whether to prevent sending CLIR activation("*31#") and deactivation("#31#")
+ * code only without dialing number.
+ * When {@code true}, these are prevented, {@code false} otherwise.
+ */
+ public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL =
+ "prevent_clir_activation_and_deactivation_code_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -3371,6 +3386,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
+ sDefaults.putInt(KEY_FDN_NUMBER_LENGTH_LIMIT_INT, 20);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL, true);
@@ -3596,6 +3612,7 @@ public class CarrierConfigManager {
sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null);
sDefaults.putIntArray(KEY_DISCONNECT_CAUSE_PLAY_BUSYTONE_INT_ARRAY,
new int[] {4 /* BUSY */});
+ sDefaults.putBoolean(KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL, false);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 97c46e33a472..4e93efde54f1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2095,13 +2095,13 @@ public class SubscriptionManager {
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static boolean isValidSlotIndex(int slotIndex) {
- return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getMaxPhoneCount();
+ return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSupportedModemCount();
}
/** @hide */
@UnsupportedAppUsage
public static boolean isValidPhoneId(int phoneId) {
- return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getMaxPhoneCount();
+ return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getSupportedModemCount();
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 311d260ee209..bec0a975108a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -289,6 +289,21 @@ public class TelephonyManager {
};
/** @hide */
+ @IntDef(prefix = {"MODEM_COUNT_"},
+ value = {
+ MODEM_COUNT_NO_MODEM,
+ MODEM_COUNT_SINGLE_MODEM,
+ MODEM_COUNT_DUAL_MODEM,
+ MODEM_COUNT_TRI_MODEM
+ })
+ public @interface ModemCount {}
+
+ public static final int MODEM_COUNT_NO_MODEM = 0;
+ public static final int MODEM_COUNT_SINGLE_MODEM = 1;
+ public static final int MODEM_COUNT_DUAL_MODEM = 2;
+ public static final int MODEM_COUNT_TRI_MODEM = 3;
+
+ /** @hide */
@UnsupportedAppUsage
public TelephonyManager(Context context) {
this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
@@ -365,12 +380,26 @@ public class TelephonyManager {
/**
* Returns the number of phones available.
* Returns 0 if none of voice, sms, data is not supported
- * Returns 1 for Single standby mode (Single SIM functionality)
- * Returns 2 for Dual standby mode.(Dual SIM functionality)
- * Returns 3 for Tri standby mode.(Tri SIM functionality)
+ * Returns 1 for Single standby mode (Single SIM functionality).
+ * Returns 2 for Dual standby mode (Dual SIM functionality).
+ * Returns 3 for Tri standby mode (Tri SIM functionality).
+ * @deprecated Use {@link #getActiveModemCount} instead.
*/
+ @Deprecated
public int getPhoneCount() {
- int phoneCount = 1;
+ return getActiveModemCount();
+ }
+
+ /**
+ * Returns the number of logical modems currently configured to be activated.
+ *
+ * Returns 0 if none of voice, sms, data is not supported
+ * Returns 1 for Single standby mode (Single SIM functionality).
+ * Returns 2 for Dual standby mode (Dual SIM functionality).
+ * Returns 3 for Tri standby mode (Tri SIM functionality).
+ */
+ public @ModemCount int getActiveModemCount() {
+ int modemCount = 1;
switch (getMultiSimConfiguration()) {
case UNKNOWN:
ConnectivityManager cm = mContext == null ? null : (ConnectivityManager) mContext
@@ -378,45 +407,32 @@ public class TelephonyManager {
// check for voice and data support, 0 if not supported
if (!isVoiceCapable() && !isSmsCapable() && cm != null
&& !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
- phoneCount = 0;
+ modemCount = MODEM_COUNT_NO_MODEM;
} else {
- phoneCount = 1;
+ modemCount = MODEM_COUNT_SINGLE_MODEM;
}
break;
case DSDS:
case DSDA:
- phoneCount = PhoneConstants.MAX_PHONE_COUNT_DUAL_SIM;
+ modemCount = MODEM_COUNT_DUAL_MODEM;
break;
case TSTS:
- phoneCount = PhoneConstants.MAX_PHONE_COUNT_TRI_SIM;
+ modemCount = MODEM_COUNT_TRI_MODEM;
break;
}
- return phoneCount;
+ return modemCount;
}
/**
- *
- * Return how many phone / logical modem can be active simultaneously, in terms of device
+ * Return how many logical modem can be potentially active simultaneously, in terms of hardware
* capability.
- * For example, for a dual-SIM capable device, it always returns 2, even if only one logical
- * modem / SIM is active (aka in single SIM mode).
- *
- * TODO: b/139642279 publicize and rename.
- * @hide
- */
- public int getMaxPhoneCount() {
- // TODO: b/139642279 when turning on this feature, remove dependency of
- // PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE and always return result based on
- // PROPERTY_MAX_ACTIVE_MODEMS.
- String rebootRequired = SystemProperties.get(
- TelephonyProperties.PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE);
- if (rebootRequired.equals("false")) {
- // If no reboot is required, return max possible active modems.
- return SystemProperties.getInt(
- TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getPhoneCount());
- } else {
- return getPhoneCount();
- }
+ * It might return different value from {@link #getActiveModemCount}. For example, for a
+ * dual-SIM capable device operating in single SIM mode (only one logical modem is turned on),
+ * {@link #getActiveModemCount} returns 1 while this API returns 2.
+ */
+ public @ModemCount int getSupportedModemCount() {
+ return SystemProperties.getInt(TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS,
+ getActiveModemCount());
}
/** {@hide} */
@@ -1177,6 +1193,35 @@ public class TelephonyManager {
"android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
/**
+ * Broadcast intent that indicates multi-SIM configuration is changed. For example, it changed
+ * from single SIM capable to dual-SIM capable (DSDS or DSDA) or triple-SIM mode.
+ *
+ * It doesn't indicate how many subscriptions are actually active, or which states SIMs are,
+ * or that all steps during multi-SIM change are done. To know those information you still need
+ * to listen to SIM_STATE changes or active subscription changes.
+ *
+ * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value.
+ */
+ public static final String ACTION_MULTI_SIM_CONFIG_CHANGED =
+ "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
+
+
+ /**
+ * The number of active SIM supported by current multi-SIM config. It's not related to how many
+ * SIM/subscriptions are currently active.
+ *
+ * For single SIM mode, it's 1.
+ * For DSDS or DSDA mode, it's 2.
+ * For triple-SIM mode, it's 3.
+ *
+ * Extra of {@link #ACTION_MULTI_SIM_CONFIG_CHANGED}.
+ *
+ * type: integer
+ */
+ public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED =
+ "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
+
+ /**
* @hide
*/
public static final String USSD_RESPONSE = "USSD_RESPONSE";
@@ -1832,7 +1877,12 @@ public class TelephonyManager {
if (telephony == null) return null;
try {
- return telephony.getMeidForSlot(slotIndex, getOpPackageName());
+ String meid = telephony.getMeidForSlot(slotIndex, getOpPackageName());
+ if (TextUtils.isEmpty(meid)) {
+ Log.d(TAG, "getMeid: return null because MEID is not available");
+ return null;
+ }
+ return meid;
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -10132,11 +10182,13 @@ public class TelephonyManager {
/**
* Action set from carrier signalling broadcast receivers to enable/disable radio
- * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required.
* @param subId the subscription ID that this action applies to.
* @param enabled control enable or disable radio.
* @hide
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
try {
ITelephony service = getITelephony();
@@ -10151,11 +10203,13 @@ public class TelephonyManager {
/**
* Action set from carrier signalling broadcast receivers to start/stop reporting default
* network available events
- * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required.
* @param subId the subscription ID that this action applies to.
* @param report control start/stop reporting network status.
* @hide
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
try {
ITelephony service = getITelephony();
@@ -10169,10 +10223,12 @@ public class TelephonyManager {
/**
* Action set from carrier signalling broadcast receivers to reset all carrier actions
- * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
+ * Permissions {@link android.Manifest.permission.MODIFY_PHONE_STATE} is required.
* @param subId the subscription ID that this action applies to.
* @hide
*/
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void carrierActionResetAll(int subId) {
try {
ITelephony service = getITelephony();
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 116c05129a96..e65e032c0cd4 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1206,7 +1206,7 @@ public class ApnSetting implements Parcelable {
&& !other.canHandleType(TYPE_DUN)
&& Objects.equals(this.mApnName, other.mApnName)
&& !typeSameAny(this, other)
- && xorEquals(this.mProxyAddress, other.mProxyAddress)
+ && xorEqualsString(this.mProxyAddress, other.mProxyAddress)
&& xorEqualsInt(this.mProxyPort, other.mProxyPort)
&& xorEquals(this.mProtocol, other.mProtocol)
&& xorEquals(this.mRoamingProtocol, other.mRoamingProtocol)
@@ -1215,7 +1215,7 @@ public class ApnSetting implements Parcelable {
&& Objects.equals(this.mMvnoType, other.mMvnoType)
&& Objects.equals(this.mMvnoMatchData, other.mMvnoMatchData)
&& xorEquals(this.mMmsc, other.mMmsc)
- && xorEquals(this.mMmsProxyAddress, other.mMmsProxyAddress)
+ && xorEqualsString(this.mMmsProxyAddress, other.mMmsProxyAddress)
&& xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
&& Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
&& Objects.equals(mApnSetId, other.mApnSetId)
@@ -1228,6 +1228,11 @@ public class ApnSetting implements Parcelable {
return first == null || second == null || first.equals(second);
}
+ // Equal or one is null.
+ private boolean xorEqualsString(String first, String second) {
+ return TextUtils.isEmpty(first) || TextUtils.isEmpty(second) || first.equals(second);
+ }
+
// Equal or one is not specified.
private boolean xorEqualsInt(int first, int second) {
return first == UNSPECIFIED_INT || second == UNSPECIFIED_INT