summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp23
-rw-r--r--api/system-current.txt6
-rw-r--r--core/java/android/provider/SettingsStringUtil.java2
-rw-r--r--core/java/com/android/internal/compat/CompatibilityChangeConfig.java12
-rw-r--r--core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl19
-rw-r--r--core/java/com/android/internal/compat/CompatibilityChangeInfo.java92
-rw-r--r--core/java/com/android/internal/compat/IPlatformCompat.aidl19
-rw-r--r--core/proto/OWNERS2
-rw-r--r--location/lib/Android.bp2
-rw-r--r--media/jni/Android.bp7
-rw-r--r--media/lib/signer/Android.bp2
-rw-r--r--packages/Shell/AndroidManifest.xml27
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java2
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpActivity.java142
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpProvider.java101
-rw-r--r--packages/Shell/src/com/android/shell/HeapDumpReceiver.java188
-rw-r--r--packages/Tethering/Android.bp13
-rw-r--r--packages/Tethering/AndroidManifestBase.xml3
-rw-r--r--packages/Tethering/src/android/net/util/PrefixUtils.java (renamed from services/net/java/android/net/util/PrefixUtils.java)5
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java (renamed from services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java)5
-rw-r--r--packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java (renamed from services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java)39
-rw-r--r--packages/Tethering/tests/unit/Android.bp7
-rw-r--r--packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java (renamed from tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java)0
-rw-r--r--packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java (renamed from tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java)74
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java26
-rw-r--r--services/core/Android.bp9
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java73
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java45
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java47
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java11
-rw-r--r--services/net/Android.bp4
-rw-r--r--services/tests/servicestests/Android.bp2
-rw-r--r--services/tests/uiservicestests/Android.bp2
-rw-r--r--telecomm/java/android/telecom/Connection.java6
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java8
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java4
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java102
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java21
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl26
-rw-r--r--tests/net/Android.bp2
40 files changed, 972 insertions, 208 deletions
diff --git a/Android.bp b/Android.bp
index f735f9e34f39..90dca0350a0c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1418,29 +1418,6 @@ droidstubs {
" --show-annotation android.annotation.TestApi ",
}
-filegroup {
- name: "apache-http-stubs-sources",
- srcs: [
- "core/java/org/apache/http/conn/ConnectTimeoutException.java",
- "core/java/org/apache/http/conn/scheme/HostNameResolver.java",
- "core/java/org/apache/http/conn/scheme/LayeredSocketFactory.java",
- "core/java/org/apache/http/conn/scheme/SocketFactory.java",
- "core/java/org/apache/http/conn/ssl/AbstractVerifier.java",
- "core/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java",
- "core/java/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/SSLSocketFactory.java",
- "core/java/org/apache/http/conn/ssl/StrictHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/X509HostnameVerifier.java",
- "core/java/org/apache/http/params/CoreConnectionPNames.java",
- "core/java/org/apache/http/params/HttpConnectionParams.java",
- "core/java/org/apache/http/params/HttpParams.java",
- "core/java/android/net/http/SslCertificate.java",
- "core/java/android/net/http/SslError.java",
- "core/java/com/android/internal/util/HexDump.java",
- ],
-}
-
droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
diff --git a/api/system-current.txt b/api/system-current.txt
index 2321e3e78b18..6574c802b339 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8159,6 +8159,7 @@ package android.telephony {
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);
@@ -8812,11 +8813,14 @@ package android.telephony.ims {
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();
@@ -9343,6 +9347,8 @@ package android.telephony.ims.feature {
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/provider/SettingsStringUtil.java b/core/java/android/provider/SettingsStringUtil.java
index a3dc9471a1d0..9e495dd775dc 100644
--- a/core/java/android/provider/SettingsStringUtil.java
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -126,7 +126,7 @@ public class SettingsStringUtil {
@Override
protected String itemToString(ComponentName item) {
- return item.flattenToString();
+ return item != null ? item.flattenToString() : "null";
}
public static String add(String delimitedElements, ComponentName element) {
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index fd2ada08edc1..36bc22906695 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -49,6 +49,18 @@ public final class CompatibilityChangeConfig implements Parcelable {
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 000000000000..3bc72771f99c
--- /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 000000000000..e48e2df4043c
--- /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 8391ad2f12c2..5857642cbd4e 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 @@ interface IPlatformCompat
*
*/
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/proto/OWNERS b/core/proto/OWNERS
index 6ab0fc91d744..74ced8921799 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -3,8 +3,10 @@
# Metrics
joeo@google.com
singhtejinder@google.com
+yanmin@google.com
yaochen@google.com
yro@google.com
+zhouwenjie@google.com
# Settings UI
per-file settings_enums.proto=tmfang@google.com
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index fe0f669508eb..cd45e8e6ffa6 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -17,10 +17,8 @@
java_sdk_library {
name: "com.android.location.provider",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
libs: [
"androidx.annotation_annotation",
- "framework-all",
],
api_packages: ["com.android.location.provider"],
}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index e6c1c67b98e5..f873eeb9aa00 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -100,13 +100,14 @@ cc_library_shared {
"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/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 6b03e4de57d7..3b2578754087 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -17,7 +17,5 @@
java_sdk_library {
name: "com.android.mediadrm.signer",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
- libs: ["framework-all"],
api_packages: ["com.android.mediadrm.signer"],
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 11b0487a64b2..047ac5984fe3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -173,6 +173,8 @@
<uses-permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED" />
<!-- Permission needed to invoke DynamicSystem (AOT) -->
<uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
+ <!-- Used to clean up heap dumps on boot. -->
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
@@ -201,7 +203,7 @@
<!-- Permission required to test ExplicitHealthCheckServiceImpl. -->
<uses-permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE" />
-
+
<!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
@@ -231,12 +233,25 @@
</intent-filter>
</provider>
+ <provider android:name=".HeapDumpProvider"
+ android:authorities="com.android.shell.heapdump"
+ android:grantUriPermissions="true"
+ android:exported="true" />
+
<activity
android:name=".BugreportWarningActivity"
android:finishOnCloseSystemDialogs="true"
android:excludeFromRecents="true"
android:exported="false" />
+ <activity android:name=".HeapDumpActivity"
+ android:theme="@*android:style/Theme.Translucent.NoTitleBar"
+ android:label="@*android:string/dump_heap_title"
+ android:finishOnCloseSystemDialogs="true"
+ android:noHistory="true"
+ android:excludeFromRecents="true"
+ android:exported="false" />
+
<receiver
android:name=".BugreportReceiver"
android:permission="android.permission.DUMP">
@@ -254,6 +269,16 @@
</intent-filter>
</receiver>
+ <receiver
+ android:name=".HeapDumpReceiver"
+ android:permission="android.permission.DUMP">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="com.android.internal.intent.action.HEAP_DUMP_FINISHED" />
+ <action android:name="com.android.shell.action.DELETE_HEAP_DUMP" />
+ </intent-filter>
+ </receiver>
+
<service
android:name=".BugreportProgressService"
android:exported="false"/>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 857cb2af41f6..29c61ee70f7d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1410,7 +1410,7 @@ public class BugreportProgressService extends Service {
return false;
}
- private static boolean isTv(Context context) {
+ static boolean isTv(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpActivity.java b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
new file mode 100644
index 000000000000..0ff0d3353041
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.shell;
+
+import static com.android.shell.HeapDumpProvider.makeUri;
+import static com.android.shell.HeapDumpReceiver.ACTION_DELETE_HEAP_DUMP;
+import static com.android.shell.HeapDumpReceiver.EXTRA_IS_USER_INITIATED;
+import static com.android.shell.HeapDumpReceiver.EXTRA_PROCESS_NAME;
+import static com.android.shell.HeapDumpReceiver.EXTRA_REPORT_PACKAGE;
+import static com.android.shell.HeapDumpReceiver.EXTRA_SIZE_BYTES;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.DebugUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+/**
+ * This activity is displayed when the system has collected a heap dump.
+ */
+public class HeapDumpActivity extends Activity {
+ private static final String TAG = "HeapDumpActivity";
+
+ static final String KEY_URI = "uri";
+
+ private AlertDialog mDialog;
+ private Uri mDumpUri;
+ private boolean mHandled = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String process = getIntent().getStringExtra(EXTRA_PROCESS_NAME);
+ long size = getIntent().getLongExtra(EXTRA_SIZE_BYTES, 0);
+ final boolean isUserInitiated = getIntent().getBooleanExtra(EXTRA_IS_USER_INITIATED, false);
+ final int uid = getIntent().getIntExtra(Intent.EXTRA_UID, 0);
+ final boolean isSystemProcess = uid == Process.SYSTEM_UID;
+ mDumpUri = makeUri(process);
+ final String procDisplayName = isSystemProcess
+ ? getString(com.android.internal.R.string.android_system_label)
+ : process;
+
+ final Intent sendIntent = new Intent();
+ ClipData clip = ClipData.newUri(getContentResolver(), "Heap Dump", mDumpUri);
+ sendIntent.setClipData(clip);
+ sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ sendIntent.setType(clip.getDescription().getMimeType(0));
+ sendIntent.putExtra(Intent.EXTRA_STREAM, mDumpUri);
+
+ String directLaunchPackage = getIntent().getStringExtra(EXTRA_REPORT_PACKAGE);
+ if (directLaunchPackage != null) {
+ sendIntent.setAction(ActivityManager.ACTION_REPORT_HEAP_LIMIT);
+ sendIntent.setPackage(directLaunchPackage);
+ try {
+ startActivity(sendIntent);
+ mHandled = true;
+ finish();
+ return;
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Unable to direct launch to " + directLaunchPackage, e);
+ }
+ }
+
+ final int messageId;
+ if (isUserInitiated) {
+ messageId = com.android.internal.R.string.dump_heap_ready_text;
+ } else if (isSystemProcess) {
+ messageId = com.android.internal.R.string.dump_heap_system_text;
+ } else {
+ messageId = com.android.internal.R.string.dump_heap_text;
+ }
+ mDialog = new AlertDialog.Builder(this, android.R.style.Theme_Material_Light_Dialog_Alert)
+ .setTitle(com.android.internal.R.string.dump_heap_title)
+ .setMessage(getString(messageId, procDisplayName,
+ DebugUtils.sizeValueToString(size, null)))
+ .setNegativeButton(android.R.string.cancel, (dialog, which) -> {
+ mHandled = true;
+ finish();
+ })
+ .setNeutralButton(R.string.delete, (dialog, which) -> {
+ mHandled = true;
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ finish();
+ })
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ mHandled = true;
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.setPackage(null);
+ startActivity(Intent.createChooser(sendIntent,
+ getText(com.android.internal.R.string.dump_heap_title)));
+ finish();
+ })
+ .show();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (!isChangingConfigurations()) {
+ if (!mHandled) {
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ }
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpProvider.java b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
new file mode 100644
index 000000000000..3eceb9118b12
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.shell;
+
+import android.annotation.NonNull;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/** ContentProvider to write and access heap dumps. */
+public class HeapDumpProvider extends ContentProvider {
+ private static final String FILENAME_SUFFIX = "_javaheap.bin";
+ private static final Object sLock = new Object();
+
+ private File mRoot;
+
+ @Override
+ public boolean onCreate() {
+ synchronized (sLock) {
+ mRoot = new File(getContext().createCredentialProtectedStorageContext().getFilesDir(),
+ "heapdumps");
+ return mRoot.mkdir();
+ }
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "application/octet-stream";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException("Insert not allowed.");
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ return (new File(mRoot, tag)).delete() ? 1 : 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException("Update not allowed.");
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ final int pMode;
+ if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+ pMode = ParcelFileDescriptor.MODE_CREATE
+ | ParcelFileDescriptor.MODE_TRUNCATE
+ | ParcelFileDescriptor.MODE_WRITE_ONLY;
+ } else {
+ pMode = ParcelFileDescriptor.MODE_READ_ONLY;
+ }
+
+ synchronized (sLock) {
+ return ParcelFileDescriptor.open(new File(mRoot, tag), pMode);
+ }
+ }
+
+ @NonNull
+ static Uri makeUri(@NonNull String procName) {
+ return Uri.parse("content://com.android.shell.heapdump/" + procName + FILENAME_SUFFIX);
+ }
+
+ private String sanitizePath(String path) {
+ return path.replaceAll("[^a-zA-Z0-9_.]", "");
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpReceiver.java b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
new file mode 100644
index 000000000000..858c521eaed5
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.shell;
+
+import static com.android.shell.BugreportProgressService.isTv;
+
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.FileUtils;
+import android.os.Process;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Receiver that handles finished heap dumps.
+ */
+public class HeapDumpReceiver extends BroadcastReceiver {
+ private static final String TAG = "HeapDumpReceiver";
+
+ /**
+ * Broadcast action to determine when to delete a specific dump heap. Must include a {@link
+ * HeapDumpActivity#KEY_URI} String extra.
+ */
+ static final String ACTION_DELETE_HEAP_DUMP = "com.android.shell.action.DELETE_HEAP_DUMP";
+
+ /** Broadcast sent when heap dump collection has been completed. */
+ private static final String ACTION_HEAP_DUMP_FINISHED =
+ "com.android.internal.intent.action.HEAP_DUMP_FINISHED";
+
+ /** The process we are reporting */
+ static final String EXTRA_PROCESS_NAME = "com.android.internal.extra.heap_dump.PROCESS_NAME";
+
+ /** The size limit the process reached. */
+ static final String EXTRA_SIZE_BYTES = "com.android.internal.extra.heap_dump.SIZE_BYTES";
+
+ /** Whether the user initiated the dump or not. */
+ static final String EXTRA_IS_USER_INITIATED =
+ "com.android.internal.extra.heap_dump.IS_USER_INITIATED";
+
+ /** Optional name of package to directly launch. */
+ static final String EXTRA_REPORT_PACKAGE =
+ "com.android.internal.extra.heap_dump.REPORT_PACKAGE";
+
+ private static final String NOTIFICATION_CHANNEL_ID = "heapdumps";
+ private static final int NOTIFICATION_ID = 2019;
+
+ /**
+ * Always keep heap dumps taken in the last week.
+ */
+ private static final long MIN_KEEP_AGE_MS = DateUtils.WEEK_IN_MILLIS;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive(): " + intent);
+ final String action = intent.getAction();
+ if (action == null) {
+ Log.e(TAG, "null action received");
+ return;
+ }
+ switch (action) {
+ case Intent.ACTION_BOOT_COMPLETED:
+ cleanupOldFiles(context);
+ break;
+ case ACTION_DELETE_HEAP_DUMP:
+ deleteHeapDump(context, intent.getStringExtra(HeapDumpActivity.KEY_URI));
+ break;
+ case ACTION_HEAP_DUMP_FINISHED:
+ showDumpNotification(context, intent);
+ break;
+ }
+ }
+
+ private void cleanupOldFiles(Context context) {
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+ Log.d(TAG, "Deleting from " + new File(context.getFilesDir(), "heapdumps"));
+ FileUtils.deleteOlderFiles(new File(context.getFilesDir(), "heapdumps"), 0,
+ MIN_KEEP_AGE_MS);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Couldn't delete old files", e);
+ }
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void deleteHeapDump(Context context, @Nullable final String uri) {
+ if (uri == null) {
+ Log.e(TAG, "null URI for delete heap dump intent");
+ return;
+ }
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ context.getContentResolver().delete(Uri.parse(uri), null, null);
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void showDumpNotification(Context context, Intent intent) {
+ final boolean isUserInitiated = intent.getBooleanExtra(
+ EXTRA_IS_USER_INITIATED, false);
+ final String procName = intent.getStringExtra(EXTRA_PROCESS_NAME);
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+
+ final String reportPackage = intent.getStringExtra(
+ EXTRA_REPORT_PACKAGE);
+ final long size = intent.getLongExtra(EXTRA_SIZE_BYTES, 0);
+
+ if (procName == null) {
+ Log.e(TAG, "No process name sent over");
+ return;
+ }
+
+ NotificationManager nm = NotificationManager.from(context);
+ nm.createNotificationChannel(
+ new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ "Heap dumps",
+ NotificationManager.IMPORTANCE_DEFAULT));
+
+ final int titleId = isUserInitiated
+ ? com.android.internal.R.string.dump_heap_ready_notification
+ : com.android.internal.R.string.dump_heap_notification;
+ final String procDisplayName = uid == Process.SYSTEM_UID
+ ? context.getString(com.android.internal.R.string.android_system_label)
+ : procName;
+ String text = context.getString(titleId, procDisplayName);
+
+ Intent shareIntent = new Intent();
+ shareIntent.setClassName(context, HeapDumpActivity.class.getName());
+ shareIntent.putExtra(EXTRA_PROCESS_NAME, procName);
+ shareIntent.putExtra(EXTRA_SIZE_BYTES, size);
+ shareIntent.putExtra(EXTRA_IS_USER_INITIATED, isUserInitiated);
+ shareIntent.putExtra(Intent.EXTRA_UID, uid);
+ if (reportPackage != null) {
+ shareIntent.putExtra(EXTRA_REPORT_PACKAGE, reportPackage);
+ }
+ final Notification.Builder builder = new Notification.Builder(context,
+ NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(
+ isTv(context) ? R.drawable.ic_bug_report_black_24dp
+ : com.android.internal.R.drawable.stat_sys_adb)
+ .setLocalOnly(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(text)
+ .setTicker(text)
+ .setAutoCancel(true)
+ .setContentText(context.getText(
+ com.android.internal.R.string.dump_heap_notification_detail))
+ .setContentIntent(PendingIntent.getActivity(context, 2, shareIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT));
+
+ Log.v(TAG, "Creating share heap dump notification");
+ NotificationManager.from(context).notify(NOTIFICATION_ID, builder.build());
+ }
+}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index ca69c187089d..998572fc5679 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -21,6 +21,7 @@ java_defaults {
"src/**/*.java",
":framework-tethering-shared-srcs",
":services-tethering-shared-srcs",
+ ":servicescore-tethering-src",
],
static_libs: [
"androidx.annotation_annotation",
@@ -67,13 +68,23 @@ android_app {
// 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 b9cac1994359..dc013da33869 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
index f60694aaedc9..f203e9995f3d 100644
--- a/services/net/java/android/net/util/PrefixUtils.java
+++ b/packages/Tethering/src/android/net/util/PrefixUtils.java
@@ -42,16 +42,19 @@ public class PrefixUtils {
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 @@ public class PrefixUtils {
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
index f952bcef5606..6b0f1de7ce85 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 @@ public class EntitlementManager {
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 class EntitlementManager {
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 @@ public class EntitlementManager {
/**
* 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 @@ public class EntitlementManager {
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
index 3a9e21f943d8..9769596ab1d0 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 @@ public class UpstreamNetworkMonitor {
}
}
+ /** Listen all networks. */
public void startObserveAllNetworks() {
stop();
@@ -155,6 +156,13 @@ public class UpstreamNetworkMonitor {
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 @@ public class UpstreamNetworkMonitor {
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 @@ public class UpstreamNetworkMonitor {
}
}
+ /** 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 @@ public class UpstreamNetworkMonitor {
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
}
+ /** Release mobile network request. */
public void releaseMobileNetworkRequest() {
if (mMobileNetworkCallback == null) return;
@@ -221,6 +233,9 @@ public class UpstreamNetworkMonitor {
// 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 @@ public class UpstreamNetworkMonitor {
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 @@ public class UpstreamNetworkMonitor {
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 @@ public class UpstreamNetworkMonitor {
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 @@ public class UpstreamNetworkMonitor {
}
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 da621076bb63..7c06e5f0d7ce 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 @@ android_test {
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
index 5217e26a40ef..5217e26a40ef 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java
+++ b/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
index 0d276cbd1b85..c028d6d9cadc 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 @@ public class UpstreamNetworkMonitorTest {
// 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 @@ public class UpstreamNetworkMonitorTest {
@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 class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
@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 @@ public class UpstreamNetworkMonitorTest {
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -217,7 +217,7 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -266,17 +266,17 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
@Test
public void testGetCurrentPreferredUpstream() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
mUNM.updateMobileRequiresDun(false);
@@ -418,7 +418,7 @@ public class UpstreamNetworkMonitorTest {
@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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
// 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 @@ public class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 class UpstreamNetworkMonitorTest {
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 @@ public class UpstreamNetworkMonitorTest {
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 05b937a34626..d4fb9acdad5e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -82,8 +82,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
-import android.provider.SettingsStringUtil;
-import android.provider.SettingsStringUtil.ComponentNameSet;
import android.provider.SettingsStringUtil.SettingStringHelper;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -2436,12 +2434,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Enables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.add(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.add(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.add(componentName)) {
@@ -2453,12 +2451,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Disables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingsStringUtil.SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.remove(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.remove(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
UserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.remove(componentName)) {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 16432212d8e2..fcf012cd3a6b 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -20,6 +20,7 @@ java_library_static {
":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",
@@ -81,3 +82,11 @@ prebuilt_etc {
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/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 7bc2e6d647be..6cbbcddc2b3f 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 @@ public final class ActiveServices {
@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 @@ public final class ActiveServices {
}
}
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 bc5973d1b270..87624359ef85 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.annotation.Nullable;
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 @@ import java.util.Map;
*
* <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 final class CompatChange {
*/
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 @@ public final class CompatChange {
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 @@ public final class CompatChange {
@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 0fabd9aef373..d6ec22b078ea 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 android.util.Slog;
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.FileInputStream;
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 @@ public final class CompatConfig {
}
}
+ /**
+ * 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 9ac9955493cc..75e2d220898d 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 android.util.StatsLog;
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 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
@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/net/Android.bp b/services/net/Android.bp
index 08cdbfc55cfe..e24dec562a46 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 ecddeb3dda61..eecdeed2cd25 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -74,7 +74,7 @@ android_test {
"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 4a9cef1f1cbd..92198fa8cb0c 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -55,6 +55,6 @@ android_test {
"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 2ce84fbc0dc7..4f373af984fa 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -857,7 +857,7 @@ public abstract class Connection extends Conferenceable {
}
/** @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 @@ public abstract class Connection extends Conferenceable {
*
* @hide
*/
- public final Connection addConnectionListener(Listener l) {
+ final Connection addConnectionListener(Listener l) {
mListeners.add(l);
return this;
}
@@ -2018,7 +2018,7 @@ public abstract class Connection extends Conferenceable {
*
* @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 1a8be6d899c3..f3596c092064 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1838,6 +1838,13 @@ public class CarrierConfigManager {
"support_direct_fdn_dialing_bool";
/**
+ * Int indicating the max number length for FDN
+ * @hide
+ */
+ public static final String KEY_FDN_NUMBER_LENGTH_LIMIT_INT =
+ "fdn_number_length_limit_int";
+
+ /**
* Report IMEI as device id even if it's a CDMA/LTE phone.
*
* @hide
@@ -3428,6 +3435,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
+ sDefaults.putInt(KEY_FDN_NUMBER_LENGTH_LIMIT_INT, 20);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL, true);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index bec0a975108a..c9440a66ab96 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9462,10 +9462,12 @@ public class TelephonyManager {
}
/**
- * 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);
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 2fad8479178e..ed292be9cd05 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -25,14 +25,13 @@ import android.annotation.Nullable;
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.telephony.ims.stub.ImsRegistrationImplBase;
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.lang.annotation.RetentionPolicy;
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 @@ import java.util.concurrent.Executor;
@SystemApi
public class ImsMmTelManager {
- private static final String TAG = "ImsMmTelManager";
-
/**
* @hide
*/
@@ -311,7 +310,7 @@ public class ImsMmTelManager {
}
}
- private int mSubId;
+ private final int mSubId;
/**
* Create an instance of {@link ImsMmTelManager} for the subscription id specified.
@@ -366,10 +365,6 @@ public class ImsMmTelManager {
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 @@ public class ImsMmTelManager {
// 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 @@ public class ImsMmTelManager {
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 @@ public class ImsMmTelManager {
// 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 @@ public class ImsMmTelManager {
}
/**
+ * 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 @@ public class ImsMmTelManager {
* @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 @@ public class ImsMmTelManager {
}
}
- 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 ceb470491dc5..8b27b6fc4bfd 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -362,6 +362,25 @@ public class MmTelFeature extends ImsFeature {
@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 @@ public class MmTelFeature extends ImsFeature {
/**
* 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/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d899a596c222..ab3861e2d517 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -864,6 +864,11 @@ interface ITelephony {
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 @@ interface ITelephony {
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 @@ interface ITelephony {
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 b9b2238572ac..10f27e243c8c 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -37,7 +37,7 @@ java_defaults {
"libvndksupport",
"libziparchive",
"libz",
- "netd_aidl_interface-V2-cpp",
+ "netd_aidl_interface-cpp",
],
}