diff options
21 files changed, 700 insertions, 523 deletions
diff --git a/Android.bp b/Android.bp index b4ea61aeec28..3a5fcfaedd9a 100644 --- a/Android.bp +++ b/Android.bp @@ -1070,107 +1070,95 @@ framework_docs_args = "-android -manifest $(location core/res/AndroidManifest.xm "-federate SupportLib https://developer.android.com " + "-federationapi SupportLib $(location current/support-api.txt) " -doc_defaults { - name: "api-stubs-default", +framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " + + "-overview $(location core/java/overview.html) " + + // Federate Support Library references against local API file. + "-federate SupportLib https://developer.android.com " + + "-federationapi SupportLib $(location current/support-api.txt) " + +framework_docs_only_libs = [ + "conscrypt", + "bouncycastle", + "voip-common", + "android.test.mock", + "android-support-annotations", + "android-support-compat", + "android-support-core-ui", + "android-support-core-utils", + "android-support-customtabs", + "android-support-design", + "android-support-dynamic-animation", + "android-support-exifinterface", + "android-support-fragment", + "android-support-media-compat", + "android-support-percent", + "android-support-recommendation", + "android-support-transition", + "android-support-tv-provider", + "android-support-v7-cardview", + "android-support-v7-gridlayout", + "android-support-v7-mediarouter", + "android-support-v7-palette", + "android-support-v7-preference", + "android-support-v13", + "android-support-v14-preference", + "android-support-v17-leanback", + "android-support-v17-preference-leanback", + "android-support-wear", + "android-support-vectordrawable", + "android-support-animatedvectordrawable", + "android-support-v7-appcompat", + "android-support-v7-recyclerview", + "android-support-emoji", + "android-support-emoji-appcompat", + "android-support-emoji-bundled", + "android-support-v8-renderscript", + "android-support-multidex", + "android-support-multidex-instrumentation", +] + +metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " + + "--hide-package com.android.okhttp " + + "--hide-package com.android.org.conscrypt --hide-package com.android.server " + + "--hide RequiresPermission " + + "--hide MissingPermission --hide BroadcastBehavior " + + "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " + + "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo" + +stubs_defaults { + name: "framework-doc-stubs-default", srcs: [ + "test-base/src/**/*.java", ":opt-telephony-srcs", ":opt-net-voip-srcs", ":openjdk_javadoc_files", ":non_openjdk_javadoc_files", ":android_icu4j_src_files_for_docs", + "test-mock/src/**/*.java", + "test-runner/src/**/*.java", ], srcs_lib: "framework", srcs_lib_whitelist_dirs: frameworks_base_subdirs, srcs_lib_whitelist_pkgs: packages_to_document, - libs: [ - "core-oj", - "core-libart", - "conscrypt", - "bouncycastle", - "okhttp", - "ext", - "framework", - "voip-common", - "android.test.mock.impl", - ], + libs: framework_docs_only_libs, local_sourcepaths: frameworks_base_subdirs, - html_dirs: [ - "docs/html", - ], - knowntags: [ - "docs/knowntags.txt", - ":known-oj-tags", + create_doc_stubs: true, + annotations_enabled: true, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", ], - custom_template: "droiddoc-templates-sdk", - hdf: [ - "dac true", - "sdk.codename O", - "sdk.preview.version 1", - "sdk.version 7.0", - "sdk.rel.id 1", - "sdk.preview 0", + previous_api: ":last-released-public-api", + merge_annotations_dirs: [ + "metalava-manual", + "ojluni-annotated-stubs", ], - resourcesdir: "docs/html/reference/images", - resourcesoutdir: "reference/android/images", - installable: false, } doc_defaults { name: "framework-docs-default", - srcs: [ - "test-base/src/**/*.java", - ":opt-telephony-srcs", - ":opt-net-voip-srcs", - ":openjdk_javadoc_files", - ":non_openjdk_javadoc_files", - ":android_icu4j_src_files_for_docs", - "test-mock/src/**/*.java", - "test-runner/src/**/*.java", - ], - srcs_lib: "framework", - srcs_lib_whitelist_dirs: frameworks_base_subdirs, - srcs_lib_whitelist_pkgs: packages_to_document, - libs: [ - "conscrypt", - "bouncycastle", - "voip-common", - "android.test.mock", - "android-support-annotations", - "android-support-compat", - "android-support-core-ui", - "android-support-core-utils", - "android-support-customtabs", - "android-support-design", - "android-support-dynamic-animation", - "android-support-exifinterface", - "android-support-fragment", - "android-support-media-compat", - "android-support-percent", - "android-support-recommendation", - "android-support-transition", - "android-support-tv-provider", - "android-support-v7-cardview", - "android-support-v7-gridlayout", - "android-support-v7-mediarouter", - "android-support-v7-palette", - "android-support-v7-preference", - "android-support-v13", - "android-support-v14-preference", - "android-support-v17-leanback", - "android-support-v17-preference-leanback", - "android-support-wear", - "android-support-vectordrawable", - "android-support-animatedvectordrawable", - "android-support-v7-appcompat", - "android-support-v7-recyclerview", - "android-support-emoji", - "android-support-emoji-appcompat", - "android-support-emoji-bundled", - "android-support-v8-renderscript", - "android-support-multidex", - "android-support-multidex-instrumentation", - ], - local_sourcepaths: frameworks_base_subdirs, + libs: framework_docs_only_libs, html_dirs: [ "docs/html", ], @@ -1191,22 +1179,12 @@ doc_defaults { ], arg_files: [ "core/res/AndroidManifest.xml", - ":api-version-xml", "core/java/overview.html", ":current-support-api", - "api/current.txt", ], create_stubs: false, } -metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " + - "--hide-package com.android.okhttp " + - "--hide-package com.android.org.conscrypt --hide-package com.android.server " + - "--hide RequiresPermission " + - "--hide MissingPermission --hide BroadcastBehavior " + - "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " + - "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo" - stubs_defaults { name: "metalava-api-stubs-default", srcs: [ @@ -1240,21 +1218,45 @@ stubs_defaults { ], } +droidstubs { + name: "framework-doc-stubs", + defaults: ["framework-doc-stubs-default"], + arg_files: [ + "core/res/AndroidManifest.xml", + ], + args: metalava_framework_docs_args, +} + +droidstubs { + name: "framework-doc-system-stubs", + defaults: ["framework-doc-stubs-default"], + arg_files: [ + "core/res/AndroidManifest.xml", + ], + args: metalava_framework_docs_args + " --show-annotation android.annotation.SystemApi ", +} + droiddoc { name: "doc-comment-check-docs", defaults: ["framework-docs-default"], - args: framework_docs_args + " -referenceonly -parsecomments", + srcs: [ + ":framework-doc-stubs", + ], + args: framework_docs_only_args + " -referenceonly -parsecomments", installable: false, } droiddoc { name: "offline-sdk-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc offline", ], proofread_file: "offline-sdk-docs-proofrerad.txt", - args: framework_docs_args + " -offlinemode -title \"Android SDK\"", + args: framework_docs_only_args + " -offlinemode -title \"Android SDK\"", write_sdk_values: true, static_doc_index_redirect: "docs/docs-preview-index.html", } @@ -1262,11 +1264,14 @@ droiddoc { droiddoc { name: "offline-sdk-referenceonly-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc offline", ], proofread_file: "offline-sdk-referenceonly-docs-proofrerad.txt", - args: framework_docs_args + " -offlinemode -title \"Android SDK\" -referenceonly", + args: framework_docs_only_args + " -offlinemode -title \"Android SDK\" -referenceonly", write_sdk_values: true, static_doc_index_redirect: "docs/docs-documentation-redirect.html", static_doc_properties: "docs/source.properties", @@ -1275,13 +1280,15 @@ droiddoc { droiddoc { name: "offline-system-sdk-referenceonly-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-system-stubs", + ], hdf: [ "android.whichdoc offline", ], proofread_file: "offline-system-sdk-referenceonly-docs-proofrerad.txt", - args: framework_docs_args + " -hide 101 -hide 104 -hide 108" + - " -showAnnotation android.annotation.SystemApi " + - " -offlinemode -title \"Android System SDK\" -referenceonly", + args: framework_docs_only_args + " -hide 101 -hide 104 -hide 108" + + " -offlinemode -title \"Android System SDK\" -referenceonly", write_sdk_values: true, static_doc_index_redirect: "docs/docs-documentation-redirect.html", static_doc_properties: "docs/source.properties", @@ -1290,12 +1297,15 @@ droiddoc { droiddoc { name: "online-sdk-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc online", "android.hasSamples true", ], proofread_file: "online-sdk-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -toroot / -samplegroup Admin " + " -samplegroup Background " + " -samplegroup Connectivity " + @@ -1316,14 +1326,16 @@ droiddoc { droiddoc { name: "online-system-api-sdk-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-system-stubs", + ], hdf: [ "android.whichdoc online", "android.hasSamples true", ], proofread_file: "online-system-api-sdk-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -referenceonly " + - " -showAnnotation android.annotation.SystemApi " + " -title \"Android SDK - Including system APIs.\" " + " -hide 101 " + " -hide 104 " + @@ -1349,12 +1361,15 @@ droiddoc { droiddoc { name: "ds-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc online", "android.hasSamples true", ], proofread_file: "ds-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -toroot / -samplegroup Admin " + " -samplegroup Background " + " -samplegroup Connectivity " + @@ -1375,11 +1390,14 @@ droiddoc { droiddoc { name: "ds-static-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc online", ], proofread_file: "ds-static-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -staticonly " + " -toroot / " + " -devsite " + @@ -1389,11 +1407,14 @@ droiddoc { droiddoc { name: "ds-ref-navtree-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc online", ], proofread_file: "ds-ref-navtree-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -toroot / " + " -atLinksNavtree " + " -navtreeonly ", @@ -1402,12 +1423,15 @@ droiddoc { droiddoc { name: "online-sdk-dev-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], hdf: [ "android.whichdoc online", "android.hasSamples true", ], proofread_file: "online-sdk-dev-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -toroot / -samplegroup Admin " + " -samplegroup Background " + " -samplegroup Connectivity " + @@ -1428,13 +1452,16 @@ droiddoc { droiddoc { name: "hidden-docs", defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], proofread_file: "hidden-docs-proofrerad.txt", - args: framework_docs_args + + args: framework_docs_only_args + " -referenceonly " + " -title \"Android SDK - Including hidden APIs.\"", } -droiddoc { +droidstubs { name: "hwbinder-stubs-docs", srcs: [ "core/java/android/os/HidlSupport.java", @@ -1452,10 +1479,15 @@ droiddoc { "core/java/android/os/RemoteException.java", "core/java/android/util/AndroidException.java", ], - custom_template: "droiddoc-templates-sdk", installable: false, no_framework_libs: true, - args: "-showAnnotation android.annotation.SystemApi -nodocs -stubsourceonly", + annotations_enabled: true, + previous_api: ":last-released-public-api", + merge_annotations_dirs: [ + "metalava-manual", + "ojluni-annotated-stubs", + ], + args: " --show-annotation android.annotation.SystemApi", } java_library_static { @@ -1482,23 +1514,17 @@ droidstubs { } -droiddoc { +droidstubs { name: "hiddenapi-mappings", - defaults: ["api-stubs-default"], + defaults: ["metalava-api-stubs-default"], arg_files: [ "core/res/AndroidManifest.xml", - ":api-version-xml", - "core/java/overview.html", - ":current-support-api", - "api/current.txt", ], dex_mapping_filename: "dex-mapping.txt", - args: framework_docs_args + - " -referenceonly" + - " -nodocs" + - " -showUnannotated" + - " -showAnnotation android.annotation.SystemApi" + - " -showAnnotation android.annotation.TestApi", + args: metalava_framework_docs_args + + " --show-unannotated " + + " --show-annotation android.annotation.SystemApi " + + " --show-annotation android.annotation.TestApi " } filegroup { diff --git a/config/preloaded-classes b/config/preloaded-classes index 63c583f9264c..50e97c53fe83 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -1436,12 +1436,6 @@ android.hardware.usb.UsbDevice$1 android.hardware.usb.UsbDeviceConnection android.hardware.usb.UsbManager android.hardware.usb.UsbRequest -android.hidl.base.V1_0.DebugInfo -android.hidl.base.V1_0.IBase -android.hidl.manager.V1_0.IServiceManager -android.hidl.manager.V1_0.IServiceManager$Proxy -android.hidl.manager.V1_0.IServiceNotification -android.hidl.manager.V1_0.IServiceNotification$Stub android.icu.impl.BMPSet android.icu.impl.CacheBase android.icu.impl.CacheValue diff --git a/core/java/android/content/pm/AndroidHidlUpdater.java b/core/java/android/content/pm/AndroidHidlUpdater.java new file mode 100644 index 000000000000..69cc94ffef55 --- /dev/null +++ b/core/java/android/content/pm/AndroidHidlUpdater.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; + +import android.content.pm.PackageParser.Package; +import android.os.Build; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * Updates a package to ensure that if it targets <= P that the android.hidl.base-V1.0-java + * and android.hidl.manager-V1.0-java libraries are included by default. + * + * @hide + */ +@VisibleForTesting +public class AndroidHidlUpdater extends PackageSharedLibraryUpdater { + + @Override + public void updatePackage(Package pkg) { + // This was the default <= P and is maintained for backwards compatibility. + if (pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.P) { + prefixRequiredLibrary(pkg, ANDROID_HIDL_BASE); + prefixRequiredLibrary(pkg, ANDROID_HIDL_MANAGER); + } + } +} diff --git a/core/java/android/content/pm/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java index a16f81b11ae6..03eefedd2b30 100644 --- a/core/java/android/content/pm/PackageBackwardCompatibility.java +++ b/core/java/android/content/pm/PackageBackwardCompatibility.java @@ -53,6 +53,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { "android.content.pm.OrgApacheHttpLegacyUpdater", RemoveUnnecessaryOrgApacheHttpLegacyLibrary::new); + packageUpdaters.add(new AndroidHidlUpdater()); + // Add this before adding AndroidTestBaseUpdater so that android.test.base comes before // android.test.mock. packageUpdaters.add(new AndroidTestRunnerSplitUpdater()); diff --git a/core/java/android/content/pm/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java index 83e86636424a..387d29e81dfc 100644 --- a/core/java/android/content/pm/SharedLibraryNames.java +++ b/core/java/android/content/pm/SharedLibraryNames.java @@ -22,6 +22,10 @@ package android.content.pm; */ public class SharedLibraryNames { + static final String ANDROID_HIDL_BASE = "android.hidl.base-V1.0-java"; + + static final String ANDROID_HIDL_MANAGER = "android.hidl.manager-V1.0-java"; + static final String ANDROID_TEST_BASE = "android.test.base"; static final String ANDROID_TEST_MOCK = "android.test.mock"; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 494a95741090..08c9678cac79 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -227,7 +227,6 @@ cc_library_shared { static_libs: [ "libgif", "libseccomp_policy", - "libselinux", "libgrallocusage", "libscrypt_static", ], diff --git a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java new file mode 100644 index 000000000000..7218b3a286a2 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; + +import android.os.Build; +import android.support.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link AndroidHidlUpdater} + */ +@SmallTest +@RunWith(JUnit4.class) +public class AndroidHidlUpdaterTest extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_O() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + // Should add both HIDL libraries + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(OTHER_LIBRARY); + + // The hidl jars should be added at the start of the list because it + // is not on the bootclasspath and the package targets pre-P. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE, OTHER_LIBRARY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE); + + // No change is required because although the HIDL libraries has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ANDROID_HIDL_BASE); + + // No change is required because the package explicitly requests the HIDL libraries + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_HIDL_BASE); + + // No change is required because the package explicitly requests the HIDL libraries + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, AndroidHidlUpdater::new); + } +} diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 6f52fbd1b4f5..c4017d15268f 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -188,6 +188,12 @@ <library name="android.test.runner" file="/system/framework/android.test.runner.impl.jar" /> + <!-- In BOOT_JARS historically, and now added to legacy applications. --> + <library name="android.hidl.base-V1.0-java" + file="/system/framework/android.hidl.base-V1.0-java.jar" /> + <library name="android.hidl.manager-V1.0-java" + file="/system/framework/android.hidl.manager-V1.0-java.jar" /> + <!-- These are the standard packages that are white-listed to always have internet access while in power save mode, even if they aren't in the foreground. --> <allow-in-power-save package="com.android.providers.downloads" /> diff --git a/packages/SystemUI/res/layout/operator_name.xml b/packages/SystemUI/res/layout/operator_name.xml index c4f75e927604..015e30a5d050 100644 --- a/packages/SystemUI/res/layout/operator_name.xml +++ b/packages/SystemUI/res/layout/operator_name.xml @@ -27,5 +27,6 @@ android:maxLength="20" android:gravity="center_vertical|start" android:textAppearance="?android:attr/textAppearanceSmall" - android:singleLine="true" /> + android:singleLine="true" + android:paddingEnd="5dp" /> </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java index 943558943821..f4f2ebce4f53 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java @@ -38,6 +38,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.widget.LockPatternUtils; import com.android.internal.util.EmergencyAffordanceManager; +import com.android.systemui.util.EmergencyDialerConstants; /** * This class implements a smart emergency button that updates itself based @@ -47,11 +48,13 @@ import com.android.internal.util.EmergencyAffordanceManager; */ public class EmergencyButton extends Button { private static final Intent INTENT_EMERGENCY_DIAL = new Intent() - .setAction("com.android.phone.EmergencyDialer.DIAL") + .setAction(EmergencyDialerConstants.ACTION_DIAL) .setPackage("com.android.phone") .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS - | Intent.FLAG_ACTIVITY_CLEAR_TOP); + | Intent.FLAG_ACTIVITY_CLEAR_TOP) + .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE, + EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON); private static final String LOG_TAG = "EmergencyButton"; private final EmergencyAffordanceManager mEmergencyAffordanceManager; diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 8320d32b7978..00758e8e1297 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -89,6 +89,7 @@ import com.android.systemui.Interpolators; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.statusbar.phone.ScrimController; +import com.android.systemui.util.EmergencyDialerConstants; import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator; import java.util.ArrayList; @@ -448,9 +449,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } private class EmergencyDialerAction extends SinglePressAction { - private static final String ACTION_EMERGENCY_DIALER_DIAL = - "com.android.phone.EmergencyDialer.DIAL"; - private EmergencyDialerAction() { super(R.drawable.ic_faster_emergency, R.string.global_action_emergency); @@ -458,8 +456,10 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, @Override public void onPress() { - Intent intent = new Intent(ACTION_EMERGENCY_DIALER_DIAL); + Intent intent = new Intent(EmergencyDialerConstants.ACTION_DIAL); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE, + EmergencyDialerConstants.ENTRY_TYPE_POWER_MENU); mContext.startActivityAsUser(intent, UserHandle.CURRENT); } diff --git a/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java new file mode 100644 index 000000000000..d101ccbe30ea --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/EmergencyDialerConstants.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util; + +/** + * Constants defined and used in emergency dialer. + * Please keep these constants being consistent with those in com.android.phone.EmergencyDialer. + */ +public class EmergencyDialerConstants { + // Intent action for emergency dialer activity. + public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL"; + + /** + * Extra included in {@link #ACTION_DIAL} to indicate the entry type that user starts + * the emergency dialer. + */ + public static final String EXTRA_ENTRY_TYPE = + "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE"; + + // Indicating the entrance to emergency dialer + public static final int ENTRY_TYPE_UNKNOWN = 0; + public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1; + public static final int ENTRY_TYPE_POWER_MENU = 2; +} diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index d16c2776dc3b..a8f7259050c1 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -68,6 +68,7 @@ import android.content.res.Resources; import android.hardware.usb.UsbManager; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; +import android.net.ip.IpServer; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; @@ -112,10 +113,8 @@ import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.server.LocalServices; -import com.android.server.connectivity.tethering.IControlsTethering; import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; import com.android.server.connectivity.tethering.OffloadController; -import com.android.server.connectivity.tethering.TetherInterfaceStateMachine; import com.android.server.connectivity.tethering.TetheringConfiguration; import com.android.server.connectivity.tethering.TetheringDependencies; import com.android.server.connectivity.tethering.TetheringInterfaceUtils; @@ -149,7 +148,7 @@ public class Tethering extends BaseNetworkObserver { protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; private static final Class[] messageClasses = { - Tethering.class, TetherMasterSM.class, TetherInterfaceStateMachine.class + Tethering.class, TetherMasterSM.class, IpServer.class }; private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(messageClasses); @@ -159,21 +158,21 @@ public class Tethering extends BaseNetworkObserver { .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable)); private static class TetherState { - public final TetherInterfaceStateMachine stateMachine; + public final IpServer ipServer; public int lastState; public int lastError; - public TetherState(TetherInterfaceStateMachine sm) { - stateMachine = sm; + public TetherState(IpServer ipServer) { + this.ipServer = ipServer; // Assume all state machines start out available and with no errors. - lastState = IControlsTethering.STATE_AVAILABLE; + lastState = IpServer.STATE_AVAILABLE; lastError = TETHER_ERROR_NO_ERROR; } public boolean isCurrentlyServing() { switch (lastState) { - case IControlsTethering.STATE_TETHERED: - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_TETHERED: + case IpServer.STATE_LOCAL_ONLY: return true; default: return false; @@ -198,7 +197,7 @@ public class Tethering extends BaseNetworkObserver { private final UpstreamNetworkMonitor mUpstreamNetworkMonitor; // TODO: Figure out how to merge this and other downstream-tracking objects // into a single coherent structure. - private final HashSet<TetherInterfaceStateMachine> mForwardedDownstreams; + private final HashSet<IpServer> mForwardedDownstreams; private final VersionedBroadcastListener mCarrierConfigChange; private final TetheringDependencies mDeps; @@ -604,7 +603,7 @@ public class Tethering extends BaseNetworkObserver { } public int tether(String iface) { - return tether(iface, IControlsTethering.STATE_TETHERED); + return tether(iface, IpServer.STATE_TETHERED); } private int tether(String iface, int requestedState) { @@ -617,7 +616,7 @@ public class Tethering extends BaseNetworkObserver { } // Ignore the error status of the interface. If the interface is available, // the errors are referring to past tethering attempts anyway. - if (tetherState.lastState != IControlsTethering.STATE_AVAILABLE) { + if (tetherState.lastState != IpServer.STATE_AVAILABLE) { Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring"); return TETHER_ERROR_UNAVAIL_IFACE; } @@ -626,8 +625,7 @@ public class Tethering extends BaseNetworkObserver { // return an error. // // TODO: reexamine the threading and messaging model. - tetherState.stateMachine.sendMessage( - TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, requestedState); + tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_REQUESTED, requestedState); return TETHER_ERROR_NO_ERROR; } } @@ -644,8 +642,7 @@ public class Tethering extends BaseNetworkObserver { Log.e(TAG, "Tried to untether an inactive iface :" + iface + ", ignoring"); return TETHER_ERROR_UNAVAIL_IFACE; } - tetherState.stateMachine.sendMessage( - TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); + tetherState.ipServer.sendMessage(IpServer.CMD_TETHER_UNREQUESTED); return TETHER_ERROR_NO_ERROR; } } @@ -689,11 +686,11 @@ public class Tethering extends BaseNetworkObserver { String iface = mTetherStates.keyAt(i); if (tetherState.lastError != TETHER_ERROR_NO_ERROR) { erroredList.add(iface); - } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) { + } else if (tetherState.lastState == IpServer.STATE_AVAILABLE) { availableList.add(iface); - } else if (tetherState.lastState == IControlsTethering.STATE_LOCAL_ONLY) { + } else if (tetherState.lastState == IpServer.STATE_LOCAL_ONLY) { localOnlyList.add(iface); - } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) { + } else if (tetherState.lastState == IpServer.STATE_TETHERED) { if (cfg.isUsb(iface)) { usbTethered = true; } else if (cfg.isWifi(iface)) { @@ -882,10 +879,10 @@ public class Tethering extends BaseNetworkObserver { synchronized (Tethering.this.mPublicSync) { if (!usbConnected && mRndisEnabled) { // Turn off tethering if it was enabled and there is a disconnect. - tetherMatchingInterfaces(IControlsTethering.STATE_AVAILABLE, TETHERING_USB); + tetherMatchingInterfaces(IpServer.STATE_AVAILABLE, TETHERING_USB); } else if (usbConfigured && rndisEnabled) { // Tether if rndis is enabled and usb is configured. - tetherMatchingInterfaces(IControlsTethering.STATE_TETHERED, TETHERING_USB); + tetherMatchingInterfaces(IpServer.STATE_TETHERED, TETHERING_USB); } mRndisEnabled = usbConfigured && rndisEnabled; } @@ -959,15 +956,15 @@ public class Tethering extends BaseNetworkObserver { if (!TextUtils.isEmpty(ifname)) { final TetherState ts = mTetherStates.get(ifname); if (ts != null) { - ts.stateMachine.unwanted(); + ts.ipServer.unwanted(); return; } } for (int i = 0; i < mTetherStates.size(); i++) { - TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine; - if (tism.interfaceType() == TETHERING_WIFI) { - tism.unwanted(); + final IpServer ipServer = mTetherStates.valueAt(i).ipServer; + if (ipServer.interfaceType() == TETHERING_WIFI) { + ipServer.unwanted(); return; } } @@ -978,15 +975,15 @@ public class Tethering extends BaseNetworkObserver { } private void enableWifiIpServingLocked(String ifname, int wifiIpMode) { - // Map wifiIpMode values to IControlsTethering serving states, inferring + // Map wifiIpMode values to IpServer.Callback serving states, inferring // from mWifiTetherRequested as a final "best guess". final int ipServingMode; switch (wifiIpMode) { case IFACE_IP_MODE_TETHERED: - ipServingMode = IControlsTethering.STATE_TETHERED; + ipServingMode = IpServer.STATE_TETHERED; break; case IFACE_IP_MODE_LOCAL_ONLY: - ipServingMode = IControlsTethering.STATE_LOCAL_ONLY; + ipServingMode = IpServer.STATE_LOCAL_ONLY; break; default: mLog.e("Cannot enable IP serving in unknown WiFi mode: " + wifiIpMode); @@ -1041,12 +1038,12 @@ public class Tethering extends BaseNetworkObserver { private void changeInterfaceState(String ifname, int requestedState) { final int result; switch (requestedState) { - case IControlsTethering.STATE_UNAVAILABLE: - case IControlsTethering.STATE_AVAILABLE: + case IpServer.STATE_UNAVAILABLE: + case IpServer.STATE_AVAILABLE: result = untether(ifname); break; - case IControlsTethering.STATE_TETHERED: - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_TETHERED: + case IpServer.STATE_LOCAL_ONLY: result = tether(ifname, requestedState); break; default: @@ -1104,7 +1101,7 @@ public class Tethering extends BaseNetworkObserver { synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); - if (tetherState.lastState == IControlsTethering.STATE_TETHERED) { + if (tetherState.lastState == IpServer.STATE_TETHERED) { list.add(mTetherStates.keyAt(i)); } } @@ -1117,7 +1114,7 @@ public class Tethering extends BaseNetworkObserver { synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); - if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) { + if (tetherState.lastState == IpServer.STATE_AVAILABLE) { list.add(mTetherStates.keyAt(i)); } } @@ -1177,7 +1174,7 @@ public class Tethering extends BaseNetworkObserver { synchronized (mPublicSync) { for (int i = 0; i < mTetherStates.size(); i++) { TetherState tetherState = mTetherStates.valueAt(i); - if (tetherState.lastState != IControlsTethering.STATE_TETHERED) { + if (tetherState.lastState != IpServer.STATE_TETHERED) { continue; // Skip interfaces that aren't tethered. } String iface = mTetherStates.keyAt(i); @@ -1231,7 +1228,7 @@ public class Tethering extends BaseNetworkObserver { // Because we excise interfaces immediately from mTetherStates, we must maintain mNotifyList // so that the garbage collector does not clean up the state machine before it has a chance // to tear itself down. - private final ArrayList<TetherInterfaceStateMachine> mNotifyList; + private final ArrayList<IpServer> mNotifyList; private final IPv6TetheringCoordinator mIPv6TetheringCoordinator; private final OffloadWrapper mOffload; @@ -1268,17 +1265,19 @@ public class Tethering extends BaseNetworkObserver { public boolean processMessage(Message message) { logMessage(this, message.what); switch (message.what) { - case EVENT_IFACE_SERVING_STATE_ACTIVE: - TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; + case EVENT_IFACE_SERVING_STATE_ACTIVE: { + final IpServer who = (IpServer) message.obj; if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); handleInterfaceServingStateActive(message.arg1, who); transitionTo(mTetherModeAliveState); break; - case EVENT_IFACE_SERVING_STATE_INACTIVE: - who = (TetherInterfaceStateMachine) message.obj; + } + case EVENT_IFACE_SERVING_STATE_INACTIVE: { + final IpServer who = (IpServer) message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); handleInterfaceServingStateInactive(who); break; + } case EVENT_IFACE_UPDATE_LINKPROPERTIES: // Silently ignore these for now. break; @@ -1410,8 +1409,8 @@ public class Tethering extends BaseNetworkObserver { protected void notifyDownstreamsOfNewUpstreamIface(InterfaceSet ifaces) { mCurrentUpstreamIfaceSet = ifaces; - for (TetherInterfaceStateMachine sm : mNotifyList) { - sm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, ifaces); + for (IpServer ipServer : mNotifyList) { + ipServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, ifaces); } } @@ -1420,13 +1419,13 @@ public class Tethering extends BaseNetworkObserver { mOffload.updateUpstreamNetworkState(ns); } - private void handleInterfaceServingStateActive(int mode, TetherInterfaceStateMachine who) { + private void handleInterfaceServingStateActive(int mode, IpServer who) { if (mNotifyList.indexOf(who) < 0) { mNotifyList.add(who); mIPv6TetheringCoordinator.addActiveDownstream(who, mode); } - if (mode == IControlsTethering.STATE_TETHERED) { + if (mode == IpServer.STATE_TETHERED) { // No need to notify OffloadController just yet as there are no // "offload-able" prefixes to pass along. This will handled // when the TISM informs Tethering of its LinkProperties. @@ -1441,10 +1440,10 @@ public class Tethering extends BaseNetworkObserver { final WifiManager mgr = getWifiManager(); final String iface = who.interfaceName(); switch (mode) { - case IControlsTethering.STATE_TETHERED: + case IpServer.STATE_TETHERED: mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED); break; - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_LOCAL_ONLY: mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY); break; default: @@ -1454,7 +1453,7 @@ public class Tethering extends BaseNetworkObserver { } } - private void handleInterfaceServingStateInactive(TetherInterfaceStateMachine who) { + private void handleInterfaceServingStateInactive(IpServer who) { mNotifyList.remove(who); mIPv6TetheringCoordinator.removeActiveDownstream(who); mOffload.excludeDownstreamInterface(who.interfaceName()); @@ -1563,10 +1562,10 @@ public class Tethering extends BaseNetworkObserver { boolean retValue = true; switch (message.what) { case EVENT_IFACE_SERVING_STATE_ACTIVE: { - TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; + IpServer who = (IpServer) message.obj; if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); handleInterfaceServingStateActive(message.arg1, who); - who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, + who.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, mCurrentUpstreamIfaceSet); // If there has been a change and an upstream is now // desired, kick off the selection process. @@ -1577,7 +1576,7 @@ public class Tethering extends BaseNetworkObserver { break; } case EVENT_IFACE_SERVING_STATE_INACTIVE: { - TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; + IpServer who = (IpServer) message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); handleInterfaceServingStateInactive(who); @@ -1591,7 +1590,7 @@ public class Tethering extends BaseNetworkObserver { if (DBG) { Log.d(TAG, "TetherModeAlive still has " + mNotifyList.size() + " live requests:"); - for (TetherInterfaceStateMachine o : mNotifyList) { + for (IpServer o : mNotifyList) { Log.d(TAG, " " + o); } } @@ -1605,7 +1604,7 @@ public class Tethering extends BaseNetworkObserver { } case EVENT_IFACE_UPDATE_LINKPROPERTIES: { final LinkProperties newLp = (LinkProperties) message.obj; - if (message.arg1 == IControlsTethering.STATE_TETHERED) { + if (message.arg1 == IpServer.STATE_TETHERED) { mOffload.updateDownstreamLinkProperties(newLp); } else { mOffload.excludeDownstreamInterface(newLp.getInterfaceName()); @@ -1650,7 +1649,7 @@ public class Tethering extends BaseNetworkObserver { boolean retValue = true; switch (message.what) { case EVENT_IFACE_SERVING_STATE_ACTIVE: - TetherInterfaceStateMachine who = (TetherInterfaceStateMachine) message.obj; + IpServer who = (IpServer) message.obj; who.sendMessage(mErrorNotification); break; case CMD_CLEAR_ERROR: @@ -1665,8 +1664,8 @@ public class Tethering extends BaseNetworkObserver { void notify(int msgType) { mErrorNotification = msgType; - for (TetherInterfaceStateMachine sm : mNotifyList) { - sm.sendMessage(msgType); + for (IpServer ipServer : mNotifyList) { + ipServer.sendMessage(msgType); } } @@ -1676,7 +1675,7 @@ public class Tethering extends BaseNetworkObserver { @Override public void enter() { Log.e(TAG, "Error in setIpForwardingEnabled"); - notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR); + notify(IpServer.CMD_IP_FORWARDING_ENABLE_ERROR); } } @@ -1684,7 +1683,7 @@ public class Tethering extends BaseNetworkObserver { @Override public void enter() { Log.e(TAG, "Error in setIpForwardingDisabled"); - notify(TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR); + notify(IpServer.CMD_IP_FORWARDING_DISABLE_ERROR); } } @@ -1692,7 +1691,7 @@ public class Tethering extends BaseNetworkObserver { @Override public void enter() { Log.e(TAG, "Error in startTethering"); - notify(TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR); + notify(IpServer.CMD_START_TETHERING_ERROR); try { mNMService.setIpForwardingEnabled(false); } catch (Exception e) {} @@ -1703,7 +1702,7 @@ public class Tethering extends BaseNetworkObserver { @Override public void enter() { Log.e(TAG, "Error in stopTethering"); - notify(TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR); + notify(IpServer.CMD_STOP_TETHERING_ERROR); try { mNMService.setIpForwardingEnabled(false); } catch (Exception e) {} @@ -1714,7 +1713,7 @@ public class Tethering extends BaseNetworkObserver { @Override public void enter() { Log.e(TAG, "Error in setDnsForwarders"); - notify(TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR); + notify(IpServer.CMD_SET_DNS_FORWARDERS_ERROR); try { mNMService.stopTethering(); } catch (Exception e) {} @@ -1771,15 +1770,15 @@ public class Tethering extends BaseNetworkObserver { // Maybe add prefixes or addresses for downstreams, depending on // the IP serving mode of each. - for (TetherInterfaceStateMachine tism : mNotifyList) { - final LinkProperties lp = tism.linkProperties(); + for (IpServer ipServer : mNotifyList) { + final LinkProperties lp = ipServer.linkProperties(); - switch (tism.servingMode()) { - case IControlsTethering.STATE_UNAVAILABLE: - case IControlsTethering.STATE_AVAILABLE: + switch (ipServer.servingMode()) { + case IpServer.STATE_UNAVAILABLE: + case IpServer.STATE_AVAILABLE: // No usable LinkProperties in these states. continue; - case IControlsTethering.STATE_TETHERED: + case IpServer.STATE_TETHERED: // Only add IPv4 /32 and IPv6 /128 prefixes. The // directly-connected prefixes will be sent as // downstream "offload-able" prefixes. @@ -1789,7 +1788,7 @@ public class Tethering extends BaseNetworkObserver { localPrefixes.add(PrefixUtils.ipAddressAsPrefix(ip)); } break; - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_LOCAL_ONLY: // Add prefixes covering all local IPs. localPrefixes.addAll(PrefixUtils.localPrefixesFrom(lp)); break; @@ -1826,16 +1825,16 @@ public class Tethering extends BaseNetworkObserver { pw.print(iface + " - "); switch (tetherState.lastState) { - case IControlsTethering.STATE_UNAVAILABLE: + case IpServer.STATE_UNAVAILABLE: pw.print("UnavailableState"); break; - case IControlsTethering.STATE_AVAILABLE: + case IpServer.STATE_AVAILABLE: pw.print("AvailableState"); break; - case IControlsTethering.STATE_TETHERED: + case IpServer.STATE_TETHERED: pw.print("TetheredState"); break; - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_LOCAL_ONLY: pw.print("LocalHotspotState"); break; default: @@ -1873,28 +1872,26 @@ public class Tethering extends BaseNetworkObserver { return false; } - private IControlsTethering makeControlCallback(String ifname) { - return new IControlsTethering() { + private IpServer.Callback makeControlCallback() { + return new IpServer.Callback() { @Override - public void updateInterfaceState( - TetherInterfaceStateMachine who, int state, int lastError) { - notifyInterfaceStateChange(ifname, who, state, lastError); + public void updateInterfaceState(IpServer who, int state, int lastError) { + notifyInterfaceStateChange(who, state, lastError); } @Override - public void updateLinkProperties( - TetherInterfaceStateMachine who, LinkProperties newLp) { - notifyLinkPropertiesChanged(ifname, who, newLp); + public void updateLinkProperties(IpServer who, LinkProperties newLp) { + notifyLinkPropertiesChanged(who, newLp); } }; } // TODO: Move into TetherMasterSM. - private void notifyInterfaceStateChange( - String iface, TetherInterfaceStateMachine who, int state, int error) { + private void notifyInterfaceStateChange(IpServer who, int state, int error) { + final String iface = who.interfaceName(); synchronized (mPublicSync) { final TetherState tetherState = mTetherStates.get(iface); - if (tetherState != null && tetherState.stateMachine.equals(who)) { + if (tetherState != null && tetherState.ipServer.equals(who)) { tetherState.lastState = state; tetherState.lastError = error; } else { @@ -1908,7 +1905,7 @@ public class Tethering extends BaseNetworkObserver { // Notify that we're tethering (or not) this interface. // This is how data saver for instance knows if the user explicitly // turned on tethering (thus keeping us from being in data saver mode). - mPolicyManager.onTetheringChanged(iface, state == IControlsTethering.STATE_TETHERED); + mPolicyManager.onTetheringChanged(iface, state == IpServer.STATE_TETHERED); } catch (RemoteException e) { // Not really very much we can do here. } @@ -1921,12 +1918,12 @@ public class Tethering extends BaseNetworkObserver { } int which; switch (state) { - case IControlsTethering.STATE_UNAVAILABLE: - case IControlsTethering.STATE_AVAILABLE: + case IpServer.STATE_UNAVAILABLE: + case IpServer.STATE_AVAILABLE: which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_INACTIVE; break; - case IControlsTethering.STATE_TETHERED: - case IControlsTethering.STATE_LOCAL_ONLY: + case IpServer.STATE_TETHERED: + case IpServer.STATE_LOCAL_ONLY: which = TetherMasterSM.EVENT_IFACE_SERVING_STATE_ACTIVE; break; default: @@ -1937,12 +1934,12 @@ public class Tethering extends BaseNetworkObserver { sendTetherStateChangedBroadcast(); } - private void notifyLinkPropertiesChanged(String iface, TetherInterfaceStateMachine who, - LinkProperties newLp) { + private void notifyLinkPropertiesChanged(IpServer who, LinkProperties newLp) { + final String iface = who.interfaceName(); final int state; synchronized (mPublicSync) { final TetherState tetherState = mTetherStates.get(iface); - if (tetherState != null && tetherState.stateMachine.equals(who)) { + if (tetherState != null && tetherState.ipServer.equals(who)) { state = tetherState.lastState; } else { mLog.log("got notification from stale iface " + iface); @@ -1952,7 +1949,7 @@ public class Tethering extends BaseNetworkObserver { mLog.log(String.format( "OBSERVED LinkProperties update iface=%s state=%s lp=%s", - iface, IControlsTethering.getStateString(state), newLp)); + iface, IpServer.getStateString(state), newLp)); final int which = TetherMasterSM.EVENT_IFACE_UPDATE_LINKPROPERTIES; mTetherMasterSM.sendMessage(which, state, 0, newLp); } @@ -1976,11 +1973,11 @@ public class Tethering extends BaseNetworkObserver { mLog.log("adding TetheringInterfaceStateMachine for: " + iface); final TetherState tetherState = new TetherState( - new TetherInterfaceStateMachine( - iface, mLooper, interfaceType, mLog, mNMService, mStatsService, - makeControlCallback(iface), mConfig.enableLegacyDhcpServer, mDeps)); + new IpServer(iface, mLooper, interfaceType, mLog, mNMService, mStatsService, + makeControlCallback(), mConfig.enableLegacyDhcpServer, + mDeps.getIpServerDependencies())); mTetherStates.put(iface, tetherState); - tetherState.stateMachine.start(); + tetherState.ipServer.start(); } private void stopTrackingInterfaceLocked(final String iface) { @@ -1989,36 +1986,11 @@ public class Tethering extends BaseNetworkObserver { mLog.log("attempting to remove unknown iface (" + iface + "), ignoring"); return; } - tetherState.stateMachine.stop(); + tetherState.ipServer.stop(); mLog.log("removing TetheringInterfaceStateMachine for: " + iface); mTetherStates.remove(iface); } - private static String getIPv4DefaultRouteInterface(NetworkState ns) { - if (ns == null) return null; - return getInterfaceForDestination(ns.linkProperties, Inet4Address.ANY); - } - - private static String getIPv6DefaultRouteInterface(NetworkState ns) { - if (ns == null) return null; - // An upstream network's IPv6 capability is currently only useful if it - // can be 64share'd downstream (RFC 7278). For now, that means mobile - // upstream networks only. - if (ns.networkCapabilities == null || - !ns.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { - return null; - } - - return getInterfaceForDestination(ns.linkProperties, Inet6Address.ANY); - } - - private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) { - final RouteInfo ri = (lp != null) - ? RouteInfo.selectBestRoute(lp.getAllRoutes(), dst) - : null; - return (ri != null) ? ri.getInterface() : null; - } - private static String[] copy(String[] strarray) { return Arrays.copyOf(strarray, strarray.length); } diff --git a/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java b/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java deleted file mode 100644 index 2b813475222f..000000000000 --- a/services/core/java/com/android/server/connectivity/tethering/IControlsTethering.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2016 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.server.connectivity.tethering; - -import android.net.LinkProperties; - -/** - * @hide - * - * Interface with methods necessary to notify that a given interface is ready for tethering. - * - * Rename to something more representative, e.g. IpServingControlCallback. - * - * All methods MUST be called on the TetherMasterSM main Looper's thread. - */ -public class IControlsTethering { - public static final int STATE_UNAVAILABLE = 0; - public static final int STATE_AVAILABLE = 1; - public static final int STATE_TETHERED = 2; - public static final int STATE_LOCAL_ONLY = 3; - - public static String getStateString(int state) { - switch (state) { - case STATE_UNAVAILABLE: return "UNAVAILABLE"; - case STATE_AVAILABLE: return "AVAILABLE"; - case STATE_TETHERED: return "TETHERED"; - case STATE_LOCAL_ONLY: return "LOCAL_ONLY"; - } - return "UNKNOWN: " + state; - } - - /** - * Notify that |who| has changed its tethering state. - * - * TODO: Remove the need for the |who| argument. - * - * @param who corresponding instance of a TetherInterfaceStateMachine - * @param state one of IControlsTethering.STATE_* - * @param lastError one of ConnectivityManager.TETHER_ERROR_* - */ - public void updateInterfaceState(TetherInterfaceStateMachine who, int state, int lastError) {} - - /** - * Notify that |who| has new LinkProperties. - * - * TODO: Remove the need for the |who| argument. - * - * @param who corresponding instance of a TetherInterfaceStateMachine - * @param newLp the new LinkProperties to report - */ - public void updateLinkProperties(TetherInterfaceStateMachine who, LinkProperties newLp) {} -} diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java index ba67c94d1cd4..100014898127 100644 --- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java @@ -17,6 +17,7 @@ package com.android.server.connectivity.tethering; import android.net.ConnectivityManager; +import android.net.ip.IpServer; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; @@ -50,19 +51,19 @@ public class IPv6TetheringCoordinator { private static final boolean VDBG = false; private static class Downstream { - public final TetherInterfaceStateMachine tism; - public final int mode; // IControlsTethering.STATE_* + public final IpServer ipServer; + public final int mode; // IpServer.STATE_* // Used to append to a ULA /48, constructing a ULA /64 for local use. public final short subnetId; - Downstream(TetherInterfaceStateMachine tism, int mode, short subnetId) { - this.tism = tism; + Downstream(IpServer ipServer, int mode, short subnetId) { + this.ipServer = ipServer; this.mode = mode; this.subnetId = subnetId; } } - private final ArrayList<TetherInterfaceStateMachine> mNotifyList; + private final ArrayList<IpServer> mNotifyList; private final SharedLog mLog; // NOTE: mActiveDownstreams is a list and not a hash data structure because // we keep active downstreams in arrival order. This is done so /64s can @@ -74,8 +75,7 @@ public class IPv6TetheringCoordinator { private short mNextSubnetId; private NetworkState mUpstreamNetworkState; - public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList, - SharedLog log) { + public IPv6TetheringCoordinator(ArrayList<IpServer> notifyList, SharedLog log) { mNotifyList = notifyList; mLog = log.forSubComponent(TAG); mActiveDownstreams = new LinkedList<>(); @@ -83,7 +83,7 @@ public class IPv6TetheringCoordinator { mNextSubnetId = 0; } - public void addActiveDownstream(TetherInterfaceStateMachine downstream, int mode) { + public void addActiveDownstream(IpServer downstream, int mode) { if (findDownstream(downstream) == null) { // Adding a new downstream appends it to the list. Adding a // downstream a second time without first removing it has no effect. @@ -98,7 +98,7 @@ public class IPv6TetheringCoordinator { } } - public void removeActiveDownstream(TetherInterfaceStateMachine downstream) { + public void removeActiveDownstream(IpServer downstream) { stopIPv6TetheringOn(downstream); if (mActiveDownstreams.remove(findDownstream(downstream))) { updateIPv6TetheringInterfaces(); @@ -133,8 +133,8 @@ public class IPv6TetheringCoordinator { } private void stopIPv6TetheringOnAllInterfaces() { - for (TetherInterfaceStateMachine sm : mNotifyList) { - stopIPv6TetheringOn(sm); + for (IpServer ipServer : mNotifyList) { + stopIPv6TetheringOn(ipServer); } } @@ -156,28 +156,28 @@ public class IPv6TetheringCoordinator { } private void updateIPv6TetheringInterfaces() { - for (TetherInterfaceStateMachine sm : mNotifyList) { - final LinkProperties lp = getInterfaceIPv6LinkProperties(sm); - sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); + for (IpServer ipServer : mNotifyList) { + final LinkProperties lp = getInterfaceIPv6LinkProperties(ipServer); + ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); break; } } - private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) { - if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) { + private LinkProperties getInterfaceIPv6LinkProperties(IpServer ipServer) { + if (ipServer.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) { // TODO: Figure out IPv6 support on PAN interfaces. return null; } - final Downstream ds = findDownstream(sm); + final Downstream ds = findDownstream(ipServer); if (ds == null) return null; - if (ds.mode == IControlsTethering.STATE_LOCAL_ONLY) { + if (ds.mode == IpServer.STATE_LOCAL_ONLY) { // Build a Unique Locally-assigned Prefix configuration. return getUniqueLocalConfig(mUniqueLocalPrefix, ds.subnetId); } - // This downstream is in IControlsTethering.STATE_TETHERED mode. + // This downstream is in IpServer.STATE_TETHERED mode. if (mUpstreamNetworkState == null || mUpstreamNetworkState.linkProperties == null) { return null; } @@ -188,7 +188,7 @@ public class IPv6TetheringCoordinator { // IPv6 toward the oldest (first requested) active downstream. final Downstream currentActive = mActiveDownstreams.peek(); - if (currentActive != null && currentActive.tism == sm) { + if (currentActive != null && currentActive.ipServer == ipServer) { final LinkProperties lp = getIPv6OnlyLinkProperties( mUpstreamNetworkState.linkProperties); if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { @@ -199,9 +199,9 @@ public class IPv6TetheringCoordinator { return null; } - Downstream findDownstream(TetherInterfaceStateMachine tism) { + Downstream findDownstream(IpServer ipServer) { for (Downstream ds : mActiveDownstreams) { - if (ds.tism == tism) return ds; + if (ds.ipServer == ipServer) return ds; } return null; } @@ -304,7 +304,7 @@ public class IPv6TetheringCoordinator { ns.linkProperties); } - private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) { - sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); + private static void stopIPv6TetheringOn(IpServer ipServer) { + ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null); } } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java index caa867c616b8..8b4006916736 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java @@ -21,6 +21,7 @@ import android.net.INetd; import android.net.NetworkRequest; import android.net.dhcp.DhcpServer; import android.net.dhcp.DhcpServingParams; +import android.net.ip.IpServer; import android.net.ip.RouterAdvertisementDaemon; import android.net.util.InterfaceParams; import android.net.util.NetdService; @@ -49,20 +50,12 @@ public class TetheringDependencies { } public IPv6TetheringCoordinator getIPv6TetheringCoordinator( - ArrayList<TetherInterfaceStateMachine> notifyList, SharedLog log) { + ArrayList<IpServer> notifyList, SharedLog log) { return new IPv6TetheringCoordinator(notifyList, log); } - public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { - return new RouterAdvertisementDaemon(ifParams); - } - - public InterfaceParams getInterfaceParams(String ifName) { - return InterfaceParams.getByName(ifName); - } - - public INetd getNetdService() { - return NetdService.getInstance(); + public IpServer.Dependencies getIpServerDependencies() { + return new IpServer.Dependencies(); } public boolean isTetheringSupported() { @@ -72,9 +65,4 @@ public class TetheringDependencies { public NetworkRequest getDefaultNetworkRequest() { return null; } - - public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, DhcpServingParams params, - SharedLog log) { - return new DhcpServer(looper, iface, params, log); - } } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/net/java/android/net/ip/IpServer.java index 5accb452d10a..823c0a1ac7b0 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package android.net.ip; import static android.net.NetworkUtils.numericToInetAddress; import static android.net.util.NetworkConstants.asByte; @@ -31,11 +31,10 @@ import android.net.LinkProperties; import android.net.RouteInfo; import android.net.dhcp.DhcpServer; import android.net.dhcp.DhcpServingParams; -import android.net.ip.InterfaceController; -import android.net.ip.RouterAdvertisementDaemon; import android.net.ip.RouterAdvertisementDaemon.RaParams; import android.net.util.InterfaceParams; import android.net.util.InterfaceSet; +import android.net.util.NetdService; import android.net.util.SharedLog; import android.os.INetworkManagementService; import android.os.Looper; @@ -67,7 +66,22 @@ import java.util.Set; * * @hide */ -public class TetherInterfaceStateMachine extends StateMachine { +public class IpServer extends StateMachine { + public static final int STATE_UNAVAILABLE = 0; + public static final int STATE_AVAILABLE = 1; + public static final int STATE_TETHERED = 2; + public static final int STATE_LOCAL_ONLY = 3; + + public static String getStateString(int state) { + switch (state) { + case STATE_UNAVAILABLE: return "UNAVAILABLE"; + case STATE_AVAILABLE: return "AVAILABLE"; + case STATE_TETHERED: return "TETHERED"; + case STATE_LOCAL_ONLY: return "LOCAL_ONLY"; + } + return "UNKNOWN: " + state; + } + private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64"); private static final byte DOUG_ADAMS = (byte) 42; @@ -83,15 +97,53 @@ public class TetherInterfaceStateMachine extends StateMachine { // TODO: have this configurable private static final int DHCP_LEASE_TIME_SECS = 3600; - private final static String TAG = "TetherInterfaceSM"; + private final static String TAG = "IpServer"; private final static boolean DBG = false; private final static boolean VDBG = false; private static final Class[] messageClasses = { - TetherInterfaceStateMachine.class + IpServer.class }; private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(messageClasses); + public static class Callback { + /** + * Notify that |who| has changed its tethering state. + * + * @param who the calling instance of IpServer + * @param state one of STATE_* + * @param lastError one of ConnectivityManager.TETHER_ERROR_* + */ + public void updateInterfaceState(IpServer who, int state, int lastError) {} + + /** + * Notify that |who| has new LinkProperties. + * + * @param who the calling instance of IpServer + * @param newLp the new LinkProperties to report + */ + public void updateLinkProperties(IpServer who, LinkProperties newLp) {} + } + + public static class Dependencies { + public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { + return new RouterAdvertisementDaemon(ifParams); + } + + public InterfaceParams getInterfaceParams(String ifName) { + return InterfaceParams.getByName(ifName); + } + + public INetd getNetdService() { + return NetdService.getInstance(); + } + + public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, + DhcpServingParams params, SharedLog log) { + return new DhcpServer(looper, iface, params, log); + } + } + private static final int BASE_IFACE = Protocol.BASE_TETHERING + 100; // request from the user that it wants to tether public static final int CMD_TETHER_REQUESTED = BASE_IFACE + 2; @@ -123,7 +175,7 @@ public class TetherInterfaceStateMachine extends StateMachine { private final INetworkManagementService mNMService; private final INetd mNetd; private final INetworkStatsService mStatsService; - private final IControlsTethering mTetherController; + private final Callback mCallback; private final InterfaceController mInterfaceCtrl; private final String mIfaceName; @@ -131,7 +183,7 @@ public class TetherInterfaceStateMachine extends StateMachine { private final LinkProperties mLinkProperties; private final boolean mUsingLegacyDhcp; - private final TetheringDependencies mDeps; + private final Dependencies mDeps; private int mLastError; private int mServingMode; @@ -148,17 +200,16 @@ public class TetherInterfaceStateMachine extends StateMachine { private DhcpServer mDhcpServer; private RaParams mLastRaParams; - public TetherInterfaceStateMachine( + public IpServer( String ifaceName, Looper looper, int interfaceType, SharedLog log, INetworkManagementService nMService, INetworkStatsService statsService, - IControlsTethering tetherController, boolean usingLegacyDhcp, - TetheringDependencies deps) { + Callback callback, boolean usingLegacyDhcp, Dependencies deps) { super(ifaceName, looper); mLog = log.forSubComponent(ifaceName); mNMService = nMService; mNetd = deps.getNetdService(); mStatsService = statsService; - mTetherController = tetherController; + mCallback = callback; mInterfaceCtrl = new InterfaceController(ifaceName, nMService, mNetd, mLog); mIfaceName = ifaceName; mInterfaceType = interfaceType; @@ -167,7 +218,7 @@ public class TetherInterfaceStateMachine extends StateMachine { mDeps = deps; resetLinkProperties(); mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; - mServingMode = IControlsTethering.STATE_AVAILABLE; + mServingMode = STATE_AVAILABLE; mInitialState = new InitialState(); mLocalHotspotState = new LocalHotspotState(); @@ -379,6 +430,8 @@ public class TetherInterfaceStateMachine extends StateMachine { params.mtu = v6only.getMtu(); params.hasDefaultRoute = v6only.hasIPv6DefaultRoute(); + if (params.hasDefaultRoute) params.hopLimit = getHopLimit(v6only.getInterfaceName()); + for (LinkAddress linkAddr : v6only.getLinkAddresses()) { if (linkAddr.getPrefixLength() != RFC7421_PREFIX_LENGTH) continue; @@ -498,6 +551,20 @@ public class TetherInterfaceStateMachine extends StateMachine { } } + private byte getHopLimit(String upstreamIface) { + try { + int upstreamHopLimit = Integer.parseUnsignedInt( + mNetd.getProcSysNet(INetd.IPV6, INetd.CONF, upstreamIface, "hop_limit")); + // Add one hop to account for this forwarding device + upstreamHopLimit++; + // Cap the hop limit to 255. + return (byte) Integer.min(upstreamHopLimit, 255); + } catch (Exception e) { + mLog.e("Failed to find upstream interface hop limit", e); + } + return RaParams.DEFAULT_HOPLIMIT; + } + private void setRaParams(RaParams newParams) { if (mRaDaemon != null) { final RaParams deprecatedParams = @@ -521,14 +588,12 @@ public class TetherInterfaceStateMachine extends StateMachine { private void sendInterfaceState(int newInterfaceState) { mServingMode = newInterfaceState; - mTetherController.updateInterfaceState( - TetherInterfaceStateMachine.this, newInterfaceState, mLastError); + mCallback.updateInterfaceState(this, newInterfaceState, mLastError); sendLinkProperties(); } private void sendLinkProperties() { - mTetherController.updateLinkProperties( - TetherInterfaceStateMachine.this, new LinkProperties(mLinkProperties)); + mCallback.updateLinkProperties(this, new LinkProperties(mLinkProperties)); } private void resetLinkProperties() { @@ -539,7 +604,7 @@ public class TetherInterfaceStateMachine extends StateMachine { class InitialState extends State { @Override public void enter() { - sendInterfaceState(IControlsTethering.STATE_AVAILABLE); + sendInterfaceState(STATE_AVAILABLE); } @Override @@ -549,10 +614,10 @@ public class TetherInterfaceStateMachine extends StateMachine { case CMD_TETHER_REQUESTED: mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; switch (message.arg1) { - case IControlsTethering.STATE_LOCAL_ONLY: + case STATE_LOCAL_ONLY: transitionTo(mLocalHotspotState); break; - case IControlsTethering.STATE_TETHERED: + case STATE_TETHERED: transitionTo(mTetheredState); break; default: @@ -649,7 +714,7 @@ public class TetherInterfaceStateMachine extends StateMachine { // problematic because transitioning during a multi-state jump yields // a Log.wtf(). Ultimately, there should be only one ServingState, // and forwarding and NAT rules should be handled by a coordinating - // functional element outside of TetherInterfaceStateMachine. + // functional element outside of IpServer. class LocalHotspotState extends BaseServingState { @Override public void enter() { @@ -659,7 +724,7 @@ public class TetherInterfaceStateMachine extends StateMachine { } if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName); - sendInterfaceState(IControlsTethering.STATE_LOCAL_ONLY); + sendInterfaceState(STATE_LOCAL_ONLY); } @Override @@ -685,7 +750,7 @@ public class TetherInterfaceStateMachine extends StateMachine { // problematic because transitioning during a multi-state jump yields // a Log.wtf(). Ultimately, there should be only one ServingState, // and forwarding and NAT rules should be handled by a coordinating - // functional element outside of TetherInterfaceStateMachine. + // functional element outside of IpServer. class TetheredState extends BaseServingState { @Override public void enter() { @@ -695,7 +760,7 @@ public class TetherInterfaceStateMachine extends StateMachine { } if (DBG) Log.d(TAG, "Tethered " + mIfaceName); - sendInterfaceState(IControlsTethering.STATE_TETHERED); + sendInterfaceState(STATE_TETHERED); } @Override @@ -817,7 +882,7 @@ public class TetherInterfaceStateMachine extends StateMachine { @Override public void enter() { mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR; - sendInterfaceState(IControlsTethering.STATE_UNAVAILABLE); + sendInterfaceState(STATE_UNAVAILABLE); } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 2cc175c395e0..ebe05e8b27db 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1498,23 +1498,24 @@ public class TelephonyManager { Rlog.d(TAG, "getCellLocation returning null because telephony is null"); return null; } + Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName()); - if (bundle.isEmpty()) { - Rlog.d(TAG, "getCellLocation returning null because bundle is empty"); + if (bundle == null || bundle.isEmpty()) { + Rlog.d(TAG, "getCellLocation returning null because CellLocation is unavailable"); return null; } + CellLocation cl = CellLocation.newFromBundle(bundle); - if (cl.isEmpty()) { - Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty"); + if (cl == null || cl.isEmpty()) { + Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty or" + + " phone type doesn't match CellLocation type"); return null; } + return cl; } catch (RemoteException ex) { Rlog.d(TAG, "getCellLocation returning null due to RemoteException " + ex); return null; - } catch (NullPointerException ex) { - Rlog.d(TAG, "getCellLocation returning null due to NullPointerException " + ex); - return null; } } diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/android/net/ip/IpServerTest.java index 593465380263..cff0b5469d47 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java +++ b/tests/net/java/android/net/ip/IpServerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package android.net.ip; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -37,9 +37,9 @@ import static android.net.ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR; import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; import static android.net.ConnectivityManager.TETHERING_USB; import static android.net.ConnectivityManager.TETHERING_WIFI; -import static com.android.server.connectivity.tethering.IControlsTethering.STATE_AVAILABLE; -import static com.android.server.connectivity.tethering.IControlsTethering.STATE_TETHERED; -import static com.android.server.connectivity.tethering.IControlsTethering.STATE_UNAVAILABLE; +import static android.net.ip.IpServer.STATE_AVAILABLE; +import static android.net.ip.IpServer.STATE_TETHERED; +import static android.net.ip.IpServer.STATE_UNAVAILABLE; import android.net.INetworkStatsService; import android.net.InterfaceConfiguration; @@ -50,7 +50,6 @@ import android.net.MacAddress; import android.net.RouteInfo; import android.net.dhcp.DhcpServer; import android.net.dhcp.DhcpServingParams; -import android.net.ip.RouterAdvertisementDaemon; import android.net.util.InterfaceParams; import android.net.util.InterfaceSet; import android.net.util.SharedLog; @@ -74,7 +73,7 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) @SmallTest -public class TetherInterfaceStateMachineTest { +public class IpServerTest { private static final String IFACE_NAME = "testnet1"; private static final String UPSTREAM_IFACE = "upstream0"; private static final String UPSTREAM_IFACE2 = "upstream1"; @@ -85,39 +84,38 @@ public class TetherInterfaceStateMachineTest { @Mock private INetworkManagementService mNMService; @Mock private INetworkStatsService mStatsService; - @Mock private IControlsTethering mTetherHelper; + @Mock private IpServer.Callback mCallback; @Mock private InterfaceConfiguration mInterfaceConfiguration; @Mock private SharedLog mSharedLog; @Mock private DhcpServer mDhcpServer; @Mock private RouterAdvertisementDaemon mRaDaemon; - @Mock private TetheringDependencies mTetheringDependencies; + @Mock private IpServer.Dependencies mDependencies; @Captor private ArgumentCaptor<DhcpServingParams> mDhcpParamsCaptor; private final TestLooper mLooper = new TestLooper(); private final ArgumentCaptor<LinkProperties> mLinkPropertiesCaptor = ArgumentCaptor.forClass(LinkProperties.class); - private TetherInterfaceStateMachine mTestedSm; + private IpServer mIpServer; private void initStateMachine(int interfaceType) throws Exception { initStateMachine(interfaceType, false /* usingLegacyDhcp */); } private void initStateMachine(int interfaceType, boolean usingLegacyDhcp) throws Exception { - mTestedSm = new TetherInterfaceStateMachine( + mIpServer = new IpServer( IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, - mNMService, mStatsService, mTetherHelper, usingLegacyDhcp, - mTetheringDependencies); - mTestedSm.start(); + mNMService, mStatsService, mCallback, usingLegacyDhcp, mDependencies); + mIpServer.start(); // Starting the state machine always puts us in a consistent state and notifies // the rest of the world that we've changed from an unknown to available state. mLooper.dispatchAll(); - reset(mNMService, mStatsService, mTetherHelper); + reset(mNMService, mStatsService, mCallback); when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); - when(mTetheringDependencies.makeDhcpServer( + when(mDependencies.makeDhcpServer( any(), any(), mDhcpParamsCaptor.capture(), any())).thenReturn(mDhcpServer); - when(mTetheringDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon); - when(mTetheringDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS); + when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon); + when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS); when(mRaDaemon.start()).thenReturn(true); } @@ -130,11 +128,11 @@ public class TetherInterfaceStateMachineTest { private void initTetheredStateMachine(int interfaceType, String upstreamIface, boolean usingLegacyDhcp) throws Exception { initStateMachine(interfaceType, usingLegacyDhcp); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, STATE_TETHERED); + dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); if (upstreamIface != null) { dispatchTetherConnectionChanged(upstreamIface); } - reset(mNMService, mStatsService, mTetherHelper); + reset(mNMService, mStatsService, mCallback); when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); } @@ -145,34 +143,34 @@ public class TetherInterfaceStateMachineTest { @Test public void startsOutAvailable() { - mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), - TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mTetherHelper, - false /* usingLegacyDhcp */, mTetheringDependencies); - mTestedSm.start(); + mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), + TETHERING_BLUETOOTH, mSharedLog, mNMService, mStatsService, mCallback, + false /* usingLegacyDhcp */, mDependencies); + mIpServer.start(); mLooper.dispatchAll(); - verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); - verify(mTetherHelper).updateLinkProperties(eq(mTestedSm), any(LinkProperties.class)); - verifyNoMoreInteractions(mTetherHelper, mNMService, mStatsService); + verify(mCallback).updateInterfaceState( + mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); + verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class)); + verifyNoMoreInteractions(mCallback, mNMService, mStatsService); } @Test public void shouldDoNothingUntilRequested() throws Exception { initStateMachine(TETHERING_BLUETOOTH); final int [] NOOP_COMMANDS = { - TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED, - TetherInterfaceStateMachine.CMD_IP_FORWARDING_ENABLE_ERROR, - TetherInterfaceStateMachine.CMD_IP_FORWARDING_DISABLE_ERROR, - TetherInterfaceStateMachine.CMD_START_TETHERING_ERROR, - TetherInterfaceStateMachine.CMD_STOP_TETHERING_ERROR, - TetherInterfaceStateMachine.CMD_SET_DNS_FORWARDERS_ERROR, - TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED + IpServer.CMD_TETHER_UNREQUESTED, + IpServer.CMD_IP_FORWARDING_ENABLE_ERROR, + IpServer.CMD_IP_FORWARDING_DISABLE_ERROR, + IpServer.CMD_START_TETHERING_ERROR, + IpServer.CMD_STOP_TETHERING_ERROR, + IpServer.CMD_SET_DNS_FORWARDERS_ERROR, + IpServer.CMD_TETHER_CONNECTION_CHANGED }; for (int command : NOOP_COMMANDS) { // None of these commands should trigger us to request action from // the rest of the system. dispatchCommand(command); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } } @@ -180,57 +178,57 @@ public class TetherInterfaceStateMachineTest { public void handlesImmediateInterfaceDown() throws Exception { initStateMachine(TETHERING_BLUETOOTH); - dispatchCommand(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN); - verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR); - verify(mTetherHelper).updateLinkProperties(eq(mTestedSm), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + dispatchCommand(IpServer.CMD_INTERFACE_DOWN); + verify(mCallback).updateInterfaceState( + mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR); + verify(mCallback).updateLinkProperties(eq(mIpServer), any(LinkProperties.class)); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test public void canBeTethered() throws Exception { initStateMachine(TETHERING_BLUETOOTH); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder inOrder = inOrder(mTetherHelper, mNMService); + dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); + InOrder inOrder = inOrder(mCallback, mNMService); inOrder.verify(mNMService).tetherInterface(IFACE_NAME); - inOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_TETHERED, TETHER_ERROR_NO_ERROR); - inOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + inOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR); + inOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), any(LinkProperties.class)); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test public void canUnrequestTethering() throws Exception { initTetheredStateMachine(TETHERING_BLUETOOTH, null); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper); + dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); + InOrder inOrder = inOrder(mNMService, mStatsService, mCallback); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); - inOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); - inOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + inOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); + inOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), any(LinkProperties.class)); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test public void canBeTetheredAsUsb() throws Exception { initStateMachine(TETHERING_USB); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder inOrder = inOrder(mTetherHelper, mNMService); + dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); + InOrder inOrder = inOrder(mCallback, mNMService); inOrder.verify(mNMService).getInterfaceConfig(IFACE_NAME); inOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration); inOrder.verify(mNMService).tetherInterface(IFACE_NAME); - inOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_TETHERED, TETHER_ERROR_NO_ERROR); - inOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), mLinkPropertiesCaptor.capture()); + inOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_TETHERED, TETHER_ERROR_NO_ERROR); + inOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), mLinkPropertiesCaptor.capture()); assertIPv4AddressAndDirectlyConnectedRoute(mLinkPropertiesCaptor.getValue()); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test @@ -243,7 +241,7 @@ public class TetherInterfaceStateMachineTest { InOrder inOrder = inOrder(mNMService); inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test @@ -257,7 +255,7 @@ public class TetherInterfaceStateMachineTest { inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).enableNat(IFACE_NAME, UPSTREAM_IFACE2); inOrder.verify(mNMService).startInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE2); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test @@ -300,18 +298,18 @@ public class TetherInterfaceStateMachineTest { public void canUnrequestTetheringWithUpstream() throws Exception { initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper); + dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); + InOrder inOrder = inOrder(mNMService, mStatsService, mCallback); inOrder.verify(mStatsService).forceUpdate(); inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); - inOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); - inOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), any(LinkProperties.class)); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + inOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); + inOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), any(LinkProperties.class)); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } @Test @@ -322,15 +320,15 @@ public class TetherInterfaceStateMachineTest { if (shouldThrow) { doThrow(RemoteException.class).when(mNMService).untetherInterface(IFACE_NAME); } - dispatchCommand(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper); + dispatchCommand(IpServer.CMD_INTERFACE_DOWN); + InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); usbTeardownOrder.verify(mNMService).setInterfaceConfig( IFACE_NAME, mInterfaceConfiguration); - usbTeardownOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR); - usbTeardownOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), mLinkPropertiesCaptor.capture()); + usbTeardownOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_UNAVAILABLE, TETHER_ERROR_NO_ERROR); + usbTeardownOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), mLinkPropertiesCaptor.capture()); assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue()); } } @@ -340,15 +338,15 @@ public class TetherInterfaceStateMachineTest { initStateMachine(TETHERING_USB); doThrow(RemoteException.class).when(mNMService).tetherInterface(IFACE_NAME); - dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED, STATE_TETHERED); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper); + dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED); + InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); usbTeardownOrder.verify(mNMService).setInterfaceConfig( IFACE_NAME, mInterfaceConfiguration); - usbTeardownOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR); - usbTeardownOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), mLinkPropertiesCaptor.capture()); + usbTeardownOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_AVAILABLE, TETHER_ERROR_TETHER_IFACE_ERROR); + usbTeardownOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), mLinkPropertiesCaptor.capture()); assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue()); } @@ -358,13 +356,13 @@ public class TetherInterfaceStateMachineTest { doThrow(RemoteException.class).when(mNMService).enableNat(anyString(), anyString()); dispatchTetherConnectionChanged(UPSTREAM_IFACE); - InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mTetherHelper); + InOrder usbTeardownOrder = inOrder(mNMService, mInterfaceConfiguration, mCallback); usbTeardownOrder.verify(mInterfaceConfiguration).setInterfaceDown(); usbTeardownOrder.verify(mNMService).setInterfaceConfig(IFACE_NAME, mInterfaceConfiguration); - usbTeardownOrder.verify(mTetherHelper).updateInterfaceState( - mTestedSm, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR); - usbTeardownOrder.verify(mTetherHelper).updateLinkProperties( - eq(mTestedSm), mLinkPropertiesCaptor.capture()); + usbTeardownOrder.verify(mCallback).updateInterfaceState( + mIpServer, STATE_AVAILABLE, TETHER_ERROR_ENABLE_NAT_ERROR); + usbTeardownOrder.verify(mCallback).updateLinkProperties( + eq(mIpServer), mLinkPropertiesCaptor.capture()); assertNoAddressesNorRoutes(mLinkPropertiesCaptor.getValue()); } @@ -372,11 +370,11 @@ public class TetherInterfaceStateMachineTest { public void ignoresDuplicateUpstreamNotifications() throws Exception { initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); for (int i = 0; i < 5; i++) { dispatchTetherConnectionChanged(UPSTREAM_IFACE); - verifyNoMoreInteractions(mNMService, mStatsService, mTetherHelper); + verifyNoMoreInteractions(mNMService, mStatsService, mCallback); } } @@ -401,11 +399,11 @@ public class TetherInterfaceStateMachineTest { initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */); dispatchTetherConnectionChanged(UPSTREAM_IFACE); - verify(mTetheringDependencies, never()).makeDhcpServer(any(), any(), any(), any()); + verify(mDependencies, never()).makeDhcpServer(any(), any(), any(), any()); } private void assertDhcpStarted(IpPrefix expectedPrefix) { - verify(mTetheringDependencies, times(1)).makeDhcpServer( + verify(mDependencies, times(1)).makeDhcpServer( eq(mLooper.getLooper()), eq(TEST_IFACE_PARAMS), any(), eq(mSharedLog)); verify(mDhcpServer, times(1)).start(); final DhcpServingParams params = mDhcpParamsCaptor.getValue(); @@ -422,21 +420,21 @@ public class TetherInterfaceStateMachineTest { /** * Send a command to the state machine under test, and run the event loop to idle. * - * @param command One of the TetherInterfaceStateMachine.CMD_* constants. + * @param command One of the IpServer.CMD_* constants. * @param arg1 An additional argument to pass. */ private void dispatchCommand(int command, int arg1) { - mTestedSm.sendMessage(command, arg1); + mIpServer.sendMessage(command, arg1); mLooper.dispatchAll(); } /** * Send a command to the state machine under test, and run the event loop to idle. * - * @param command One of the TetherInterfaceStateMachine.CMD_* constants. + * @param command One of the IpServer.CMD_* constants. */ private void dispatchCommand(int command) { - mTestedSm.sendMessage(command); + mIpServer.sendMessage(command); mLooper.dispatchAll(); } @@ -447,7 +445,7 @@ public class TetherInterfaceStateMachineTest { * @param upstreamIface String name of upstream interface (or null) */ private void dispatchTetherConnectionChanged(String upstreamIface) { - mTestedSm.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED, + mIpServer.sendMessage(IpServer.CMD_TETHER_CONNECTION_CHANGED, new InterfaceSet(upstreamIface)); mLooper.dispatchAll(); } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 0d3b8e4a0452..40d5544dccd8 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -75,6 +75,7 @@ import android.net.NetworkRequest; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.RouteInfo; +import android.net.ip.IpServer; import android.net.ip.RouterAdvertisementDaemon; import android.net.util.InterfaceParams; import android.net.util.NetworkConstants; @@ -99,10 +100,8 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.StateMachine; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; -import com.android.server.connectivity.tethering.IControlsTethering; import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; import com.android.server.connectivity.tethering.OffloadHardwareInterface; -import com.android.server.connectivity.tethering.TetherInterfaceStateMachine; import com.android.server.connectivity.tethering.TetheringDependencies; import com.android.server.connectivity.tethering.UpstreamNetworkMonitor; @@ -190,7 +189,7 @@ public class TetheringTest { public class MockTetheringDependencies extends TetheringDependencies { StateMachine upstreamNetworkMonitorMasterSM; - ArrayList<TetherInterfaceStateMachine> ipv6CoordinatorNotifyList; + ArrayList<IpServer> ipv6CoordinatorNotifyList; int isTetheringSupportedCalls; public void reset() { @@ -213,29 +212,35 @@ public class TetheringTest { @Override public IPv6TetheringCoordinator getIPv6TetheringCoordinator( - ArrayList<TetherInterfaceStateMachine> notifyList, SharedLog log) { + ArrayList<IpServer> notifyList, SharedLog log) { ipv6CoordinatorNotifyList = notifyList; return mIPv6TetheringCoordinator; } @Override - public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) { - return mRouterAdvertisementDaemon; - } - - @Override - public INetd getNetdService() { - return mNetd; - } - - @Override - public InterfaceParams getInterfaceParams(String ifName) { - final String[] ifaces = new String[] { TEST_USB_IFNAME, TEST_WLAN_IFNAME, - TEST_MOBILE_IFNAME }; - final int index = ArrayUtils.indexOf(ifaces, ifName); - assertTrue("Non-mocked interface: " + ifName, index >= 0); - return new InterfaceParams(ifName, index + IFINDEX_OFFSET, - MacAddress.ALL_ZEROS_ADDRESS); + public IpServer.Dependencies getIpServerDependencies() { + return new IpServer.Dependencies() { + @Override + public RouterAdvertisementDaemon getRouterAdvertisementDaemon( + InterfaceParams ifParams) { + return mRouterAdvertisementDaemon; + } + + @Override + public InterfaceParams getInterfaceParams(String ifName) { + final String[] ifaces = new String[] { + TEST_USB_IFNAME, TEST_WLAN_IFNAME, TEST_MOBILE_IFNAME }; + final int index = ArrayUtils.indexOf(ifaces, ifName); + assertTrue("Non-mocked interface: " + ifName, index >= 0); + return new InterfaceParams(ifName, index + IFINDEX_OFFSET, + MacAddress.ALL_ZEROS_ADDRESS); + } + + @Override + public INetd getNetdService() { + return mNetd; + } + }; } @Override @@ -458,9 +463,9 @@ public class TetheringTest { sendWifiApStateChanged(WIFI_AP_STATE_ENABLED); mLooper.dispatchAll(); - // If, and only if, Tethering received an interface status changed - // then it creates a TetherInterfaceStateMachine and sends out a - // broadcast indicating that the interface is "available". + // If, and only if, Tethering received an interface status changed then + // it creates a IpServer and sends out a broadcast indicating that the + // interface is "available". if (emulateInterfaceStatusChanged) { assertEquals(1, mTetheringDependencies.isTetheringSupportedCalls); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_AVAILABLE_TETHER); @@ -557,18 +562,18 @@ public class TetheringTest { } /** - * Send CMD_IPV6_TETHER_UPDATE to TISMs as would be done by IPv6TetheringCoordinator. + * Send CMD_IPV6_TETHER_UPDATE to IpServers as would be done by IPv6TetheringCoordinator. */ private void sendIPv6TetherUpdates(NetworkState upstreamState) { // IPv6TetheringCoordinator must have been notified of downstream verify(mIPv6TetheringCoordinator, times(1)).addActiveDownstream( argThat(sm -> sm.linkProperties().getInterfaceName().equals(TEST_USB_IFNAME)), - eq(IControlsTethering.STATE_TETHERED)); + eq(IpServer.STATE_TETHERED)); - for (TetherInterfaceStateMachine tism : + for (IpServer ipSrv : mTetheringDependencies.ipv6CoordinatorNotifyList) { NetworkState ipv6OnlyState = buildMobileUpstreamState(false, true, false); - tism.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, + ipSrv.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, upstreamState.linkProperties.isIPv6Provisioned() ? ipv6OnlyState.linkProperties : null); @@ -812,7 +817,7 @@ public class TetheringTest { // We verify get/set called thrice here: once for setup and twice during // teardown because all events happen over the course of the single - // dispatchAll() above. Note that once the TISM IPv4 address config + // dispatchAll() above. Note that once the IpServer IPv4 address config // code is refactored the two calls during shutdown will revert to one. verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); verify(mNMService, times(3)) diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh index bdcc8076dde1..76a2f2d6eba1 100755 --- a/tools/hiddenapi/sort_api.sh +++ b/tools/hiddenapi/sort_api.sh @@ -12,8 +12,8 @@ readarray A < "$source_list" # Sort IFS=$'\n' # Stash away comments -C=( $(grep -E '^#' <<< "${A[*]}") ) -A=( $(grep -v -E '^#' <<< "${A[*]}") ) +C=( $(grep -E '^#' <<< "${A[*]}" || :) ) +A=( $(grep -v -E '^#' <<< "${A[*]}" || :) ) # Sort entries A=( $(LC_COLLATE=C sort -f <<< "${A[*]}") ) A=( $(uniq <<< "${A[*]}") ) |