Merge "Add API to set the sll_protocol on PacketSocket"
diff --git a/Android.bp b/Android.bp
index 7e65924..90dca03 100644
--- a/Android.bp
+++ b/Android.bp
@@ -914,6 +914,7 @@
]
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 @@
" --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 0c60fc1..95338e8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44161,6 +44161,7 @@
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";
@@ -44725,6 +44726,7 @@
method public static int getDefaultSmsSubscriptionId();
method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback);
+ method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress();
method public int getSubscriptionId();
method public void injectSmsPdu(byte[], String, android.app.PendingIntent);
method public void sendDataMessage(String, String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
@@ -44732,6 +44734,7 @@
method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSmscAddress(@NonNull String);
field public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
field public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
field public static final String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
@@ -44970,6 +44973,7 @@
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 +45006,7 @@
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 +45022,7 @@
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 +45075,7 @@
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 +45116,7 @@
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 +45127,10 @@
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 26ee758..e878c38 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8150,6 +8150,9 @@
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);
@@ -8157,6 +8160,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
+ method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset(int);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
@@ -8810,11 +8814,14 @@
public class ImsMmTelManager {
method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAvailable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isCapable(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void isSupported(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, @NonNull java.util.function.Consumer<java.lang.Boolean>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTtyOverVolteEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled();
@@ -9341,6 +9348,8 @@
method public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus();
method public void setUiTtyMode(int, @Nullable android.os.Message);
method @android.telephony.ims.feature.MmTelFeature.ProcessCallResult public int shouldProcessCall(@NonNull String[]);
+ field public static final String EXTRA_IS_UNKNOWN_CALL = "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+ field public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
field public static final int PROCESS_CALL_CSFB = 1; // 0x1
field public static final int PROCESS_CALL_IMS = 0; // 0x0
}
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index f641731..124b6c6 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -86,6 +86,10 @@
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 a3dc947..9e495dd 100644
--- a/core/java/android/provider/SettingsStringUtil.java
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -126,7 +126,7 @@
@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/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index fd2ada0..36bc229 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -49,6 +49,18 @@
return mChangeConfig.forceDisabledSet();
}
+ /**
+ * Returns if a change is enabled or disabled in this config.
+ */
+ public boolean isChangeEnabled(long changeId) {
+ if (mChangeConfig.isForceEnabled(changeId)) {
+ return true;
+ } else if (mChangeConfig.isForceDisabled(changeId)) {
+ return false;
+ }
+ throw new IllegalStateException("Change " + changeId + " is not defined.");
+ }
+
private CompatibilityChangeConfig(Parcel in) {
long[] enabledArray = in.createLongArray();
long[] disabledArray = in.createLongArray();
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl b/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl
new file mode 100644
index 0000000..3bc7277
--- /dev/null
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.internal.compat;
+
+parcelable CompatibilityChangeInfo;
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
new file mode 100644
index 0000000..e48e2df
--- /dev/null
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -0,0 +1,92 @@
+/*
+ * 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.internal.compat;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is a parcelable version of {@link com.android.server.compat.Change}.
+ *
+ * @hide
+ */
+public class CompatibilityChangeInfo implements Parcelable {
+ private final long mChangeId;
+ private final @Nullable String mName;
+ private final int mEnableAfterTargetSdk;
+ private final boolean mDisabled;
+
+ public long getId() {
+ return mChangeId;
+ }
+
+ @Nullable
+ public String getName() {
+ return mName;
+ }
+
+ public int getEnableAfterTargetSdk() {
+ return mEnableAfterTargetSdk;
+ }
+
+ public boolean getDisabled() {
+ return mDisabled;
+ }
+
+ public CompatibilityChangeInfo(
+ Long changeId, String name, int enableAfterTargetSdk, boolean disabled) {
+ this.mChangeId = changeId;
+ this.mName = name;
+ this.mEnableAfterTargetSdk = enableAfterTargetSdk;
+ this.mDisabled = disabled;
+ }
+
+ private CompatibilityChangeInfo(Parcel in) {
+ mChangeId = in.readLong();
+ mName = in.readString();
+ mEnableAfterTargetSdk = in.readInt();
+ mDisabled = in.readBoolean();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mChangeId);
+ dest.writeString(mName);
+ dest.writeInt(mEnableAfterTargetSdk);
+ dest.writeBoolean(mDisabled);
+ }
+
+ public static final Parcelable.Creator<CompatibilityChangeInfo> CREATOR =
+ new Parcelable.Creator<CompatibilityChangeInfo>() {
+
+ @Override
+ public CompatibilityChangeInfo createFromParcel(Parcel in) {
+ return new CompatibilityChangeInfo(in);
+ }
+
+ @Override
+ public CompatibilityChangeInfo[] newArray(int size) {
+ return new CompatibilityChangeInfo[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 8391ad2..5857642 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -17,8 +17,10 @@
package com.android.internal.compat;
import android.content.pm.ApplicationInfo;
+import java.util.Map;
parcelable CompatibilityChangeConfig;
+parcelable CompatibilityChangeInfo;
/**
* Platform private API for talking with the PlatformCompat service.
@@ -146,4 +148,21 @@
*
*/
void clearOverrides(in String packageName);
+
+ /**
+ * Get configs for an application.
+ *
+ * @param appInfo The application whose config will be returned.
+ *
+ * @return A {@link CompatibilityChangeConfig}, representing whether a change is enabled for
+ * the given app or not.
+ */
+ CompatibilityChangeConfig getAppConfig(in ApplicationInfo appInfo);
+
+ /**
+ * List all compatibility changes.
+ *
+ * @return An array of {@link CompatChangeInfo} known to the service.
+ */
+ CompatibilityChangeInfo[] listAllChanges();
}
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index bb57805..3704ccd 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -59,6 +59,10 @@
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 @@
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 @@
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 @@
}
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 @@
// 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 6ab0fc9..74ced89 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/libs/hwui/Android.bp b/libs/hwui/Android.bp
index f51848e5..4c08a38 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -234,9 +234,6 @@
"protos/graphicsstats.proto",
],
- // Allow implicit fallthroughs in HardwareBitmapUploader.cpp until they are fixed.
- cflags: ["-Wno-implicit-fallthrough"],
-
proto: {
export_proto_headers: true,
},
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 9bb6031..b64588e 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -302,6 +302,7 @@
switch (skBitmap.info().colorType()) {
case kRGBA_8888_SkColorType:
formatInfo.isSupported = true;
+ [[fallthrough]];
// ARGB_4444 is upconverted to RGBA_8888
case kARGB_4444_SkColorType:
formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_8888;
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index fe0f669..cd45e8e 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 0000000..64c0bb5
--- /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/Android.bp b/media/jni/Android.bp
index e6c1c67..f873eeb 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -100,13 +100,14 @@
"android_media_Utils.cpp",
],
+ header_libs: [
+ "libgui_headers",
+ ],
+
shared_libs: [
"liblog",
- "libgui",
- "libnativewindow",
"libui",
"libutils",
- "android.hidl.token@1.0-utils",
],
include_dirs: [
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index 8078e36..d4672a9 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -73,7 +73,8 @@
~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 6b03e4d..3b25787 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 11b0487..047ac59 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 857cb2a..29c61ee 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1410,7 +1410,7 @@
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 0000000..0ff0d33
--- /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 0000000..3eceb91
--- /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 0000000..858c521
--- /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/legacy/recents/res/values/config.xml b/packages/SystemUI/legacy/recents/res/values/config.xml
index 2ff9abf..0fbb623 100644
--- a/packages/SystemUI/legacy/recents/res/values/config.xml
+++ b/packages/SystemUI/legacy/recents/res/values/config.xml
@@ -26,6 +26,14 @@
(package/class) -->
<string name="config_recentsComponent" translatable="false">com.android.systemui.recents.LegacyRecentsImpl</string>
+ <!-- SystemUI Services (per user): The classes of the stuff to start for each user. This is a subset of the config_systemUIServiceComponents -->
+ <string-array name="config_systemUIServiceComponentsPerUser" translatable="false">
+ <item>com.android.systemui.Dependency$DependencyCreator</item>
+ <item>com.android.systemui.util.NotificationChannels</item>
+ <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
+ <item>com.android.systemui.recents.Recents</item>
+ </string-array>
+
<!-- Whether recents should use hardware layers for its taskviews. This flag can be enabled
for devices where the java drawing of round rects may be slow -->
<bool name="config_recents_use_hardware_layers">false</bool>
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
index a150de9..a572110 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/LegacyRecentsImpl.java
@@ -195,6 +195,7 @@
mContext.getColor(R.color.recents_task_bar_default_background_color);
final int defaultTaskViewBackgroundColor =
mContext.getColor(R.color.recents_task_view_default_background_color);
+ getComponent(Recents.class).putComponent(LegacyRecentsImpl.class, this);
sDebugFlags = new RecentsDebugFlags();
sSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
sConfiguration = new RecentsConfiguration(mContext);
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index a15c035..0efc5bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -172,7 +172,7 @@
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 e74e955cd..528625e 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 @@
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/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index ca69c18..998572f 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -21,6 +21,7 @@
"src/**/*.java",
":framework-tethering-shared-srcs",
":services-tethering-shared-srcs",
+ ":servicescore-tethering-src",
],
static_libs: [
"androidx.annotation_annotation",
@@ -67,13 +68,23 @@
// This group will be removed when tethering migration is done.
filegroup {
- name: "tethering-services-srcs",
+ name: "tethering-servicescore-srcs",
srcs: [
+ "src/com/android/server/connectivity/tethering/EntitlementManager.java",
"src/com/android/server/connectivity/tethering/TetheringConfiguration.java",
+ "src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java",
+ ],
+}
+
+// This group will be removed when tethering migration is done.
+filegroup {
+ name: "tethering-servicesnet-srcs",
+ srcs: [
"src/android/net/dhcp/DhcpServerCallbacks.java",
"src/android/net/dhcp/DhcpServingParamsParcelExt.java",
"src/android/net/ip/IpServer.java",
"src/android/net/ip/RouterAdvertisementDaemon.java",
"src/android/net/util/InterfaceSet.java",
+ "src/android/net/util/PrefixUtils.java",
],
}
diff --git a/packages/Tethering/AndroidManifestBase.xml b/packages/Tethering/AndroidManifestBase.xml
index b9cac19..dc013da 100644
--- a/packages/Tethering/AndroidManifestBase.xml
+++ b/packages/Tethering/AndroidManifestBase.xml
@@ -23,7 +23,6 @@
<application
android:label="Tethering"
android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true"
- android:usesCleartextTraffic="true">
+ android:directBootAware="true">
</application>
</manifest>
diff --git a/services/net/java/android/net/util/PrefixUtils.java b/packages/Tethering/src/android/net/util/PrefixUtils.java
similarity index 92%
rename from services/net/java/android/net/util/PrefixUtils.java
rename to packages/Tethering/src/android/net/util/PrefixUtils.java
index f60694a..f203e99 100644
--- a/services/net/java/android/net/util/PrefixUtils.java
+++ b/packages/Tethering/src/android/net/util/PrefixUtils.java
@@ -42,16 +42,19 @@
public static final IpPrefix DEFAULT_WIFI_P2P_PREFIX = pfx("192.168.49.0/24");
+ /** Get non forwardable prefixes. */
public static Set<IpPrefix> getNonForwardablePrefixes() {
final HashSet<IpPrefix> prefixes = new HashSet<>();
addNonForwardablePrefixes(prefixes);
return prefixes;
}
+ /** Add non forwardable prefixes. */
public static void addNonForwardablePrefixes(Set<IpPrefix> prefixes) {
Collections.addAll(prefixes, MIN_NON_FORWARDABLE_PREFIXES);
}
+ /** Get local prefixes from |lp|. */
public static Set<IpPrefix> localPrefixesFrom(LinkProperties lp) {
final HashSet<IpPrefix> localPrefixes = new HashSet<>();
if (lp == null) return localPrefixes;
@@ -66,10 +69,12 @@
return localPrefixes;
}
+ /** Convert LinkAddress |addr| to IpPrefix. */
public static IpPrefix asIpPrefix(LinkAddress addr) {
return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
}
+ /** Convert InetAddress |ip| to IpPrefix. */
public static IpPrefix ipAddressAsPrefix(InetAddress ip) {
final int bitLength = (ip instanceof Inet4Address)
? NetworkConstants.IPV4_ADDR_BITS
diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
similarity index 99%
rename from services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
rename to packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
index f952bce..6b0f1de 100644
--- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java
@@ -87,7 +87,6 @@
private static final int EVENT_MAYBE_RUN_PROVISIONING = 3;
private static final int EVENT_GET_ENTITLEMENT_VALUE = 4;
-
// The ArraySet contains enabled downstream types, ex:
// {@link ConnectivityManager.TETHERING_WIFI}
// {@link ConnectivityManager.TETHERING_USB}
@@ -112,7 +111,6 @@
public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log,
int permissionChangeMessageCode, MockableSystemProperties systemProperties) {
-
mContext = ctx;
mLog = log.forSubComponent(TAG);
mCurrentTethers = new ArraySet<Integer>();
@@ -138,7 +136,7 @@
/**
* Ui entitlement check fails in |downstream|.
*
- * @param downstream tethering type from ConnectivityManager.TETHERING_{@code *}.
+ * @param downstream tethering type from ConnectivityManager.TETHERING_{@code *}.
*/
void onUiEntitlementFailed(int downstream);
}
@@ -662,7 +660,6 @@
private void handleGetLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver,
boolean showEntitlementUi) {
-
final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration();
if (!isTetherProvisioningRequired(config)) {
receiver.send(TETHER_ERROR_NO_ERROR, null);
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
similarity index 93%
rename from services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
rename to packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 3a9e21f..9769596 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -146,6 +146,7 @@
}
}
+ /** Listen all networks. */
public void startObserveAllNetworks() {
stop();
@@ -155,6 +156,13 @@
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
}
+ /**
+ * Stop tracking candidate tethering upstreams and release mobile network request.
+ * Note: this function is used when tethering is stopped because tethering do not need to
+ * choose upstream anymore. But it would not stop default network tracking because
+ * EntitlementManager may need to know default network to decide whether to request entitlement
+ * check even tethering is not active yet.
+ */
public void stop() {
releaseMobileNetworkRequest();
@@ -165,6 +173,7 @@
mNetworkMap.clear();
}
+ /** Setup or teardown DUN connection according to |dunRequired|. */
public void updateMobileRequiresDun(boolean dunRequired) {
final boolean valueChanged = (mDunRequired != dunRequired);
mDunRequired = dunRequired;
@@ -174,10 +183,12 @@
}
}
+ /** Whether mobile network is requested. */
public boolean mobileNetworkRequested() {
return (mMobileNetworkCallback != null);
}
+ /** Request mobile network if mobile upstream is permitted. */
public void registerMobileNetworkRequest() {
if (!isCellularUpstreamPermitted()) {
mLog.i("registerMobileNetworkRequest() is not permitted");
@@ -209,6 +220,7 @@
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
}
+ /** Release mobile network request. */
public void releaseMobileNetworkRequest() {
if (mMobileNetworkCallback == null) return;
@@ -221,6 +233,9 @@
// becomes available and useful we (a) file a request to keep it up as
// necessary and (b) change all upstream tracking state accordingly (by
// passing LinkProperties up to Tethering).
+ /**
+ * Select the first available network from |perferredTypes|.
+ */
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
@@ -254,7 +269,11 @@
return typeStatePair.ns;
}
- // Returns null if no current upstream available.
+ /**
+ * Get current preferred upstream network. If default network is cellular and DUN is required,
+ * preferred upstream would be DUN otherwise preferred upstream is the same as default network.
+ * Returns null if no current upstream is available.
+ */
public NetworkState getCurrentPreferredUpstream() {
final NetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
@@ -270,10 +289,12 @@
return findFirstDunNetwork(mNetworkMap.values());
}
+ /** Tell UpstreamNetworkMonitor which network is the current upstream of tethering. */
public void setCurrentUpstream(Network upstream) {
mTetheringUpstreamNetwork = upstream;
}
+ /** Return local prefixes. */
public Set<IpPrefix> getLocalPrefixes() {
return (Set<IpPrefix>) mLocalPrefixes.clone();
}
@@ -501,8 +522,8 @@
try {
nc = ConnectivityManager.networkCapabilitiesForType(type);
} catch (IllegalArgumentException iae) {
- Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " +
- ConnectivityManager.getNetworkTypeName(type));
+ Log.e(TAG, "No NetworkCapabilities mapping for legacy type: "
+ + ConnectivityManager.getNetworkTypeName(type));
continue;
}
if (!isCellularUpstreamPermitted && isCellular(nc)) {
@@ -547,18 +568,18 @@
}
private static boolean isCellular(NetworkCapabilities nc) {
- return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR) &&
- nc.hasCapability(NET_CAPABILITY_NOT_VPN);
+ return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR)
+ && nc.hasCapability(NET_CAPABILITY_NOT_VPN);
}
private static boolean hasCapability(NetworkState ns, int netCap) {
- return (ns != null) && (ns.networkCapabilities != null) &&
- ns.networkCapabilities.hasCapability(netCap);
+ return (ns != null) && (ns.networkCapabilities != null)
+ && ns.networkCapabilities.hasCapability(netCap);
}
private static boolean isNetworkUsableAndNotCellular(NetworkState ns) {
- return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null) &&
- !isCellular(ns.networkCapabilities);
+ return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
+ && !isCellular(ns.networkCapabilities);
}
private static NetworkState findFirstDunNetwork(Iterable<NetworkState> netStates) {
diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp
index da62107..7c06e5f 100644
--- a/packages/Tethering/tests/unit/Android.bp
+++ b/packages/Tethering/tests/unit/Android.bp
@@ -17,7 +17,10 @@
android_test {
name: "TetheringTests",
certificate: "platform",
- srcs: ["src/**/*.java"],
+ srcs: [
+ ":servicescore-tethering-src",
+ "src/**/*.java",
+ ],
test_suites: ["device-tests"],
static_libs: [
"androidx.test.rules",
@@ -42,7 +45,9 @@
filegroup {
name: "tethering-tests-src",
srcs: [
+ "src/com/android/server/connectivity/tethering/EntitlementManagerTest.java",
"src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java",
+ "src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java",
"src/android/net/dhcp/DhcpServingParamsParcelExtTest.java",
"src/android/net/ip/IpServerTest.java",
"src/android/net/util/InterfaceSetTest.java",
diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
rename to packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
similarity index 94%
rename from tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
rename to packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index 0d276cb..c028d6d 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -87,7 +87,7 @@
// Actual contents of the request don't matter for this test. The lack of
// any specific TRANSPORT_* is sufficient to identify this request.
- private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
+ private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
@Mock private Context mContext;
@Mock private EntitlementManager mEntitleMgr;
@@ -140,7 +140,7 @@
@Test
public void testDefaultNetworkIsTracked() throws Exception {
assertTrue(mCM.hasNoCallbacks());
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertEquals(1, mCM.trackingDefault.size());
@@ -153,7 +153,7 @@
public void testListensForAllNetworks() throws Exception {
assertTrue(mCM.listening.isEmpty());
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertFalse(mCM.listening.isEmpty());
assertTrue(mCM.isListeningForAll());
@@ -164,9 +164,9 @@
@Test
public void testCallbacksRegistered() {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
verify(mCM, times(1)).requestNetwork(
- eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
+ eq(sDefaultRequest), any(NetworkCallback.class), any(Handler.class));
mUNM.startObserveAllNetworks();
verify(mCM, times(1)).registerNetworkCallback(
any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
@@ -191,7 +191,7 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -217,7 +217,7 @@
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
// Try a few things that must not result in any state change.
mUNM.registerMobileNetworkRequest();
@@ -226,7 +226,7 @@
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
mUNM.stop();
verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
@@ -250,7 +250,7 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -266,17 +266,17 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.updateMobileRequiresDun(true);
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
// Test going from DUN to no-DUN correctly re-registers callbacks.
mUNM.updateMobileRequiresDun(false);
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -287,7 +287,7 @@
final Collection<Integer> preferredTypes = new ArrayList<>();
preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// There are no networks, so there is nothing to select.
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -369,7 +369,7 @@
@Test
public void testGetCurrentPreferredUpstream() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
mUNM.updateMobileRequiresDun(false);
@@ -418,7 +418,7 @@
@Test
public void testLocalPrefixes() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// [0] Test minimum set of local prefixes.
@@ -431,13 +431,13 @@
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
final LinkProperties wifiLp = wifiAgent.linkProperties;
wifiLp.setInterfaceName("wlan0");
- final String[] WIFI_ADDRS = {
+ final String[] wifi_addrs = {
"fe80::827a:bfff:fe6f:374d", "100.112.103.18",
"2001:db8:4:fd00:827a:bfff:fe6f:374d",
"2001:db8:4:fd00:6dea:325a:fdae:4ef4",
"fd6a:a640:60bf:e985::123", // ULA address for good measure.
};
- for (String addrStr : WIFI_ADDRS) {
+ for (String addrStr : wifi_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/20";
wifiLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -458,10 +458,10 @@
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
final LinkProperties cellLp = cellAgent.linkProperties;
cellLp.setInterfaceName("rmnet_data0");
- final String[] CELL_ADDRS = {
+ final String[] cell_addrs = {
"10.102.211.48", "2001:db8:0:1:b50e:70d9:10c9:433d",
};
- for (String addrStr : CELL_ADDRS) {
+ for (String addrStr : cell_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/27";
cellLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -481,10 +481,10 @@
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
final LinkProperties dunLp = dunAgent.linkProperties;
dunLp.setInterfaceName("rmnet_data1");
- final String[] DUN_ADDRS = {
+ final String[] dun_addrs = {
"192.0.2.48", "2001:db8:1:2:b50e:70d9:10c9:433d",
};
- for (String addrStr : DUN_ADDRS) {
+ for (String addrStr : dun_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/27";
dunLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -525,7 +525,7 @@
// Mobile has higher pirority than wifi.
preferredTypes.add(TYPE_MOBILE_HIPRI);
preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// Setup wifi and make wifi as default network.
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
@@ -556,6 +556,15 @@
mCM.legacyTypeMap.values().iterator().next());
}
+ private boolean isDunRequested() {
+ for (NetworkRequest req : mCM.requested.values()) {
+ if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static class TestConnectivityManager extends ConnectivityManager {
public Map<NetworkCallback, Handler> allCallbacks = new HashMap<>();
public Set<NetworkCallback> trackingDefault = new HashSet<>();
@@ -598,17 +607,10 @@
return false;
}
- boolean isDunRequested() {
- for (NetworkRequest req : requested.values()) {
- if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
- return true;
- }
- }
- return false;
+ int getNetworkId() {
+ return ++mNetworkId;
}
- int getNetworkId() { return ++mNetworkId; }
-
void makeDefaultNetwork(TestNetworkAgent agent) {
if (Objects.equals(defaultNetwork, agent)) return;
@@ -630,7 +632,7 @@
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
assertFalse(allCallbacks.containsKey(cb));
allCallbacks.put(cb, h);
- if (mDefaultRequest.equals(req)) {
+ if (sDefaultRequest.equals(req)) {
assertFalse(trackingDefault.contains(cb));
trackingDefault.add(cb);
} else {
@@ -749,9 +751,13 @@
private final State mLoggingState = new LoggingState();
class LoggingState extends State {
- @Override public void enter() { messages.clear(); }
+ @Override public void enter() {
+ messages.clear();
+ }
- @Override public void exit() { messages.clear(); }
+ @Override public void exit() {
+ messages.clear();
+ }
@Override public boolean processMessage(Message msg) {
messages.add(msg);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 05b937a..d4fb9ac 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.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 @@
* 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 @@
* 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/Android.bp b/services/core/Android.bp
index 1643221..ed68f32 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -20,6 +20,7 @@
":vold_aidl",
":gsiservice_aidl",
":platform-compat-config",
+ ":tethering-servicescore-srcs",
"java/com/android/server/EventLogTags.logtags",
"java/com/android/server/am/EventLogTags.logtags",
"java/com/android/server/policy/EventLogTags.logtags",
@@ -48,12 +49,11 @@
"android.hardware.biometrics.fingerprint-V2.1-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
- "android.hardware.vibrator-V1.0-java",
+ "android.hardware.vibrator-V1.4-java",
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
"dnsresolver_aidl_interface-V2-java",
- "netd_aidl_interface-java",
"netd_event_listener_interface-java",
],
}
@@ -81,3 +81,11 @@
name: "gps_debug.conf",
src: "java/com/android/server/location/gps_debug.conf",
}
+
+// TODO: this should be removed after tethering migration done.
+filegroup {
+ name: "servicescore-tethering-src",
+ srcs: [
+ "java/com/android/server/connectivity/MockableSystemProperties.java",
+ ],
+}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0269579..1467888 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -382,7 +382,7 @@
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/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 9936d73..d622fb4 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -29,6 +29,7 @@
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.hardware.vibrator.V1_0.EffectStrength;
+import android.hardware.vibrator.V1_4.Capabilities;
import android.icu.text.DateFormat;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -108,6 +109,9 @@
// If a vibration is playing for longer than 5s, it's probably not haptic feedback.
private static final long MAX_HAPTIC_FEEDBACK_DURATION = 5000;
+ // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration.
+ private static final long ASYNC_TIMEOUT_MULTIPLIER = 2;
+
// A mapping from the intensity adjustment to the scaling to apply, where the intensity
// adjustment is defined as the delta between the default intensity level and the user selected
@@ -123,6 +127,7 @@
private final boolean mAllowPriorityVibrationsInLowPowerMode;
private final boolean mSupportsAmplitudeControl;
private final boolean mSupportsExternalControl;
+ private final long mCapabilities;
private final int mDefaultVibrationAmplitude;
private final SparseArray<VibrationEffect> mFallbackEffects;
private final SparseArray<Integer> mProcStatesCache = new SparseArray();
@@ -163,9 +168,10 @@
static native void vibratorOff();
static native boolean vibratorSupportsAmplitudeControl();
static native void vibratorSetAmplitude(int amplitude);
- static native long vibratorPerformEffect(long effect, long strength);
+ static native long vibratorPerformEffect(long effect, long strength, Vibration vibration);
static native boolean vibratorSupportsExternalControl();
static native void vibratorSetExternalControl(boolean enabled);
+ static native long vibratorGetCapabilities();
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
@@ -226,6 +232,14 @@
}
}
+ private void onComplete() {
+ synchronized (mLock) {
+ if (this == mCurrentVibration) {
+ doCancelVibrateLocked();
+ }
+ }
+ }
+
public boolean hasTimeoutLongerThan(long millis) {
final long duration = effect.getDuration();
return duration >= 0 && duration > millis;
@@ -347,6 +361,7 @@
mSupportsAmplitudeControl = vibratorSupportsAmplitudeControl();
mSupportsExternalControl = vibratorSupportsExternalControl();
+ mCapabilities = vibratorGetCapabilities();
mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -1135,10 +1150,14 @@
}
// Input devices don't support prebaked effect, so skip trying it with them.
if (!usingInputDeviceVibrators) {
- long timeout = vibratorPerformEffect(prebaked.getId(),
- prebaked.getEffectStrength());
+ long duration = vibratorPerformEffect(prebaked.getId(),
+ prebaked.getEffectStrength(), vib);
+ long timeout = duration;
+ if ((mCapabilities & Capabilities.PERFORM_COMPLETION_CALLBACK) != 0) {
+ timeout *= ASYNC_TIMEOUT_MULTIPLIER;
+ }
if (timeout > 0) {
- noteVibratorOnLocked(vib.uid, timeout);
+ noteVibratorOnLocked(vib.uid, duration);
return timeout;
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7bc2e6d..6cbbcdd 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -192,34 +192,38 @@
@Override
public void stopForegroundServicesForUidPackage(final int uid, final String packageName) {
synchronized (mAm) {
- final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
- final int N = smap.mServicesByInstanceName.size();
- final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
- for (int i = 0; i < N; i++) {
- final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
- if (uid == r.serviceInfo.applicationInfo.uid
- || packageName.equals(r.serviceInfo.packageName)) {
- if (r.isForeground) {
- toStop.add(r);
- }
- }
- }
+ stopAllForegroundServicesLocked(uid, packageName);
+ }
+ }
+ }
- // Now stop them all
- final int numToStop = toStop.size();
- if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, "Package " + packageName + "/" + uid
- + " entering FAS with foreground services");
- }
- for (int i = 0; i < numToStop; i++) {
- final ServiceRecord r = toStop.get(i);
- if (DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, " Stopping fg for service " + r);
- }
- setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ void stopAllForegroundServicesLocked(final int uid, final String packageName) {
+ final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
+ final int N = smap.mServicesByInstanceName.size();
+ final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
+ for (int i = 0; i < N; i++) {
+ final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
+ if (uid == r.serviceInfo.applicationInfo.uid
+ || packageName.equals(r.serviceInfo.packageName)) {
+ if (r.isForeground) {
+ toStop.add(r);
}
}
}
+
+ // Now stop them all
+ final int numToStop = toStop.size();
+ if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, "Package " + packageName + "/" + uid
+ + " in FAS with foreground services");
+ }
+ for (int i = 0; i < numToStop; i++) {
+ final ServiceRecord r = toStop.get(i);
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, " Stopping fg for service " + r);
+ }
+ setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ }
}
/**
@@ -1010,12 +1014,23 @@
}
}
if (!aa.mAppOnTop) {
- if (active == null) {
- active = new ArrayList<>();
+ // Transitioning a fg-service host app out of top: if it's bg restricted,
+ // it loses the fg service state now.
+ if (!appRestrictedAnyInBackground(aa.mUid, aa.mPackageName)) {
+ if (active == null) {
+ active = new ArrayList<>();
+ }
+ if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
+ + aa.mPackageName + ", uid=" + aa.mUid);
+ active.add(aa);
+ } else {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "bg-restricted app "
+ + aa.mPackageName + "/" + aa.mUid
+ + " exiting top; demoting fg services ");
+ }
+ stopAllForegroundServicesLocked(aa.mUid, aa.mPackageName);
}
- if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
- + aa.mPackageName + ", uid=" + aa.mUid);
- active.add(aa);
}
}
smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index bc5973d..8762435 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -20,6 +20,7 @@
import android.compat.annotation.EnabledAfter;
import android.content.pm.ApplicationInfo;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.server.compat.config.Change;
import java.util.HashMap;
@@ -35,12 +36,8 @@
*
* <p>Note, this class is not thread safe so callers must ensure thread safety.
*/
-public final class CompatChange {
+public final class CompatChange extends CompatibilityChangeInfo {
- private final long mChangeId;
- @Nullable private final String mName;
- private final int mEnableAfterTargetSdk;
- private final boolean mDisabled;
private Map<String, Boolean> mPackageOverrides;
public CompatChange(long changeId) {
@@ -56,29 +53,15 @@
*/
public CompatChange(long changeId, @Nullable String name, int enableAfterTargetSdk,
boolean disabled) {
- mChangeId = changeId;
- mName = name;
- mEnableAfterTargetSdk = enableAfterTargetSdk;
- mDisabled = disabled;
+ super(changeId, name, enableAfterTargetSdk, disabled);
}
/**
* @param change an object generated by services/core/xsd/platform-compat-config.xsd
*/
public CompatChange(Change change) {
- mChangeId = change.getId();
- mName = change.getName();
- mEnableAfterTargetSdk = change.getEnableAfterTargetSdk();
- mDisabled = change.getDisabled();
- }
-
- long getId() {
- return mChangeId;
- }
-
- @Nullable
- String getName() {
- return mName;
+ super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
+ change.getDisabled());
}
/**
@@ -121,11 +104,11 @@
if (mPackageOverrides != null && mPackageOverrides.containsKey(app.packageName)) {
return mPackageOverrides.get(app.packageName);
}
- if (mDisabled) {
+ if (getDisabled()) {
return false;
}
- if (mEnableAfterTargetSdk != -1) {
- return app.targetSdkVersion > mEnableAfterTargetSdk;
+ if (getEnableAfterTargetSdk() != -1) {
+ return app.targetSdkVersion > getEnableAfterTargetSdk();
}
return true;
}
@@ -133,14 +116,14 @@
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ChangeId(")
- .append(mChangeId);
- if (mName != null) {
- sb.append("; name=").append(mName);
+ .append(getId());
+ if (getName() != null) {
+ sb.append("; name=").append(getName());
}
- if (mEnableAfterTargetSdk != -1) {
- sb.append("; enableAfterTargetSdk=").append(mEnableAfterTargetSdk);
+ if (getEnableAfterTargetSdk() != -1) {
+ sb.append("; enableAfterTargetSdk=").append(getEnableAfterTargetSdk());
}
- if (mDisabled) {
+ if (getDisabled()) {
sb.append("; disabled");
}
if (mPackageOverrides != null && mPackageOverrides.size() > 0) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 0fabd9a..d6ec22b 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -16,6 +16,7 @@
package com.android.server.compat;
+import android.compat.Compatibility.ChangeConfig;
import android.content.pm.ApplicationInfo;
import android.os.Environment;
import android.text.TextUtils;
@@ -26,6 +27,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.server.compat.config.Change;
import com.android.server.compat.config.XmlParser;
@@ -37,6 +39,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
import javax.xml.datatype.DatatypeConfigurationException;
/**
@@ -243,6 +247,49 @@
}
}
+ /**
+ * Get the config for a given app.
+ *
+ * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped.
+ * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the
+ * given app.
+ */
+
+ public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ synchronized (mChanges) {
+ for (int i = 0; i < mChanges.size(); ++i) {
+ CompatChange c = mChanges.valueAt(i);
+ if (c.isEnabled(applicationInfo)) {
+ enabled.add(c.getId());
+ } else {
+ disabled.add(c.getId());
+ }
+ }
+ }
+ return new CompatibilityChangeConfig(new ChangeConfig(enabled, disabled));
+ }
+
+ /**
+ * Dumps all the compatibility change information.
+ *
+ * @return An array of {@link CompatibilityChangeInfo} with the current changes.
+ */
+ public CompatibilityChangeInfo[] dumpChanges() {
+ synchronized (mChanges) {
+ CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()];
+ for (int i = 0; i < mChanges.size(); ++i) {
+ CompatChange change = mChanges.valueAt(i);
+ changeInfos[i] = new CompatibilityChangeInfo(change.getId(),
+ change.getName(),
+ change.getEnableAfterTargetSdk(),
+ change.getDisabled());
+ }
+ return changeInfos;
+ }
+ }
+
CompatConfig initConfigFromLib(File libraryDir) {
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.e(TAG, "No directory " + libraryDir + ", skipping");
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 9ac9955..75e2d22 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -25,6 +25,7 @@
import com.android.internal.compat.ChangeReporter;
import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.util.DumpUtils;
@@ -114,6 +115,16 @@
}
@Override
+ public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
+ return CompatConfig.get().getAppConfig(appInfo);
+ }
+
+ @Override
+ public CompatibilityChangeInfo[] listAllChanges() {
+ return CompatConfig.get().dumpChanges();
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
CompatConfig.get().dumpConfig(pw);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index c5c53d8..a18a53d 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 @@
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/Android.bp b/services/core/jni/Android.bp
index 3bc239b..248baf7 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -130,6 +130,7 @@
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
+ "android.hardware.vibrator@1.4",
"android.hardware.vr@1.0",
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index d5fbd2b..64c7935 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -16,17 +16,12 @@
#define LOG_TAG "VibratorService"
-#include <android/hardware/vibrator/1.0/IVibrator.h>
-#include <android/hardware/vibrator/1.0/types.h>
-#include <android/hardware/vibrator/1.0/IVibrator.h>
-#include <android/hardware/vibrator/1.1/types.h>
-#include <android/hardware/vibrator/1.2/IVibrator.h>
-#include <android/hardware/vibrator/1.2/types.h>
-#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <android/hardware/vibrator/1.4/IVibrator.h>
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
+#include "core_jni_helpers.h"
#include <utils/misc.h>
#include <utils/Log.h>
@@ -36,6 +31,7 @@
#include <stdio.h>
using android::hardware::Return;
+using android::hardware::Void;
using android::hardware::vibrator::V1_0::EffectStrength;
using android::hardware::vibrator::V1_0::Status;
using android::hardware::vibrator::V1_1::Effect_1_1;
@@ -44,9 +40,32 @@
namespace V1_1 = android::hardware::vibrator::V1_1;
namespace V1_2 = android::hardware::vibrator::V1_2;
namespace V1_3 = android::hardware::vibrator::V1_3;
+namespace V1_4 = android::hardware::vibrator::V1_4;
namespace android {
+static jmethodID sMethodIdOnComplete;
+
+class VibratorCallback : public V1_4::IVibratorCallback {
+ public:
+ VibratorCallback(JNIEnv *env, jobject vibration) :
+ mVibration(MakeGlobalRefOrDie(env, vibration)) {}
+
+ ~VibratorCallback() {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ env->DeleteGlobalRef(mVibration);
+ }
+
+ Return<void> onComplete() override {
+ auto env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mVibration, sMethodIdOnComplete);
+ return Void();
+ }
+
+ private:
+ jobject mVibration;
+};
+
static constexpr int NUM_TRIES = 2;
// Creates a Return<R> with STATUS::EX_NULL_POINTER.
@@ -56,37 +75,57 @@
return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
}
-// Helper used to transparently deal with the vibrator HAL becoming unavailable.
+template <typename I>
+class HalWrapper {
+ public:
+ static std::unique_ptr<HalWrapper> Create() {
+ // Assume that if getService returns a nullptr, HAL is not available on the
+ // device.
+ auto hal = I::getService();
+ return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
+ }
+
+ // Helper used to transparently deal with the vibrator HAL becoming unavailable.
+ template<class R, class... Args0, class... Args1>
+ Return<R> call(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+ // Return<R> doesn't have a default constructor, so make a Return<R> with
+ // STATUS::EX_NONE.
+ using ::android::hardware::Status;
+ Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+
+ // Note that ret is guaranteed to be changed after this loop.
+ for (int i = 0; i < NUM_TRIES; ++i) {
+ ret = (mHal == nullptr) ? NullptrStatus<R>()
+ : (*mHal.*fn)(std::forward<Args1>(args1)...);
+
+ if (ret.isOk()) {
+ break;
+ }
+
+ ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+ // Restoring connection to the HAL.
+ mHal = I::tryGetService();
+ }
+ return ret;
+ }
+
+ private:
+ HalWrapper(sp<I> &&hal) : mHal(std::move(hal)) {}
+
+ private:
+ sp<I> mHal;
+};
+
+template <typename I>
+static auto getHal() {
+ static auto sHalWrapper = HalWrapper<I>::Create();
+ return sHalWrapper.get();
+}
+
template<class R, class I, class... Args0, class... Args1>
Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
- // Assume that if getService returns a nullptr, HAL is not available on the
- // device.
- static sp<I> sHal = I::getService();
- static bool sAvailable = sHal != nullptr;
-
- if (!sAvailable) {
- return NullptrStatus<R>();
- }
-
- // Return<R> doesn't have a default constructor, so make a Return<R> with
- // STATUS::EX_NONE.
- using ::android::hardware::Status;
- Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
-
- // Note that ret is guaranteed to be changed after this loop.
- for (int i = 0; i < NUM_TRIES; ++i) {
- ret = (sHal == nullptr) ? NullptrStatus<R>()
- : (*sHal.*fn)(std::forward<Args1>(args1)...);
-
- if (ret.isOk()) {
- break;
- }
-
- ALOGE("Failed to issue command to vibrator HAL. Retrying.");
- // Restoring connection to the HAL.
- sHal = I::tryGetService();
- }
- return ret;
+ auto hal = getHal<I>();
+ return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
}
template<class R>
@@ -99,17 +138,17 @@
return val >= *iter.begin() && val <= *std::prev(iter.end());
}
-static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
+static void vibratorInit(JNIEnv *env, jclass clazz)
{
halCall(&V1_0::IVibrator::ping).isOk();
}
-static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
+static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */)
{
return halCall(&V1_0::IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
}
-static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
+static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
{
Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
if (retStatus != Status::OK) {
@@ -117,7 +156,7 @@
}
}
-static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
+static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */)
{
Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
if (retStatus != Status::OK) {
@@ -125,11 +164,11 @@
}
}
-static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) {
+static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jclass) {
return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
}
-static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) {
+static void vibratorSetAmplitude(JNIEnv*, jclass, jint amplitude) {
Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
.withDefault(Status::UNKNOWN_ERROR);
if (status != Status::OK) {
@@ -138,11 +177,11 @@
}
}
-static jboolean vibratorSupportsExternalControl(JNIEnv*, jobject) {
+static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) {
return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
}
-static void vibratorSetExternalControl(JNIEnv*, jobject, jboolean enabled) {
+static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) {
Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
.withDefault(Status::UNKNOWN_ERROR);
if (status != Status::OK) {
@@ -151,7 +190,8 @@
}
}
-static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
+static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong strength,
+ jobject vibration) {
Status status;
uint32_t lengthMs;
auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
@@ -161,7 +201,11 @@
EffectStrength effectStrength(static_cast<EffectStrength>(strength));
Return<void> ret;
- if (isValidEffect<V1_0::Effect>(effect)) {
+ if (auto hal = getHal<V1_4::IVibrator>(); hal && isValidEffect<V1_3::Effect>(effect)) {
+ sp<VibratorCallback> effectCallback = new VibratorCallback(env, vibration);
+ ret = hal->call(&V1_4::IVibrator::perform_1_4, static_cast<V1_3::Effect>(effect),
+ effectStrength, effectCallback, callback);
+ } else if (isValidEffect<V1_0::Effect>(effect)) {
ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
effectStrength, callback);
} else if (isValidEffect<Effect_1_1>(effect)) {
@@ -198,6 +242,10 @@
return -1;
}
+static jlong vibratorGetCapabilities(JNIEnv*, jclass) {
+ return halCall(&V1_4::IVibrator::getCapabilities).withDefault(0);
+}
+
static const JNINativeMethod method_table[] = {
{ "vibratorExists", "()Z", (void*)vibratorExists },
{ "vibratorInit", "()V", (void*)vibratorInit },
@@ -205,13 +253,18 @@
{ "vibratorOff", "()V", (void*)vibratorOff },
{ "vibratorSupportsAmplitudeControl", "()Z", (void*)vibratorSupportsAmplitudeControl},
{ "vibratorSetAmplitude", "(I)V", (void*)vibratorSetAmplitude},
- { "vibratorPerformEffect", "(JJ)J", (void*)vibratorPerformEffect},
+ { "vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;)J",
+ (void*)vibratorPerformEffect},
{ "vibratorSupportsExternalControl", "()Z", (void*)vibratorSupportsExternalControl},
{ "vibratorSetExternalControl", "(Z)V", (void*)vibratorSetExternalControl},
+ { "vibratorGetCapabilities", "()J", (void*)vibratorGetCapabilities},
};
int register_android_server_VibratorService(JNIEnv *env)
{
+ sMethodIdOnComplete = GetMethodIDOrDie(env,
+ FindClassOrDie(env, "com/android/server/VibratorService$Vibration"),
+ "onComplete", "()V");
return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
method_table, NELEM(method_table));
}
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 08cdbfc..e24dec5 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -1,12 +1,12 @@
java_library_static {
name: "services.net",
srcs: [
- ":tethering-services-srcs",
+ ":tethering-servicesnet-srcs",
"java/**/*.java",
],
static_libs: [
"dnsresolver_aidl_interface-V2-java",
- "netd_aidl_interface-java",
+ "netd_aidl_interface-unstable-java",
"networkstack-client",
"tethering-client",
],
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index ecddeb3..eecdeed 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -74,7 +74,7 @@
"libui",
"libunwindstack",
"libutils",
- "netd_aidl_interface-V2-cpp",
+ "netd_aidl_interface-cpp",
],
dxflags: ["--multi-dex"],
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 4a9cef1..92198fa 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -55,6 +55,6 @@
"libui",
"libunwindstack",
"libutils",
- "netd_aidl_interface-V2-cpp",
+ "netd_aidl_interface-cpp",
],
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 2ce84fb..4f373af 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -857,7 +857,7 @@
}
/** @hide */
- public abstract static class Listener {
+ abstract static class Listener {
public void onStateChanged(Connection c, int state) {}
public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
public void onCallerDisplayNameChanged(
@@ -2005,7 +2005,7 @@
*
* @hide
*/
- public final Connection addConnectionListener(Listener l) {
+ final Connection addConnectionListener(Listener l) {
mListeners.add(l);
return this;
}
@@ -2018,7 +2018,7 @@
*
* @hide
*/
- public final Connection removeConnectionListener(Listener l) {
+ final Connection removeConnectionListener(Listener l) {
if (l != null) {
mListeners.remove(l);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index fc0c2e8..e458ae6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1831,6 +1831,13 @@
"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 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 @@
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 @@
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/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 1912c60..f9b7f6d 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -194,13 +194,13 @@
/** @hide */
@Override
public void updateLevel(PersistableBundle cc, ServiceState ss) {
- if (mCsiRsrp == CellInfo.UNAVAILABLE) {
+ if (mSsRsrp == CellInfo.UNAVAILABLE) {
mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- } else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_GREAT_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_GREAT;
- } else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_GOOD_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_GOOD;
- } else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_MODERATE_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_MODERATE;
} else {
mLevel = SIGNAL_STRENGTH_POOR;
@@ -212,7 +212,7 @@
*
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
*
- * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
+ * @return RSRP in ASU 0..97, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
@@ -231,11 +231,11 @@
}
/**
- * Get the CSI-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
+ * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
*/
@Override
public int getDbm() {
- return mCsiRsrp;
+ return mSsRsrp;
}
/** @hide */
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 209d462..f661bba 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -3049,4 +3049,74 @@
}
return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
}
+
+ /**
+ * Gets the SMSC address from (U)SIM.
+ *
+ * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
+ * default SMS application, or READ_PRIVILEGED_PHONE_STATE permission, or has the carrier
+ * privileges.</p>
+ *
+ * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
+ * dialog. If this method is called on a device that has multiple active subscriptions, this
+ * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
+ * default subscription is defined, the subscription ID associated with this method will be
+ * INVALID, which will result in the operation being completed on the subscription associated
+ * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
+ * is performed on the correct subscription.
+ * </p>
+ *
+ * @return the SMSC address string, null if failed.
+ */
+ @SuppressAutoDoc // for carrier privileges and default SMS application.
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @Nullable
+ public String getSmscAddress() {
+ String smsc = null;
+
+ try {
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ smsc = iSms.getSmscAddressFromIccEfForSubscriber(
+ getSubscriptionId(), ActivityThread.currentPackageName());
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ return smsc;
+ }
+
+ /**
+ * Sets the SMSC address on (U)SIM.
+ *
+ * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
+ * default SMS application, or has {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+ * permission, or has the carrier privileges.</p>
+ *
+ * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
+ * dialog. If this method is called on a device that has multiple active subscriptions, this
+ * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
+ * default subscription is defined, the subscription ID associated with this method will be
+ * INVALID, which will result in the operation being completed on the subscription associated
+ * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
+ * is performed on the correct subscription.
+ * </p>
+ *
+ * @param smsc the SMSC address string.
+ * @return true for success, false otherwise.
+ */
+ @SuppressAutoDoc // for carrier privileges and default SMS application.
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public boolean setSmscAddress(@NonNull String smsc) {
+ try {
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ return iSms.setSmscAddressOnIccEfForSubscriber(
+ smsc, getSubscriptionId(), ActivityThread.currentPackageName());
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ return false;
+ }
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 97c46e3..4e93efd 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2095,13 +2095,13 @@
/** @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 311d260..c9440a6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -289,6 +289,21 @@
};
/** @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 @@
/**
* 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 @@
// 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
+ * 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 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();
- }
+ public @ModemCount int getSupportedModemCount() {
+ return SystemProperties.getInt(TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS,
+ getActiveModemCount());
}
/** {@hide} */
@@ -1177,6 +1193,35 @@
"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 @@
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) {
@@ -9412,10 +9462,12 @@
}
/**
- * Resets telephony manager settings back to factory defaults.
+ * Resets Telephony and IMS settings back to factory defaults.
*
* @hide
*/
+ @SystemApi
+ @RequiresPermission(Manifest.permission.CONNECTIVITY_INTERNAL)
public void factoryReset(int subId) {
try {
Log.d(TAG, "factoryReset: subId=" + subId);
@@ -10132,11 +10184,13 @@
/**
* 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 +10205,13 @@
/**
* 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 +10225,12 @@
/**
* 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 116c051..e65e032 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1206,7 +1206,7 @@
&& !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 @@
&& 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 @@
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
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 2fad847..ed292be 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -25,14 +25,13 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.telephony.AccessNetworkConstants;
+import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.aidl.IImsRegistrationCallback;
@@ -42,6 +41,7 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.ITelephony;
import java.lang.annotation.Retention;
@@ -49,6 +49,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* A manager for the MmTel (Multimedia Telephony) feature of an IMS network, given an associated
@@ -64,8 +65,6 @@
@SystemApi
public class ImsMmTelManager {
- private static final String TAG = "ImsMmTelManager";
-
/**
* @hide
*/
@@ -311,7 +310,7 @@
}
}
- private int mSubId;
+ private final int mSubId;
/**
* Create an instance of {@link ImsMmTelManager} for the subscription id specified.
@@ -366,10 +365,6 @@
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
- if (!isImsAvailableOnDevice()) {
- throw new ImsException("IMS not available on device.",
- ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
- }
c.setExecutor(executor);
try {
getITelephony().registerImsRegistrationCallback(mSubId, c.getBinder());
@@ -378,7 +373,7 @@
// Rethrow as runtime error to keep API compatible.
throw new IllegalArgumentException(e.getMessage());
} else {
- throw new RuntimeException(e.getMessage());
+ throw new ImsException(e.getMessage(), e.errorCode);
}
} catch (RemoteException | IllegalStateException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
@@ -441,10 +436,6 @@
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
- if (!isImsAvailableOnDevice()) {
- throw new ImsException("IMS not available on device.",
- ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
- }
c.setExecutor(executor);
try {
getITelephony().registerMmTelCapabilityCallback(mSubId, c.getBinder());
@@ -453,7 +444,7 @@
// Rethrow as runtime error to keep API compatible.
throw new IllegalArgumentException(e.getMessage());
} else {
- throw new RuntimeException(e.getMessage());
+ throw new ImsException(e.getMessage(), e.errorCode);
}
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
@@ -618,6 +609,46 @@
}
/**
+ * Query whether or not the requested MmTel capability is supported by the carrier on the
+ * specified network transport.
+ * <p>
+ * This is a configuration option and does not change. The only time this may change is if a
+ * new IMS configuration is loaded when there is a
+ * {@link CarrierConfigManager#ACTION_CARRIER_CONFIG_CHANGED} broadcast for this subscription.
+ * @param capability The capability that is being queried for support on the carrier network.
+ * @param transportType The transport type of the capability to check support for.
+ * @param callback A consumer containing a Boolean result specifying whether or not the
+ * capability is supported on this carrier network for the transport specified.
+ * @param executor The executor that the callback will be called with.
+ * @throws ImsException if the subscription is no longer valid or the IMS service is not
+ * available.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void isSupported(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+ @AccessNetworkConstants.TransportType int transportType,
+ @NonNull Consumer<Boolean> callback,
+ @NonNull @CallbackExecutor Executor executor) throws ImsException {
+ if (callback == null) {
+ throw new IllegalArgumentException("Must include a non-null Consumer.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ try {
+ getITelephony().isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> callback.accept(result == 1));
+ }
+ }, capability, transportType);
+ } catch (ServiceSpecificException sse) {
+ throw new ImsException(sse.getMessage(), sse.errorCode);
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
* The user's setting for whether or not they have enabled the "Video Calling" setting.
*
* @throws IllegalArgumentException if the subscription associated with this operation is not
@@ -940,7 +971,7 @@
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- boolean isTtyOverVolteEnabled() {
+ public boolean isTtyOverVolteEnabled() {
try {
return getITelephony().isTtyOverVolteEnabled(mSubId);
} catch (ServiceSpecificException e) {
@@ -955,20 +986,39 @@
}
}
- private static boolean isImsAvailableOnDevice() {
- IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
- if (pm == null) {
- // For some reason package manger is not available.. This will fail internally anyways,
- // so do not throw error and allow.
- return true;
+ /**
+ * Get the status of the MmTel Feature registered on this subscription.
+ * @param callback A callback containing an Integer describing the current state of the
+ * MmTel feature, Which will be one of the following:
+ * {@link ImsFeature#STATE_UNAVAILABLE},
+ * {@link ImsFeature#STATE_INITIALIZING},
+ * {@link ImsFeature#STATE_READY}. Will be called using the executor
+ * specified when the service state has been retrieved from the IMS service.
+ * @param executor The executor that will be used to call the callback.
+ * @throws ImsException if the IMS service associated with this subscription is not available or
+ * the IMS service is not available.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void getFeatureState(@NonNull @ImsFeature.ImsState Consumer<Integer> callback,
+ @NonNull @CallbackExecutor Executor executor) throws ImsException {
+ if (callback == null) {
+ throw new IllegalArgumentException("Must include a non-null Consumer.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
}
try {
- return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
+ getITelephony().getImsMmTelFeatureState(mSubId, new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> callback.accept(result));
+ }
+ });
+ } catch (ServiceSpecificException sse) {
+ throw new ImsException(sse.getMessage(), sse.errorCode);
} catch (RemoteException e) {
- // For some reason package manger is not available.. This will fail internally anyways,
- // so do not throw error and allow.
+ e.rethrowAsRuntimeException();
}
- return true;
}
private static ITelephony getITelephony() {
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index ceb4704..8b27b6f 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -362,6 +362,25 @@
@Retention(RetentionPolicy.SOURCE)
public @interface ProcessCallResult {}
+ /**
+ * If the flag is present and true, it indicates that the incoming call is for USSD.
+ * <p>
+ * This is an optional boolean flag.
+ */
+ public static final String EXTRA_IS_USSD = "android.telephony.ims.feature.extra.IS_USSD";
+
+ /**
+ * If this flag is present and true, this call is marked as an unknown dialing call instead
+ * of an incoming call. An example of such a call is a call that is originated by sending
+ * commands (like AT commands) directly to the modem without Android involvement or dialing
+ * calls appearing over IMS when the modem does a silent redial from circuit-switched to IMS in
+ * certain situations.
+ * <p>
+ * This is an optional boolean flag.
+ */
+ public static final String EXTRA_IS_UNKNOWN_CALL =
+ "android.telephony.ims.feature.extra.IS_UNKNOWN_CALL";
+
private IImsMmTelListener mListener;
/**
@@ -410,6 +429,8 @@
/**
* Notify the framework of an incoming call.
* @param c The {@link ImsCallSessionImplBase} of the new incoming call.
+ * @param extras A bundle containing extra parameters related to the call. See
+ * {@link #EXTRA_IS_UNKNOWN_CALL} and {@link #EXTRA_IS_USSD} above.
*/
public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
@NonNull Bundle extras) {
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 7441c26..c1d700a 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -586,4 +586,23 @@
* @param destAddress the destination address to test for possible short code
*/
int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
+
+ /**
+ * Gets the SMSC address from (U)SIM.
+ *
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ * @return the SMSC address string, null if failed.
+ */
+ String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage);
+
+ /**
+ * Sets the SMSC address on (U)SIM.
+ *
+ * @param smsc the SMSC address string.
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ * @return true for success, false otherwise.
+ */
+ boolean setSmscAddressOnIccEfForSubscriber(String smsc, int subId, String callingPackage);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index aa1f94f..ff816f2 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -208,4 +208,15 @@
int subid, String callingApk, String destAddress, String countryIso) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean setSmscAddressOnIccEfForSubscriber(
+ String smsc, int subId, String callingPackage) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d899a59..ab3861e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -864,6 +864,11 @@
String getImsService(int slotId, boolean isCarrierImsService);
/**
+ * Get the MmTelFeature state attached to this subscription id.
+ */
+ void getImsMmTelFeatureState(int subId, IIntegerConsumer callback);
+
+ /**
* Set the network selection mode to automatic.
*
* @param subId the id of the subscription to update.
@@ -1774,21 +1779,6 @@
boolean isInEmergencySmsMode();
/**
- * Get a list of SMS apps on a user.
- */
- String[] getSmsApps(int userId);
-
- /**
- * Get the default SMS app on a given user.
- */
- String getDefaultSmsApp(int userId);
-
- /**
- * Set the default SMS app to a given package on a given user.
- */
- void setDefaultSmsApp(int userId, String packageName);
-
- /**
* Return the modem radio power state for slot index.
*
*/
@@ -1826,6 +1816,12 @@
boolean isAvailable(int subId, int capability, int regTech);
/**
+ * Return whether or not the MmTel capability is supported for the requested transport type.
+ */
+ void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
+ int transportType);
+
+ /**
* Returns true if the user's setting for 4G LTE is enabled, for the subscription specified.
*/
boolean isAdvancedCallingSettingEnabled(int subId);
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index b9b2238..10f27e2 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -37,7 +37,7 @@
"libvndksupport",
"libziparchive",
"libz",
- "netd_aidl_interface-V2-cpp",
+ "netd_aidl_interface-cpp",
],
}