diff options
267 files changed, 6579 insertions, 1793 deletions
diff --git a/Android.bp b/Android.bp index 42c2b217e5cf..e2b432cdd8cd 100644 --- a/Android.bp +++ b/Android.bp @@ -506,11 +506,14 @@ java_defaults { "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl", "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl", "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl", + "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl", "telephony/java/android/telephony/mbms/IDownloadStatusListener.aidl", "telephony/java/android/telephony/mbms/IDownloadProgressListener.aidl", "telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl", + "telephony/java/android/telephony/mbms/IGroupCallCallback.aidl", "telephony/java/android/telephony/mbms/vendor/IMbmsDownloadService.aidl", "telephony/java/android/telephony/mbms/vendor/IMbmsStreamingService.aidl", + "telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl", "telephony/java/android/telephony/INetworkService.aidl", "telephony/java/android/telephony/INetworkServiceCallback.aidl", "telephony/java/com/android/ims/internal/IImsCallSession.aidl", @@ -795,7 +798,7 @@ gensrcs { java_library { name: "ext", installable: true, - no_framework_libs: true, + sdk_version: "core_current", static_libs: [ "libphonenumber-platform", "nist-sip", @@ -1216,6 +1219,11 @@ stubs_defaults { "metalava-manual", "ojluni-annotated-sdk-stubs", ], + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], } droidstubs { @@ -1262,6 +1270,9 @@ droiddoc { } droiddoc { + // Please sync with android-api-council@ before making any changes for the name property below. + // Since there's cron jobs that fetch offline-sdk-referenceonly-docs-docs.zip periodically. + // See b/116221385 for reference. name: "offline-sdk-referenceonly-docs", defaults: ["framework-docs-default"], srcs: [ @@ -1278,6 +1289,9 @@ droiddoc { } droiddoc { + // Please sync with android-api-council@ before making any changes for the name property below. + // Since there's cron jobs that fetch offline-system-sdk-referenceonly-docs-docs.zip periodically. + // See b/116221385 for reference. name: "offline-system-sdk-referenceonly-docs", defaults: ["framework-docs-default"], srcs: [ @@ -1571,6 +1585,7 @@ droidstubs { removed_api_file: "api/removed.txt", }, }, + jdiff_enabled: true, } droidstubs { @@ -1595,6 +1610,7 @@ droidstubs { removed_api_file: "api/system-removed.txt", }, }, + jdiff_enabled: true, } droidstubs { diff --git a/Android.mk b/Android.mk index 73c0233be076..d33307425968 100644 --- a/Android.mk +++ b/Android.mk @@ -53,262 +53,10 @@ $(gen): $(aidl_parcelables) cat $^ | sort -u > $@.tmp $(call commit-change-for-toc,$@) -# the documentation -# ============================================================ - -# TODO: deal with com/google/android/googleapps -packages_to_document := \ - android \ - javax/microedition/khronos \ - org/apache/http/conn \ - org/apache/http/params \ - -# include definition of libcore_to_document -include libcore/Docs.mk - -non_base_dirs := \ - ../opt/telephony/src/java/android/telephony \ - ../opt/telephony/src/java/android/telephony/gsm \ - ../opt/net/voip/src/java/android/net/rtp \ - ../opt/net/voip/src/java/android/net/sip \ - -# Find all files in specific directories (relative to frameworks/base) -# to document and check apis -files_to_check_apis := \ - $(call find-other-java-files, \ - $(non_base_dirs) \ - ) - -# Find all files in specific packages that were used to compile -# framework.jar to document and check apis -files_to_check_apis += \ - $(addprefix ../../,\ - $(filter \ - $(foreach dir,$(FRAMEWORKS_BASE_JAVA_SRC_DIRS),\ - $(foreach package,$(packages_to_document),\ - $(dir)/$(package)/%.java)),\ - $(SOONG_FRAMEWORK_SRCS))) - -# Find all generated files that were used to compile framework.jar -files_to_check_apis_generated := \ - $(filter $(OUT_DIR)/%,\ - $(SOONG_FRAMEWORK_SRCS)) - -# These are relative to frameworks/base -# FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk -files_to_document := \ - $(files_to_check_apis) \ - $(call find-other-java-files,\ - test-base/src \ - test-mock/src \ - test-runner/src) - -# These are relative to frameworks/base -html_dirs := \ - $(FRAMEWORKS_BASE_SUBDIRS) \ - $(non_base_dirs) \ - -# Common sources for doc check and api check -common_src_files := \ - $(call find-other-html-files, $(html_dirs)) \ - $(addprefix ../../, $(libcore_to_document)) \ - -# These are relative to frameworks/base -framework_docs_LOCAL_SRC_FILES := \ - $(files_to_document) \ - $(common_src_files) \ - -# These are relative to frameworks/base -framework_docs_LOCAL_API_CHECK_SRC_FILES := \ - $(files_to_check_apis) \ - $(common_src_files) \ - # This is used by ide.mk as the list of source files that are # always included. INTERNAL_SDK_SOURCE_DIRS := $(addprefix $(LOCAL_PATH)/,$(dirs_to_document)) -framework_docs_LOCAL_DROIDDOC_SOURCE_PATH := \ - $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) - -framework_docs_LOCAL_SRCJARS := $(SOONG_FRAMEWORK_SRCJARS) - -framework_docs_LOCAL_GENERATED_SOURCES := \ - $(libcore_to_document_generated) \ - $(files_to_check_apis_generated) \ - -framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES := \ - core-oj \ - core-libart \ - conscrypt \ - bouncycastle \ - okhttp \ - ext \ - framework \ - voip-common \ - -# Platform docs can refer to Support Library APIs, but we don't actually build -# them as part of the docs target, so we need to include them on the classpath. -framework_docs_LOCAL_JAVA_LIBRARIES := \ - $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES) \ - $(FRAMEWORKS_SUPPORT_JAVA_LIBRARIES) - -framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES -framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html -# The since flag (-since N.xml API_LEVEL) is used to add API Level information -# to the reference documentation. Must be in order of oldest to newest. -# -# Conscrypt (com.android.org.conscrypt) is an implementation detail and should -# not be referenced in the documentation. -framework_docs_LOCAL_DROIDDOC_OPTIONS := \ - -android \ - -knowntags ./frameworks/base/docs/knowntags.txt \ - -knowntags ./libcore/known_oj_tags.txt \ - -manifest ./frameworks/base/core/res/AndroidManifest.xml \ - -hidePackage com.android.internal \ - -hidePackage com.android.internal.util \ - -hidePackage com.android.okhttp \ - -hidePackage com.android.org.conscrypt \ - -hidePackage com.android.server - -# Convert an sdk level to a "since" argument. -since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.$(2)) $(1) - -finalized_xml_sdks := $(call numerically_sort,\ - $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\ - $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml))) -finalized_txt_sdks := $(call numerically_sort,\ - $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\ - $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt))) - -framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_xml_sdks),$(call since-arg,$(sdk),xml)) -framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_txt_sdks),$(call since-arg,$(sdk),txt)) -ifneq ($(PLATFORM_VERSION_CODENAME),REL) - framework_docs_LOCAL_DROIDDOC_OPTIONS += \ - -since ./frameworks/base/api/current.txt $(PLATFORM_VERSION_CODENAME) -endif -framework_docs_LOCAL_DROIDDOC_OPTIONS += \ - -werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \ - -overview $(LOCAL_PATH)/core/java/overview.html - -framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \ - $(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON) - -framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \ - $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) - -framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES := \ - frameworks/base/docs/knowntags.txt \ - $(libcore_to_document_generated) - -samples_dir := development/samples/browseable - -# Whitelist of valid groups, used for default TOC grouping. Each sample must -# belong to one (and only one) group. Assign samples to groups by setting -# a sample.group var to one of these groups in the sample's _index.jd. -sample_groups := -samplegroup Admin \ - -samplegroup Background \ - -samplegroup Connectivity \ - -samplegroup Content \ - -samplegroup Input \ - -samplegroup Media \ - -samplegroup Notification \ - -samplegroup RenderScript \ - -samplegroup Security \ - -samplegroup Sensors \ - -samplegroup System \ - -samplegroup Testing \ - -samplegroup UI \ - -samplegroup Views \ - -samplegroup Wearable - -## SDK version identifiers used in the published docs - # major[.minor] version for current SDK. (full releases only) -framework_docs_SDK_VERSION:=7.0 - # release version (ie "Release x") (full releases only) -framework_docs_SDK_REL_ID:=1 - -framework_docs_LOCAL_DROIDDOC_OPTIONS += \ - -hdf dac true \ - -hdf sdk.codename O \ - -hdf sdk.preview.version 1 \ - -hdf sdk.version $(framework_docs_SDK_VERSION) \ - -hdf sdk.rel.id $(framework_docs_SDK_REL_ID) \ - -hdf sdk.preview 0 \ - -resourcesdir $(LOCAL_PATH)/docs/html/reference/images/ \ - -resourcesoutdir reference/android/images/ - -# Federate Support Library references against local API file. -framework_docs_LOCAL_DROIDDOC_OPTIONS += \ - -federate SupportLib https://developer.android.com \ - -federationapi SupportLib prebuilts/sdk/current/support-api.txt - -# Federate AndroidX references against local API file. -framework_docs_LOCAL_DROIDDOC_OPTIONS += \ - -federate AndroidX https://developer.android.com \ - -federationapi AndroidX prebuilts/sdk/current/androidx-api.txt - -# Get the highest numbered api txt for the given api level. -# $(1): the api level (e.g. public, system) -define highest_sdk_txt -$(HISTORICAL_SDK_VERSIONS_ROOT)/$(lastword $(call numerically_sort, \ - $(patsubst \ - $(HISTORICAL_SDK_VERSIONS_ROOT)/%,\ - %,\ - $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/$(1)/api/android.txt)\ - ) \ -)) -endef - -# ==== Public API diff =========================== -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES) -LOCAL_GENERATED_SOURCES := $(framework_docs_LOCAL_GENERATED_SOURCES) -LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS) -LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES) -LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS) -LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) -LOCAL_ADDITIONAL_DEPENDENCIES := \ - $(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES) \ - $(INTERNAL_PLATFORM_API_FILE) - -LOCAL_MODULE := offline-sdk-referenceonly - -# Basename, because apidiff adds .txt internally. -LOCAL_APIDIFF_OLDAPI := $(basename $(call highest_sdk_txt,public)) -LOCAL_APIDIFF_NEWAPI := $(LOCAL_PATH)/../../$(basename $(INTERNAL_PLATFORM_API_FILE)) - -include $(BUILD_APIDIFF) - -# Hack to get diffs included in docs output -out_zip := $(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip -$(out_zip): $(full_target) - -# ==== System API diff =========================== -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(framework_docs_LOCAL_API_CHECK_SRC_FILES) -LOCAL_GENERATED_SOURCES := $(framework_docs_LOCAL_GENERATED_SOURCES) -LOCAL_SRCJARS:=$(framework_docs_LOCAL_SRCJARS) -LOCAL_JAVA_LIBRARIES := $(framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES) -LOCAL_MODULE_CLASS := $(framework_docs_LOCAL_MODULE_CLASS) -LOCAL_ADDITIONAL_JAVA_DIR := $(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) -LOCAL_ADDITIONAL_DEPENDENCIES := \ - $(framework_docs_LOCAL_ADDITIONAL_DEPENDENCIES) \ - $(INTERNAL_PLATFORM_SYSTEM_API_FILE) - -LOCAL_MODULE := offline-system-sdk-referenceonly - -# Basename, because apidiff adds .txt internally. -LOCAL_APIDIFF_OLDAPI := $(basename $(call highest_sdk_txt,system)) -LOCAL_APIDIFF_NEWAPI := $(LOCAL_PATH)/../../$(basename $(INTERNAL_PLATFORM_SYSTEM_API_FILE)) - -include $(BUILD_APIDIFF) - -# Hack to get diffs included in docs output -out_zip := $(OUT_DOCS)/$(LOCAL_MODULE)-docs.zip -$(out_zip): $(full_target) - $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_API_FILE)) $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_SYSTEM_API_FILE)) $(call dist-for-goals,sdk,$(INTERNAL_PLATFORM_TEST_API_FILE)) diff --git a/api/current.txt b/api/current.txt index 955b13b8c018..93fcf3b80a56 100755 --- a/api/current.txt +++ b/api/current.txt @@ -18486,6 +18486,114 @@ package android.icu.text { method public java.lang.CharSequence getName(); } + public class Bidi { + ctor public Bidi(); + ctor public Bidi(int, int); + ctor public Bidi(java.lang.String, int); + ctor public Bidi(java.text.AttributedCharacterIterator); + ctor public Bidi(char[], int, byte[], int, int, int); + method public boolean baseIsLeftToRight(); + method public int countParagraphs(); + method public int countRuns(); + method public android.icu.text.Bidi createLineBidi(int, int); + method public static byte getBaseDirection(java.lang.CharSequence); + method public int getBaseLevel(); + method public android.icu.text.BidiClassifier getCustomClassifier(); + method public int getCustomizedClass(int); + method public byte getDirection(); + method public int getLength(); + method public byte getLevelAt(int); + method public byte[] getLevels(); + method public int getLogicalIndex(int); + method public int[] getLogicalMap(); + method public android.icu.text.BidiRun getLogicalRun(int); + method public byte getParaLevel(); + method public android.icu.text.BidiRun getParagraph(int); + method public android.icu.text.BidiRun getParagraphByIndex(int); + method public int getParagraphIndex(int); + method public int getProcessedLength(); + method public int getReorderingMode(); + method public int getReorderingOptions(); + method public int getResultLength(); + method public int getRunCount(); + method public int getRunLevel(int); + method public int getRunLimit(int); + method public int getRunStart(int); + method public char[] getText(); + method public java.lang.String getTextAsString(); + method public int getVisualIndex(int); + method public int[] getVisualMap(); + method public android.icu.text.BidiRun getVisualRun(int); + method public static int[] invertMap(int[]); + method public boolean isInverse(); + method public boolean isLeftToRight(); + method public boolean isMixed(); + method public boolean isOrderParagraphsLTR(); + method public boolean isRightToLeft(); + method public void orderParagraphsLTR(boolean); + method public static int[] reorderLogical(byte[]); + method public static int[] reorderVisual(byte[]); + method public static void reorderVisually(byte[], int, java.lang.Object[], int, int); + method public static boolean requiresBidi(char[], int, int); + method public void setContext(java.lang.String, java.lang.String); + method public void setCustomClassifier(android.icu.text.BidiClassifier); + method public void setInverse(boolean); + method public android.icu.text.Bidi setLine(int, int); + method public void setPara(java.lang.String, byte, byte[]); + method public void setPara(char[], byte, byte[]); + method public void setPara(java.text.AttributedCharacterIterator); + method public void setReorderingMode(int); + method public void setReorderingOptions(int); + method public java.lang.String writeReordered(int); + method public static java.lang.String writeReverse(java.lang.String, int); + field public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = 126; // 0x7e + field public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = 127; // 0x7f + field public static final int DIRECTION_LEFT_TO_RIGHT = 0; // 0x0 + field public static final int DIRECTION_RIGHT_TO_LEFT = 1; // 0x1 + field public static final short DO_MIRRORING = 2; // 0x2 + field public static final short INSERT_LRM_FOR_NUMERIC = 4; // 0x4 + field public static final short KEEP_BASE_COMBINING = 1; // 0x1 + field public static final byte LEVEL_DEFAULT_LTR = 126; // 0x7e + field public static final byte LEVEL_DEFAULT_RTL = 127; // 0x7f + field public static final byte LEVEL_OVERRIDE = -128; // 0xffffff80 + field public static final byte LTR = 0; // 0x0 + field public static final int MAP_NOWHERE = -1; // 0xffffffff + field public static final byte MAX_EXPLICIT_LEVEL = 125; // 0x7d + field public static final byte MIXED = 2; // 0x2 + field public static final byte NEUTRAL = 3; // 0x3 + field public static final int OPTION_DEFAULT = 0; // 0x0 + field public static final int OPTION_INSERT_MARKS = 1; // 0x1 + field public static final int OPTION_REMOVE_CONTROLS = 2; // 0x2 + field public static final int OPTION_STREAMING = 4; // 0x4 + field public static final short OUTPUT_REVERSE = 16; // 0x10 + field public static final short REMOVE_BIDI_CONTROLS = 8; // 0x8 + field public static final short REORDER_DEFAULT = 0; // 0x0 + field public static final short REORDER_GROUP_NUMBERS_WITH_R = 2; // 0x2 + field public static final short REORDER_INVERSE_FOR_NUMBERS_SPECIAL = 6; // 0x6 + field public static final short REORDER_INVERSE_LIKE_DIRECT = 5; // 0x5 + field public static final short REORDER_INVERSE_NUMBERS_AS_L = 4; // 0x4 + field public static final short REORDER_NUMBERS_SPECIAL = 1; // 0x1 + field public static final short REORDER_RUNS_ONLY = 3; // 0x3 + field public static final byte RTL = 1; // 0x1 + } + + public class BidiClassifier { + ctor public BidiClassifier(java.lang.Object); + method public int classify(int); + method public java.lang.Object getContext(); + method public void setContext(java.lang.Object); + } + + public class BidiRun { + method public byte getDirection(); + method public byte getEmbeddingLevel(); + method public int getLength(); + method public int getLimit(); + method public int getStart(); + method public boolean isEvenRun(); + method public boolean isOddRun(); + } + public abstract class BreakIterator implements java.lang.Cloneable { ctor protected BreakIterator(); method public java.lang.Object clone(); @@ -26987,6 +27095,7 @@ package android.net { method public android.net.Network[] getAllNetworks(); method public deprecated boolean getBackgroundDataSetting(); method public android.net.Network getBoundNetworkForProcess(); + method public int getConnectionOwnerUid(int, java.net.InetSocketAddress, java.net.InetSocketAddress); method public android.net.ProxyInfo getDefaultProxy(); method public android.net.LinkProperties getLinkProperties(android.net.Network); method public int getMultipathPreference(android.net.Network); @@ -33113,6 +33222,7 @@ package android.os { method public static final void setThreadPriority(int) throws java.lang.IllegalArgumentException, java.lang.SecurityException; method public static final deprecated boolean supportsProcesses(); field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710 + field public static final int INVALID_UID = -1; // 0xffffffff field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f field public static final int PHONE_UID = 1001; // 0x3e9 field public static final int SIGNAL_KILL = 9; // 0x9 @@ -40925,6 +41035,7 @@ package android.telecom { field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80 field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10 field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40 + field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800 field public static final int PROPERTY_RTT = 1024; // 0x400 field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100 field public static final int PROPERTY_WIFI = 8; // 0x8 @@ -40962,8 +41073,9 @@ package android.telecom { public abstract class CallRedirectionService extends android.app.Service { ctor public CallRedirectionService(); method public final void cancelCall(); - method public android.os.IBinder onBind(android.content.Intent); + method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onPlaceCall(android.net.Uri, android.telecom.PhoneAccountHandle); + method public final boolean onUnbind(android.content.Intent); method public final void placeCallUnmodified(); method public final void redirectCall(android.net.Uri, android.telecom.PhoneAccountHandle); field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.CallRedirectionService"; @@ -41579,6 +41691,7 @@ package android.telecom { field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE"; + field public static final java.lang.String EXTRA_CALL_NETWORK_TYPE = "android.telecom.extra.CALL_NETWORK_TYPE"; field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME"; field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS"; @@ -41876,6 +41989,7 @@ package android.telephony { field public static final deprecated java.lang.String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool"; field public static final java.lang.String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool"; field public static final java.lang.String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool"; + field public static final java.lang.String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool"; field public static final java.lang.String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool"; field public static final java.lang.String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool"; field public static final java.lang.String KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL = "show_onscreen_dial_button_bool"; @@ -42137,6 +42251,13 @@ package android.telephony { field public static final int STATUS_UNKNOWN = 0; // 0x0 } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + method public void close(); + method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsGroupCallSessionCallback); + method public static android.telephony.MbmsGroupCallSession create(android.content.Context, java.util.concurrent.Executor, android.telephony.mbms.MbmsGroupCallSessionCallback); + method public android.telephony.mbms.GroupCall startGroupCall(java.util.concurrent.Executor, long, int[], int[], android.telephony.mbms.GroupCallCallback); + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { method public void close(); method public static android.telephony.MbmsStreamingSession create(android.content.Context, java.util.concurrent.Executor, int, android.telephony.mbms.MbmsStreamingSessionCallback); @@ -42145,7 +42266,7 @@ package android.telephony { method public android.telephony.mbms.StreamingService startStreaming(android.telephony.mbms.StreamingServiceInfo, java.util.concurrent.Executor, android.telephony.mbms.StreamingServiceCallback); } - public class NeighboringCellInfo implements android.os.Parcelable { + public deprecated class NeighboringCellInfo implements android.os.Parcelable { ctor public deprecated NeighboringCellInfo(); ctor public deprecated NeighboringCellInfo(int, int); ctor public NeighboringCellInfo(int, java.lang.String, int); @@ -42516,6 +42637,7 @@ package android.telephony { method public static int getDefaultVoiceSubscriptionId(); method public static int[] getSubscriptionIds(int); method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int); + method public boolean isActiveSubscriptionId(int); method public boolean isNetworkRoaming(int); method public static boolean isValidSubscriptionId(int); method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); @@ -42601,7 +42723,6 @@ package android.telephony { method public java.lang.String getMmsUAProfUrl(); method public java.lang.String getMmsUserAgent(); method public java.lang.String getNai(); - method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo(); method public java.lang.String getNetworkCountryIso(); method public java.lang.String getNetworkOperator(); method public java.lang.String getNetworkOperatorName(); @@ -43082,6 +43203,29 @@ package android.telephony.mbms { field public static final android.os.Parcelable.Creator<android.telephony.mbms.FileServiceInfo> CREATOR; } + public class GroupCall implements java.lang.AutoCloseable { + method public void close(); + method public long getTmgi(); + method public void updateGroupCall(int[], int[]); + field public static final int REASON_BY_USER_REQUEST = 1; // 0x1 + field public static final int REASON_FREQUENCY_CONFLICT = 3; // 0x3 + field public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; // 0x6 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; // 0x5 + field public static final int REASON_OUT_OF_MEMORY = 4; // 0x4 + field public static final int STATE_STALLED = 3; // 0x3 + field public static final int STATE_STARTED = 2; // 0x2 + field public static final int STATE_STOPPED = 1; // 0x1 + } + + public class GroupCallCallback { + ctor public GroupCallCallback(); + method public void onBroadcastSignalStrengthUpdated(int); + method public void onError(int, java.lang.String); + method public void onGroupCallStateChanged(int, int); + field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff + } + public class MbmsDownloadReceiver extends android.content.BroadcastReceiver { ctor public MbmsDownloadReceiver(); method public void onReceive(android.content.Context, android.content.Intent); @@ -43130,6 +43274,14 @@ package android.telephony.mbms { field public static final int ERROR_UNABLE_TO_START_SERVICE = 302; // 0x12e } + public class MbmsGroupCallSessionCallback { + ctor public MbmsGroupCallSessionCallback(); + method public void onAvailableSaisUpdated(java.util.List<java.lang.Integer>, java.util.List<java.util.List<java.lang.Integer>>); + method public void onError(int, java.lang.String); + method public void onMiddlewareReady(); + method public void onServiceInterfaceAvailable(java.lang.String, int); + } + public class MbmsStreamingSessionCallback { ctor public MbmsStreamingSessionCallback(); method public void onError(int, java.lang.String); @@ -54721,6 +54873,7 @@ package dalvik.system { public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader { ctor public DelegateLastClassLoader(java.lang.String, java.lang.ClassLoader); ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader); + ctor public DelegateLastClassLoader(java.lang.String, java.lang.String, java.lang.ClassLoader, boolean); } public class DexClassLoader extends dalvik.system.BaseDexClassLoader { diff --git a/api/removed.txt b/api/removed.txt index f35348ec8bfd..fba5187929fd 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -540,6 +540,7 @@ package android.telephony { } public class TelephonyManager { + method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo(); method public deprecated android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, android.telephony.TelephonyScanManager.NetworkScanCallback); } diff --git a/api/system-current.txt b/api/system-current.txt index 1df9a466ddc7..fd5aa7b59741 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5048,6 +5048,7 @@ package android.telecom { method public deprecated android.content.ComponentName getDefaultPhoneApp(); method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage(); method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String); + method public boolean isInEmergencyCall(); method public boolean isRinging(); method public boolean isTtySupported(); field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT"; @@ -5074,6 +5075,10 @@ package android.telephony { field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload"; } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_ACTION = "android.telephony.action.EmbmsGroupCall"; + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { field public static final java.lang.String MBMS_STREAMING_SERVICE_ACTION = "android.telephony.action.EmbmsStreaming"; } @@ -5133,9 +5138,12 @@ package android.telephony { } public class ServiceState implements android.os.Parcelable { + method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int); method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(); - method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(int); - method public android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int); + method public deprecated java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(int); + method public deprecated android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int); + method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int); + method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int); } public final class SmsManager { @@ -5230,7 +5238,6 @@ package android.telephony { } public class TelephonyManager { - method public deprecated void answerRingingCall(); method public deprecated void call(java.lang.String, java.lang.String); method public int checkCarrierPrivilegesForPackage(java.lang.String); method public int checkCarrierPrivilegesForPackageAnyPhone(java.lang.String); @@ -5238,7 +5245,7 @@ package android.telephony { method public boolean disableDataConnectivity(); method public boolean enableDataConnectivity(); method public void enableVideoCalling(boolean); - method public deprecated boolean endCall(); + method public java.lang.String getAidForAppType(int); method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); @@ -5253,6 +5260,8 @@ package android.telephony { method public deprecated boolean getDataEnabled(); method public deprecated boolean getDataEnabled(int); method public boolean getEmergencyCallbackMode(); + method public java.lang.String getIsimDomain(); + method public int getPreferredNetworkType(int); method public int getSimApplicationState(); method public int getSimCardState(); method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms(); @@ -5262,10 +5271,7 @@ package android.telephony { method public boolean handlePinMmi(java.lang.String); method public boolean handlePinMmiForSubscriber(int, java.lang.String); method public boolean isDataConnectivityPossible(); - method public deprecated boolean isIdle(); - method public deprecated boolean isOffhook(); method public deprecated boolean isRadioOn(); - method public deprecated boolean isRinging(); method public boolean isVideoCallingEnabled(); method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); method public boolean needsOtaServiceProvisioning(); @@ -5279,7 +5285,6 @@ package android.telephony { method public void setSimPowerStateForSlot(int, int); method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean); method public void setVoiceActivationState(int); - method public deprecated void silenceRinger(); method public boolean supplyPin(java.lang.String); method public int[] supplyPinReportResult(java.lang.String); method public boolean supplyPuk(java.lang.String, java.lang.String); @@ -5297,6 +5302,29 @@ package android.telephony { field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; + field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4 + field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5 + field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6 + field public static final int NETWORK_MODE_GLOBAL = 7; // 0x7 + field public static final int NETWORK_MODE_GSM_ONLY = 1; // 0x1 + field public static final int NETWORK_MODE_GSM_UMTS = 3; // 0x3 + field public static final int NETWORK_MODE_LTE_CDMA_EVDO = 8; // 0x8 + field public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; // 0xa + field public static final int NETWORK_MODE_LTE_GSM_WCDMA = 9; // 0x9 + field public static final int NETWORK_MODE_LTE_ONLY = 11; // 0xb + field public static final int NETWORK_MODE_LTE_TDSCDMA = 15; // 0xf + field public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; // 0x16 + field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = 17; // 0x11 + field public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = 20; // 0x14 + field public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = 19; // 0x13 + field public static final int NETWORK_MODE_LTE_WCDMA = 12; // 0xc + field public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 21; // 0x15 + field public static final int NETWORK_MODE_TDSCDMA_GSM = 16; // 0x10 + field public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = 18; // 0x12 + field public static final int NETWORK_MODE_TDSCDMA_ONLY = 13; // 0xd + field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe + field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2 + field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0 field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2 field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1 field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3 @@ -5632,6 +5660,7 @@ package android.telephony.ims { field public static final java.lang.String EXTRA_CODEC = "Codec"; field public static final java.lang.String EXTRA_DIALSTRING = "dialstring"; field public static final java.lang.String EXTRA_DISPLAY_TEXT = "DisplayText"; + field public static final java.lang.String EXTRA_E_CALL = "e_call"; field public static final java.lang.String EXTRA_IS_CALL_PULL = "CallPull"; field public static final java.lang.String EXTRA_OI = "oi"; field public static final java.lang.String EXTRA_OIR = "oir"; @@ -6375,6 +6404,17 @@ package android.telephony.mbms.vendor { method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException; } + public class MbmsGroupCallServiceBase extends android.app.Service { + ctor public MbmsGroupCallServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public android.os.IBinder onBind(android.content.Intent); + method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback); + method public void stopGroupCall(int, long); + method public void updateGroupCall(int, long, int[], int[]); + } + public class MbmsStreamingServiceBase extends android.os.Binder { ctor public MbmsStreamingServiceBase(); method public void dispose(int) throws android.os.RemoteException; diff --git a/api/system-removed.txt b/api/system-removed.txt index 961026b827e8..72b60e2e4db2 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -143,3 +143,16 @@ package android.service.notification { } +package android.telephony { + + public class TelephonyManager { + method public deprecated void answerRingingCall(); + method public deprecated boolean endCall(); + method public deprecated boolean isIdle(); + method public deprecated boolean isOffhook(); + method public deprecated boolean isRinging(); + method public deprecated void silenceRinger(); + } + +} + diff --git a/api/test-current.txt b/api/test-current.txt index 634293ab89e8..a7bb467e6141 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -966,6 +966,10 @@ package android.telephony { field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override"; } + public class MbmsGroupCallSession implements java.lang.AutoCloseable { + field public static final java.lang.String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = "mbms-group-call-service-override"; + } + public class MbmsStreamingSession implements java.lang.AutoCloseable { field public static final java.lang.String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override"; } @@ -1035,6 +1039,17 @@ package android.telephony.mbms.vendor { method public int setTempFileRootDirectory(int, java.lang.String) throws android.os.RemoteException; } + public class MbmsGroupCallServiceBase extends android.app.Service { + ctor public MbmsGroupCallServiceBase(); + method public void dispose(int) throws android.os.RemoteException; + method public int initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) throws android.os.RemoteException; + method public void onAppCallbackDied(int, int); + method public android.os.IBinder onBind(android.content.Intent); + method public int startGroupCall(int, long, int[], int[], android.telephony.mbms.GroupCallCallback); + method public void stopGroupCall(int, long); + method public void updateGroupCall(int, long, int[], int[]); + } + public class MbmsStreamingServiceBase extends android.os.Binder { ctor public MbmsStreamingServiceBase(); method public void dispose(int) throws android.os.RemoteException; diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 4bbe04204a54..72a41036e595 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -425,7 +425,19 @@ WorkerThreadSection::WorkerThreadSection(int id, const int64_t timeoutMs, bool u WorkerThreadSection::~WorkerThreadSection() {} +void sigpipe_handler(int signum) { + if (signum == SIGPIPE) { + ALOGE("Wrote to a broken pipe\n"); + } else { + ALOGE("Received unexpected signal: %d\n", signum); + } +} + static void* worker_thread_func(void* cookie) { + // Don't crash the service if we write to a closed pipe (which can happen if + // dumping times out). + signal(SIGPIPE, sigpipe_handler); + WorkerThreadData* data = (WorkerThreadData*)cookie; status_t err = data->section->BlockingCall(data->pipe.writeFd().get()); @@ -506,6 +518,7 @@ status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const { } } } + write_section_stats(requests->sectionStats(this->id), buffer); if (timedOut || buffer.timedOut()) { ALOGW("WorkerThreadSection '%s' timed out", this->name.string()); @@ -813,7 +826,10 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { } } gLastLogsRetrieved[mLogID] = lastTimestamp; - proto.flush(pipeWriteFd); + if (!proto.flush(pipeWriteFd) && errno == EPIPE) { + ALOGE("[%s] wrote to a broken pipe\n", this->name.string()); + return EPIPE; + } return NO_ERROR; } @@ -915,7 +931,7 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { break; } if (cStatus != NO_ERROR) { - ALOGE("TombstoneSection '%s' child had an issue: %s\n", this->name.string(), strerror(-cStatus)); + ALOGE("[%s] child had an issue: %s\n", this->name.string(), strerror(-cStatus)); } auto dump = std::make_unique<char[]>(buffer.size()); @@ -934,7 +950,13 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { dumpPipe.readFd().reset(); } - proto.flush(pipeWriteFd); + if (!proto.flush(pipeWriteFd) && errno == EPIPE) { + ALOGE("[%s] wrote to a broken pipe\n", this->name.string()); + if (err != NO_ERROR) { + return EPIPE; + } + } + return err; } diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h index a031a15fe7c9..2f89370b0d26 100644 --- a/cmds/incidentd/src/Section.h +++ b/cmds/incidentd/src/Section.h @@ -173,7 +173,7 @@ private: */ class TombstoneSection : public WorkerThreadSection { public: - TombstoneSection(int id, const char* type, int64_t timeoutMs = 30000 /* 30 seconds */); + TombstoneSection(int id, const char* type, int64_t timeoutMs = 120000 /* 2 minutes */); virtual ~TombstoneSection(); virtual status_t BlockingCall(int pipeWriteFd) const; diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 18f6a1c28086..c4824c084370 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -152,8 +152,9 @@ message Atom { Temperature temperature = 10021; } - // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above - // 100,000 are reserved for non-AOSP (e.g. OEMs) to use. + // DO NOT USE field numbers above 100,000 in AOSP. + // Field numbers 100,000 - 199,999 are reserved for non-AOSP (e.g. OEMs) to use. + // Field numbers 200,000 and above are reserved for future use; do not use them at all. } /** diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 35676059124a..9857cd072068 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -11074,6 +11074,7 @@ HPLjava/lang/Long;->formatUnsignedLong(JI[CII)I HPLjava/lang/Long;->valueOf(Ljava/lang/String;I)Ljava/lang/Long; HPLjava/lang/Math;->addExact(JJ)J HPLjava/lang/Math;->scalb(FI)F +HPLjava/lang/Object;->wait()V HPLjava/lang/StackTraceElement;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V HPLjava/lang/String;->copyValueOf([C)Ljava/lang/String; HPLjava/lang/String;->join(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/String; diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 1f4f3c2b11db..fbf5b5288928 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -2147,27 +2147,20 @@ Lcom/android/internal/telephony/ISub;->getDefaultDataSubId()I Lcom/android/internal/telephony/ISub;->getDefaultSubId()I Lcom/android/internal/telephony/ISub;->setDefaultDataSubId(I)V Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCall()Z -Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->endCallForSubscriber(I)Z Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String; Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->isRadioOn(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony$Stub$Proxy;->mRemote:Landroid/os/IBinder; Lcom/android/internal/telephony/ITelephony$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephony; Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String; -Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_answerRingingCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_call:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I -Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_endCall:I Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I -Lcom/android/internal/telephony/ITelephony;->answerRingingCall()V Lcom/android/internal/telephony/ITelephony;->call(Ljava/lang/String;Ljava/lang/String;)V Lcom/android/internal/telephony/ITelephony;->dial(Ljava/lang/String;)V Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z Lcom/android/internal/telephony/ITelephony;->disableLocationUpdates()V Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z Lcom/android/internal/telephony/ITelephony;->enableLocationUpdates()V -Lcom/android/internal/telephony/ITelephony;->endCall()Z -Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I Lcom/android/internal/telephony/ITelephony;->getCallState()I Lcom/android/internal/telephony/ITelephony;->getDataActivity()I @@ -2179,12 +2172,8 @@ Lcom/android/internal/telephony/ITelephony;->handlePinMmiForSubscriber(ILjava/la Lcom/android/internal/telephony/ITelephony;->hasIccCard()Z Lcom/android/internal/telephony/ITelephony;->iccCloseLogicalChannel(II)Z Lcom/android/internal/telephony/ITelephony;->iccTransmitApduLogicalChannel(IIIIIIILjava/lang/String;)Ljava/lang/String; -Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z -Lcom/android/internal/telephony/ITelephony;->isIdleForSubscriber(ILjava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->isRadioOnForSubscriber(ILjava/lang/String;)Z -Lcom/android/internal/telephony/ITelephony;->isRinging(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z -Lcom/android/internal/telephony/ITelephony;->silenceRinger()V Lcom/android/internal/telephony/ITelephony;->supplyPin(Ljava/lang/String;)Z Lcom/android/internal/telephony/ITelephony;->toggleRadioOnOff()V Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V @@ -2298,6 +2287,7 @@ Lcom/android/org/conscrypt/OpenSSLKey;-><init>(J)V Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey; Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY; Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey; +Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String; diff --git a/config/preloaded-classes b/config/preloaded-classes index 63c583f9264c..d93befdf5143 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -2381,7 +2381,6 @@ android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ android.os.-$$Lambda$StrictMode$yZJXPvy2veRNA-xL_SWdXzX_OLg android.os.-$$Lambda$Trace$2zLZ-Lc2kAXsVjw_nLYeNhqmGq0 android.os.AsyncResult -android.os.AsyncTask android.os.AsyncTask$1 android.os.AsyncTask$2 android.os.AsyncTask$3 diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist index 8b8d640a543b..eca3bf3e47fe 100644 --- a/config/preloaded-classes-blacklist +++ b/config/preloaded-classes-blacklist @@ -1,4 +1,5 @@ android.net.ConnectivityThread$Singleton +android.os.AsyncTask android.os.FileObserver android.widget.Magnifier sun.nio.fs.UnixChannelFactory diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java index 183be5f38bd1..559a59b68b4e 100644 --- a/core/java/android/bluetooth/BluetoothMapClient.java +++ b/core/java/android/bluetooth/BluetoothMapClient.java @@ -73,6 +73,8 @@ public final class BluetoothMapClient implements BluetoothProfile { /** Connection canceled before completion. */ public static final int RESULT_CANCELED = 2; + private static final int UPLOADING_FEATURE_BITMASK = 0x08; + private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback = new IBluetoothStateChangeCallback.Stub() { public void onBluetoothStateChange(boolean up) { @@ -395,6 +397,23 @@ public final class BluetoothMapClient implements BluetoothProfile { return false; } + /** + * Returns the "Uploading" feature bit value from the SDP record's + * MapSupportedFeatures field (see Bluetooth MAP 1.4 spec, page 114). + * @param device The Bluetooth device to get this value for. + * @return Returns true if the Uploading bit value in SDP record's + * MapSupportedFeatures field is set. False is returned otherwise. + */ + public boolean isUploadingSupported(BluetoothDevice device) { + try { + return (mService != null && isEnabled() && isValidDevice(device)) + && ((mService.getSupportedFeatures(device) & UPLOADING_FEATURE_BITMASK) > 0); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + return false; + } + private final ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) Log.d(TAG, "Proxy object connected"); diff --git a/core/java/android/net/ConnectionInfo.aidl b/core/java/android/net/ConnectionInfo.aidl new file mode 100644 index 000000000000..07faf8bbbed8 --- /dev/null +++ b/core/java/android/net/ConnectionInfo.aidl @@ -0,0 +1,20 @@ +/* +** +** 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.net; + +parcelable ConnectionInfo; diff --git a/core/java/android/net/ConnectionInfo.java b/core/java/android/net/ConnectionInfo.java new file mode 100644 index 000000000000..58d0e05be6fd --- /dev/null +++ b/core/java/android/net/ConnectionInfo.java @@ -0,0 +1,83 @@ +/* + * 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.net; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; + +/** + * Describe a network connection including local and remote address/port of a connection and the + * transport protocol. + * + * @hide + */ +public final class ConnectionInfo implements Parcelable { + public final int protocol; + public final InetSocketAddress local; + public final InetSocketAddress remote; + + @Override + public int describeContents() { + return 0; + } + + public ConnectionInfo(int protocol, InetSocketAddress local, InetSocketAddress remote) { + this.protocol = protocol; + this.local = local; + this.remote = remote; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(protocol); + out.writeByteArray(local.getAddress().getAddress()); + out.writeInt(local.getPort()); + out.writeByteArray(remote.getAddress().getAddress()); + out.writeInt(remote.getPort()); + } + + public static final Creator<ConnectionInfo> CREATOR = new Creator<ConnectionInfo>() { + public ConnectionInfo createFromParcel(Parcel in) { + int protocol = in.readInt(); + InetAddress localAddress; + try { + localAddress = InetAddress.getByAddress(in.createByteArray()); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid InetAddress"); + } + int localPort = in.readInt(); + InetAddress remoteAddress; + try { + remoteAddress = InetAddress.getByAddress(in.createByteArray()); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid InetAddress"); + } + int remotePort = in.readInt(); + InetSocketAddress local = new InetSocketAddress(localAddress, localPort); + InetSocketAddress remote = new InetSocketAddress(remoteAddress, remotePort); + return new ConnectionInfo(protocol, local, remote); + } + + public ConnectionInfo[] newArray(int size) { + return new ConnectionInfo[size]; + } + }; +} diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index ce1879620ce3..8333b817add0 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -26,7 +26,6 @@ import android.annotation.UnsupportedAppUsage; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.os.Binder; import android.os.Build.VERSION_CODES; import android.os.Bundle; @@ -59,6 +58,7 @@ import libcore.net.event.NetworkEventDispatcher; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -3800,8 +3800,9 @@ public class ConnectivityManager { private void unsupportedStartingFrom(int version) { if (Process.myUid() == Process.SYSTEM_UID) { - // The getApplicationInfo() call we make below is not supported in system context, and - // we want to allow the system to use these APIs anyway. + // The getApplicationInfo() call we make below is not supported in system context. Let + // the call through here, and rely on the fact that ConnectivityService will refuse to + // allow the system to use these APIs anyway. return; } @@ -3818,11 +3819,6 @@ public class ConnectivityManager { // functions by accessing ConnectivityService directly. However, it should be clear that doing // so is unsupported and may break in the future. http://b/22728205 private void checkLegacyRoutingApiAccess() { - if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS") - == PackageManager.PERMISSION_GRANTED) { - return; - } - unsupportedStartingFrom(VERSION_CODES.M); } @@ -3930,4 +3926,26 @@ public class ConnectivityManager { throw e.rethrowFromSystemServer(); } } + + /** + * Returns the {@code uid} of the owner of a network connection. + * + * @param protocol The protocol of the connection. Only {@code IPPROTO_TCP} and + * {@code IPPROTO_UDP} currently supported. + * @param local The local {@link InetSocketAddress} of a connection. + * @param remote The remote {@link InetSocketAddress} of a connection. + * + * @return {@code uid} if the connection is found and the app has permission to observe it + * (e.g., if it is associated with the calling VPN app's tunnel) or + * {@link android.os.Process#INVALID_UID} if the connection is not found. + */ + public int getConnectionOwnerUid(int protocol, InetSocketAddress local, + InetSocketAddress remote) { + ConnectionInfo connectionInfo = new ConnectionInfo(protocol, local, remote); + try { + return mService.getConnectionOwnerUid(connectionInfo); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index ce95b60dd2db..e7d441df82a6 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -17,6 +17,7 @@ package android.net; import android.app.PendingIntent; +import android.net.ConnectionInfo; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; @@ -182,4 +183,6 @@ interface IConnectivityManager String getCaptivePortalServerUrl(); byte[] getNetworkWatchlistConfigHash(); + + int getConnectionOwnerUid(in ConnectionInfo connectionInfo); } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 7ce7c9237815..d0cdf6e75224 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -40,6 +40,11 @@ public class Process { public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary"; /** + * An invalid UID value. + */ + public static final int INVALID_UID = -1; + + /** * Defines the root UID. * @hide */ diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 3e8e8854634d..8492b0cf58e2 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -36,16 +36,12 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; -import com.android.internal.logging.MetricsLogger; - import libcore.io.Streams; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; @@ -97,7 +93,7 @@ public class RecoverySystem { /** Used to communicate with recovery. See bootable/recovery/recovery.cpp. */ private static final File RECOVERY_DIR = new File("/cache/recovery"); private static final File LOG_FILE = new File(RECOVERY_DIR, "log"); - private static final File LAST_INSTALL_FILE = new File(RECOVERY_DIR, "last_install"); + private static final String LAST_INSTALL_PATH = "last_install"; private static final String LAST_PREFIX = "last_"; private static final String ACTION_EUICC_FACTORY_RESET = "com.android.internal.action.EUICC_FACTORY_RESET"; @@ -935,116 +931,6 @@ public class RecoverySystem { throw new IOException("Reboot failed (no permissions?)"); } - // Read last_install; then report time (in seconds) and I/O (in MiB) for - // this update to tron. - // Only report on the reboots immediately after an OTA update. - private static void parseLastInstallLog(Context context) { - try (BufferedReader in = new BufferedReader(new FileReader(LAST_INSTALL_FILE))) { - String line = null; - int bytesWrittenInMiB = -1, bytesStashedInMiB = -1; - int timeTotal = -1; - int uncryptTime = -1; - int sourceVersion = -1; - int temperatureStart = -1; - int temperatureEnd = -1; - int temperatureMax = -1; - int errorCode = -1; - int causeCode = -1; - - while ((line = in.readLine()) != null) { - // Here is an example of lines in last_install: - // ... - // time_total: 101 - // bytes_written_vendor: 51074 - // bytes_stashed_vendor: 200 - int numIndex = line.indexOf(':'); - if (numIndex == -1 || numIndex + 1 >= line.length()) { - continue; - } - String numString = line.substring(numIndex + 1).trim(); - long parsedNum; - try { - parsedNum = Long.parseLong(numString); - } catch (NumberFormatException ignored) { - Log.e(TAG, "Failed to parse numbers in " + line); - continue; - } - - final int MiB = 1024 * 1024; - int scaled; - try { - if (line.startsWith("bytes")) { - scaled = Math.toIntExact(parsedNum / MiB); - } else { - scaled = Math.toIntExact(parsedNum); - } - } catch (ArithmeticException ignored) { - Log.e(TAG, "Number overflows in " + line); - continue; - } - - if (line.startsWith("time")) { - timeTotal = scaled; - } else if (line.startsWith("uncrypt_time")) { - uncryptTime = scaled; - } else if (line.startsWith("source_build")) { - sourceVersion = scaled; - } else if (line.startsWith("bytes_written")) { - bytesWrittenInMiB = (bytesWrittenInMiB == -1) ? scaled : - bytesWrittenInMiB + scaled; - } else if (line.startsWith("bytes_stashed")) { - bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled : - bytesStashedInMiB + scaled; - } else if (line.startsWith("temperature_start")) { - temperatureStart = scaled; - } else if (line.startsWith("temperature_end")) { - temperatureEnd = scaled; - } else if (line.startsWith("temperature_max")) { - temperatureMax = scaled; - } else if (line.startsWith("error")) { - errorCode = scaled; - } else if (line.startsWith("cause")) { - causeCode = scaled; - } - } - - // Don't report data to tron if corresponding entry isn't found in last_install. - if (timeTotal != -1) { - MetricsLogger.histogram(context, "ota_time_total", timeTotal); - } - if (uncryptTime != -1) { - MetricsLogger.histogram(context, "ota_uncrypt_time", uncryptTime); - } - if (sourceVersion != -1) { - MetricsLogger.histogram(context, "ota_source_version", sourceVersion); - } - if (bytesWrittenInMiB != -1) { - MetricsLogger.histogram(context, "ota_written_in_MiBs", bytesWrittenInMiB); - } - if (bytesStashedInMiB != -1) { - MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB); - } - if (temperatureStart != -1) { - MetricsLogger.histogram(context, "ota_temperature_start", temperatureStart); - } - if (temperatureEnd != -1) { - MetricsLogger.histogram(context, "ota_temperature_end", temperatureEnd); - } - if (temperatureMax != -1) { - MetricsLogger.histogram(context, "ota_temperature_max", temperatureMax); - } - if (errorCode != -1) { - MetricsLogger.histogram(context, "ota_non_ab_error_code", errorCode); - } - if (causeCode != -1) { - MetricsLogger.histogram(context, "ota_non_ab_cause_code", causeCode); - } - - } catch (IOException e) { - Log.e(TAG, "Failed to read lines in last_install", e); - } - } - /** * Called after booting to process and remove recovery-related files. * @return the log file from recovery, or null if none was found. @@ -1062,9 +948,6 @@ public class RecoverySystem { Log.e(TAG, "Error reading recovery log", e); } - if (log != null) { - parseLastInstallLog(context); - } // Only remove the OTA package if it's partially processed (uncrypt'd). boolean reservePackage = BLOCK_MAP_FILE.exists(); @@ -1095,7 +978,8 @@ public class RecoverySystem { // GmsCore to avoid re-downloading everything again. String[] names = RECOVERY_DIR.list(); for (int i = 0; names != null && i < names.length; i++) { - if (names[i].startsWith(LAST_PREFIX)) continue; + // Do not remove the last_install file since the recovery-persist takes care of it. + if (names[i].startsWith(LAST_PREFIX) || names[i].equals(LAST_INSTALL_PATH)) continue; if (reservePackage && names[i].equals(BLOCK_MAP_FILE.getName())) continue; if (reservePackage && names[i].equals(UNCRYPT_PACKAGE_FILE.getName())) continue; diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java index 534ef8d8e0e9..4b5a7b40fe44 100644 --- a/core/java/android/preference/DialogPreference.java +++ b/core/java/android/preference/DialogPreference.java @@ -43,7 +43,7 @@ import android.widget.TextView; * A base class for {@link Preference} objects that are * dialog-based. These preferences will, when clicked, open a dialog showing the * actual preference controls. - * + * * @attr ref android.R.styleable#DialogPreference_dialogTitle * @attr ref android.R.styleable#DialogPreference_dialogMessage * @attr ref android.R.styleable#DialogPreference_dialogIcon @@ -56,7 +56,7 @@ public abstract class DialogPreference extends Preference implements PreferenceManager.OnActivityDestroyListener { @UnsupportedAppUsage private AlertDialog.Builder mBuilder; - + @UnsupportedAppUsage private CharSequence mDialogTitle; @UnsupportedAppUsage @@ -77,6 +77,14 @@ public abstract class DialogPreference extends Preference implements @UnsupportedAppUsage private int mWhichButtonClicked; + /** Dismiss the dialog on the UI thread, but not inline with handlers */ + private final Runnable mDismissRunnable = new Runnable() { + @Override + public void run() { + mDialog.dismiss(); + } + }; + public DialogPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); @@ -112,7 +120,7 @@ public abstract class DialogPreference extends Preference implements /** * Sets the title of the dialog. This will be shown on subsequent dialogs. - * + * * @param dialogTitle The title. */ public void setDialogTitle(CharSequence dialogTitle) { @@ -126,7 +134,7 @@ public abstract class DialogPreference extends Preference implements public void setDialogTitle(int dialogTitleResId) { setDialogTitle(getContext().getString(dialogTitleResId)); } - + /** * Returns the title to be shown on subsequent dialogs. * @return The title. @@ -134,7 +142,7 @@ public abstract class DialogPreference extends Preference implements public CharSequence getDialogTitle() { return mDialogTitle; } - + /** * Sets the message of the dialog. This will be shown on subsequent dialogs. * <p> @@ -142,7 +150,7 @@ public abstract class DialogPreference extends Preference implements * list-based dialogs, for example. If setting a custom View on a dialog via * {@link #setDialogLayoutResource(int)}, include a text View with ID * {@link android.R.id#message} and it will be populated with this message. - * + * * @param dialogMessage The message. */ public void setDialogMessage(CharSequence dialogMessage) { @@ -156,7 +164,7 @@ public abstract class DialogPreference extends Preference implements public void setDialogMessage(int dialogMessageResId) { setDialogMessage(getContext().getString(dialogMessageResId)); } - + /** * Returns the message to be shown on subsequent dialogs. * @return The message. @@ -164,26 +172,26 @@ public abstract class DialogPreference extends Preference implements public CharSequence getDialogMessage() { return mDialogMessage; } - + /** * Sets the icon of the dialog. This will be shown on subsequent dialogs. - * + * * @param dialogIcon The icon, as a {@link Drawable}. */ public void setDialogIcon(Drawable dialogIcon) { mDialogIcon = dialogIcon; } - + /** * Sets the icon (resource ID) of the dialog. This will be shown on * subsequent dialogs. - * + * * @param dialogIconRes The icon, as a resource ID. */ public void setDialogIcon(@DrawableRes int dialogIconRes) { mDialogIcon = getContext().getDrawable(dialogIconRes); } - + /** * Returns the icon to be shown on subsequent dialogs. * @return The icon, as a {@link Drawable}. @@ -191,11 +199,11 @@ public abstract class DialogPreference extends Preference implements public Drawable getDialogIcon() { return mDialogIcon; } - + /** * Sets the text of the positive button of the dialog. This will be shown on * subsequent dialogs. - * + * * @param positiveButtonText The text of the positive button. */ public void setPositiveButtonText(CharSequence positiveButtonText) { @@ -209,27 +217,27 @@ public abstract class DialogPreference extends Preference implements public void setPositiveButtonText(@StringRes int positiveButtonTextResId) { setPositiveButtonText(getContext().getString(positiveButtonTextResId)); } - + /** * Returns the text of the positive button to be shown on subsequent * dialogs. - * + * * @return The text of the positive button. */ public CharSequence getPositiveButtonText() { return mPositiveButtonText; } - + /** * Sets the text of the negative button of the dialog. This will be shown on * subsequent dialogs. - * + * * @param negativeButtonText The text of the negative button. */ public void setNegativeButtonText(CharSequence negativeButtonText) { mNegativeButtonText = negativeButtonText; } - + /** * @see #setNegativeButtonText(CharSequence) * @param negativeButtonTextResId The negative button text as a resource. @@ -237,38 +245,38 @@ public abstract class DialogPreference extends Preference implements public void setNegativeButtonText(@StringRes int negativeButtonTextResId) { setNegativeButtonText(getContext().getString(negativeButtonTextResId)); } - + /** * Returns the text of the negative button to be shown on subsequent * dialogs. - * + * * @return The text of the negative button. */ public CharSequence getNegativeButtonText() { return mNegativeButtonText; } - + /** * Sets the layout resource that is inflated as the {@link View} to be shown * as the content View of subsequent dialogs. - * + * * @param dialogLayoutResId The layout resource ID to be inflated. * @see #setDialogMessage(CharSequence) */ public void setDialogLayoutResource(int dialogLayoutResId) { mDialogLayoutResId = dialogLayoutResId; } - + /** * Returns the layout resource that is used as the content View for * subsequent dialogs. - * + * * @return The layout resource. */ public int getDialogLayoutResource() { return mDialogLayoutResId; } - + /** * Prepares the dialog builder to be shown when the preference is clicked. * Use this to set custom properties on the dialog. @@ -278,7 +286,7 @@ public abstract class DialogPreference extends Preference implements */ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { } - + @Override protected void onClick() { if (mDialog != null && mDialog.isShowing()) return; @@ -290,14 +298,14 @@ public abstract class DialogPreference extends Preference implements * Shows the dialog associated with this Preference. This is normally initiated * automatically on clicking on the preference. Call this method if you need to * show the dialog on some other event. - * + * * @param state Optional instance state to restore on the dialog */ protected void showDialog(Bundle state) { Context context = getContext(); mWhichButtonClicked = DialogInterface.BUTTON_NEGATIVE; - + mBuilder = new AlertDialog.Builder(context) .setTitle(mDialogTitle) .setIcon(mDialogIcon) @@ -311,11 +319,11 @@ public abstract class DialogPreference extends Preference implements } else { mBuilder.setMessage(mDialogMessage); } - + onPrepareDialogBuilder(mBuilder); - + getPreferenceManager().registerOnActivityDestroyListener(this); - + // Create the dialog final Dialog dialog = mDialog = mBuilder.create(); if (state != null) { @@ -324,10 +332,29 @@ public abstract class DialogPreference extends Preference implements if (needInputMethod()) { requestInputMethod(dialog); } + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface dialog) { + removeDismissCallbacks(); + } + }); dialog.setOnDismissListener(this); dialog.show(); } + void postDismiss() { + removeDismissCallbacks(); + View decorView = mDialog.getWindow().getDecorView(); + decorView.post(mDismissRunnable); + } + + private void removeDismissCallbacks() { + if (mDialog != null && mDialog.getWindow() != null + && mDialog.getWindow().getDecorView() != null) { + mDialog.getWindow().getDecorView().removeCallbacks(mDismissRunnable); + } + } + /** * Returns whether the preference needs to display a soft input method when the dialog * is displayed. Default is false. Subclasses should override this method if they need @@ -350,7 +377,7 @@ public abstract class DialogPreference extends Preference implements * Creates the content view for the dialog (if a custom content view is * required). By default, it inflates the dialog layout resource if it is * set. - * + * * @return The content View for the dialog. * @see #setLayoutResource(int) */ @@ -358,48 +385,49 @@ public abstract class DialogPreference extends Preference implements if (mDialogLayoutResId == 0) { return null; } - + LayoutInflater inflater = LayoutInflater.from(mBuilder.getContext()); return inflater.inflate(mDialogLayoutResId, null); } - + /** * Binds views in the content View of the dialog to data. * <p> * Make sure to call through to the superclass implementation. - * + * * @param view The content View of the dialog, if it is custom. */ @CallSuper protected void onBindDialogView(View view) { View dialogMessageView = view.findViewById(com.android.internal.R.id.message); - + if (dialogMessageView != null) { final CharSequence message = getDialogMessage(); int newVisibility = View.GONE; - + if (!TextUtils.isEmpty(message)) { if (dialogMessageView instanceof TextView) { ((TextView) dialogMessageView).setText(message); } - + newVisibility = View.VISIBLE; } - + if (dialogMessageView.getVisibility() != newVisibility) { dialogMessageView.setVisibility(newVisibility); } } } - + public void onClick(DialogInterface dialog, int which) { mWhichButtonClicked = which; } - + + @Override public void onDismiss(DialogInterface dialog) { - + removeDismissCallbacks(); getPreferenceManager().unregisterOnActivityDestroyListener(this); - + mDialog = null; onDialogClosed(mWhichButtonClicked == DialogInterface.BUTTON_POSITIVE); } @@ -407,7 +435,7 @@ public abstract class DialogPreference extends Preference implements /** * Called when the dialog is dismissed and should be used to save data to * the {@link SharedPreferences}. - * + * * @param positiveResult Whether the positive button was clicked (true), or * the negative button was clicked or the dialog was canceled (false). */ @@ -416,7 +444,7 @@ public abstract class DialogPreference extends Preference implements /** * Gets the dialog that is shown by this preference. - * + * * @return The dialog, or null if a dialog is not being shown. */ public Dialog getDialog() { @@ -427,11 +455,11 @@ public abstract class DialogPreference extends Preference implements * {@inheritDoc} */ public void onActivityDestroy() { - + if (mDialog == null || !mDialog.isShowing()) { return; } - + mDialog.dismiss(); } @@ -466,7 +494,7 @@ public abstract class DialogPreference extends Preference implements private static class SavedState extends BaseSavedState { boolean isDialogShowing; Bundle dialogBundle; - + public SavedState(Parcel source) { super(source); isDialogShowing = source.readInt() == 1; @@ -495,5 +523,5 @@ public abstract class DialogPreference extends Preference implements } }; } - + } diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java index e7dec0ec2bba..c0c71af8639e 100644 --- a/core/java/android/preference/ListPreference.java +++ b/core/java/android/preference/ListPreference.java @@ -33,7 +33,7 @@ import android.util.AttributeSet; * <p> * This preference will store a string into the SharedPreferences. This string will be the value * from the {@link #setEntryValues(CharSequence[])} array. - * + * * @attr ref android.R.styleable#ListPreference_entries * @attr ref android.R.styleable#ListPreference_entryValues */ @@ -193,7 +193,7 @@ public class ListPreference extends DialogPreference { /** * Sets the value to the given index from the entry values. - * + * * @param index The index of the value to set. */ public void setValueIndex(int index) { @@ -201,30 +201,30 @@ public class ListPreference extends DialogPreference { setValue(mEntryValues[index].toString()); } } - + /** * Returns the value of the key. This should be one of the entries in * {@link #getEntryValues()}. - * + * * @return The value of the key. */ public String getValue() { - return mValue; + return mValue; } - + /** * Returns the entry corresponding to the current value. - * + * * @return The entry corresponding to the current value, or null. */ public CharSequence getEntry() { int index = getValueIndex(); return index >= 0 && mEntries != null ? mEntries[index] : null; } - + /** * Returns the index of the given value (in the entry values array). - * + * * @param value The value whose index should be returned. * @return The index of the value, or -1 if not found. */ @@ -238,22 +238,22 @@ public class ListPreference extends DialogPreference { } return -1; } - + private int getValueIndex() { return findIndexOfValue(mValue); } - + @Override protected void onPrepareDialogBuilder(Builder builder) { super.onPrepareDialogBuilder(builder); - + if (mEntries == null || mEntryValues == null) { throw new IllegalStateException( "ListPreference requires an entries array and an entryValues array."); } mClickedDialogEntryIndex = getValueIndex(); - builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, + builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mClickedDialogEntryIndex = which; @@ -263,10 +263,10 @@ public class ListPreference extends DialogPreference { * click, and dismisses the dialog. */ ListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE); - dialog.dismiss(); + postDismiss(); } }); - + /* * The typical interaction for list-based dialogs is to have * click-on-an-item dismiss the dialog instead of the user having to @@ -278,7 +278,7 @@ public class ListPreference extends DialogPreference { @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); - + if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) { String value = mEntryValues[mClickedDialogEntryIndex].toString(); if (callChangeListener(value)) { @@ -296,7 +296,7 @@ public class ListPreference extends DialogPreference { protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue); } - + @Override protected Parcelable onSaveInstanceState() { final Parcelable superState = super.onSaveInstanceState(); @@ -304,7 +304,7 @@ public class ListPreference extends DialogPreference { // No need to save instance state since it's persistent return superState; } - + final SavedState myState = new SavedState(superState); myState.value = getValue(); return myState; @@ -317,15 +317,15 @@ public class ListPreference extends DialogPreference { super.onRestoreInstanceState(state); return; } - + SavedState myState = (SavedState) state; super.onRestoreInstanceState(myState.getSuperState()); setValue(myState.value); } - + private static class SavedState extends BaseSavedState { String value; - + public SavedState(Parcel source) { super(source); value = source.readString(); @@ -352,5 +352,5 @@ public class ListPreference extends DialogPreference { } }; } - + } diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 149f2b40add5..dd011a0ff0ec 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -1444,18 +1444,6 @@ public final class MediaStore { } public static final class Media implements AudioColumns { - - private static final String[] EXTERNAL_PATHS; - - static { - String secondary_storage = System.getenv("SECONDARY_STORAGE"); - if (secondary_storage != null) { - EXTERNAL_PATHS = secondary_storage.split(":"); - } else { - EXTERNAL_PATHS = new String[0]; - } - } - /** * Get the content:// style URI for the audio media table on the * given volume. @@ -1469,14 +1457,9 @@ public final class MediaStore { } public static Uri getContentUriForPath(String path) { - for (String ep : EXTERNAL_PATHS) { - if (path.startsWith(ep)) { - return EXTERNAL_CONTENT_URI; - } - } - - return (path.startsWith(Environment.getExternalStorageDirectory().getPath()) ? - EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI); + return (path.startsWith( + Environment.getStorageDirectory().getAbsolutePath() + "/") + ? EXTERNAL_CONTENT_URI : INTERNAL_CONTENT_URI); } /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 4b76ba8be63f..29dbb83ca591 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -9131,6 +9131,19 @@ public final class Settings { public static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on"; /** + * Whether the wifi data connection should remain active even when higher + * priority networks like Ethernet are active, to keep both networks. + * In the case where higher priority networks are connected, wifi will be + * unused unless an application explicitly requests to use it. + * + * See ConnectivityService for more info. + * + * (0 = disabled, 1 = enabled) + * @hide + */ + public static final String WIFI_ALWAYS_REQUESTED = "wifi_always_requested"; + + /** * Size of the event buffer for IP connectivity metrics. * @hide */ @@ -9469,8 +9482,7 @@ public final class Settings { * Use the old dnsmasq DHCP server for tethering instead of the framework implementation. * * Integer values are interpreted as boolean, and the absence of an explicit setting - * is interpreted as |true|. - * TODO: make the default |false| + * is interpreted as |false|. * @hide */ public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER = diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java index 119f5d0de0a0..4f4d62af679c 100644 --- a/core/java/android/security/net/config/DirectoryCertificateSource.java +++ b/core/java/android/security/net/config/DirectoryCertificateSource.java @@ -16,26 +16,23 @@ package android.security.net.config; -import android.os.Environment; -import android.os.UserHandle; import android.util.ArraySet; import android.util.Log; -import android.util.Pair; + +import libcore.io.IoUtils; + import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.InputStream; import java.io.IOException; -import java.security.cert.Certificate; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Set; -import libcore.io.IoUtils; - -import com.android.org.conscrypt.Hex; -import com.android.org.conscrypt.NativeCrypto; import javax.security.auth.x500.X500Principal; @@ -192,8 +189,36 @@ abstract class DirectoryCertificateSource implements CertificateSource { } private String getHash(X500Principal name) { - int hash = NativeCrypto.X509_NAME_hash_old(name); - return Hex.intToHexString(hash, 8); + int hash = hashName(name); + return intToHexString(hash, 8); + } + + private static final char[] DIGITS = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + private static String intToHexString(int i, int minWidth) { + int bufLen = 8; // Max number of hex digits in an int + char[] buf = new char[bufLen]; + int cursor = bufLen; + + do { + buf[--cursor] = DIGITS[i & 0xf]; + } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth)); + + return new String(buf, cursor, bufLen - cursor); + } + + // This code matches the code in X509_NAME_hash_old() in Conscrypt, which in turn matches + // the names of certificate files. It must be kept in sync. + private static int hashName(X500Principal principal) { + try { + byte[] digest = MessageDigest.getInstance("MD5").digest(principal.getEncoded()); + int offset = 0; + return (((digest[offset++] & 0xff) << 0) | ((digest[offset++] & 0xff) << 8) + | ((digest[offset++] & 0xff) << 16) | ((digest[offset] & 0xff) << 24)); + } catch (NoSuchAlgorithmException e) { + throw new AssertionError(e); + } } private X509Certificate readCertificate(String file) { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index b93afdf3a090..bca2e117a8a1 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1421,6 +1421,10 @@ public final class InputMethodManager { mServedView.getWindowToken() == appWindowToken) { finishInputLocked(); } + if (mCurRootView != null && + mCurRootView.getWindowToken() == appWindowToken) { + mCurRootView = null; + } } } diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java index b591163e8728..f90eab13bbcf 100644 --- a/core/java/com/android/internal/content/FileSystemProvider.java +++ b/core/java/com/android/internal/content/FileSystemProvider.java @@ -236,6 +236,7 @@ public abstract class FileSystemProvider extends DocumentsProvider { displayName = FileUtils.buildValidFatFilename(displayName); final File before = getFileForDocId(docId); + final File beforeVisibleFile = getFileForDocId(docId, true); final File after = FileUtils.buildUniqueFile(before.getParentFile(), displayName); if (!before.renameTo(after)) { throw new IllegalStateException("Failed to rename to " + after); @@ -245,7 +246,6 @@ public abstract class FileSystemProvider extends DocumentsProvider { onDocIdChanged(docId); onDocIdChanged(afterDocId); - final File beforeVisibleFile = getFileForDocId(docId, true); final File afterVisibleFile = getFileForDocId(afterDocId, true); moveInMediaStore(beforeVisibleFile, afterVisibleFile); diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java index 7fd83bc6c8b9..f6d80a572c75 100644 --- a/core/java/com/android/internal/util/DumpUtils.java +++ b/core/java/com/android/internal/util/DumpUtils.java @@ -34,9 +34,18 @@ import java.util.function.Predicate; /** * Helper functions for dumping the state of system services. * Test: - atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java + atest FrameworksCoreTests:DumpUtilsTest */ public final class DumpUtils { + + /** + * List of component names that should be dumped in the bug report critical section. + * + * @hide + */ + public static final ComponentName[] CRITICAL_SECTION_COMPONENTS = { + new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService") + }; private static final String TAG = "DumpUtils"; private static final boolean DEBUG = false; @@ -213,6 +222,45 @@ public final class DumpUtils { } /** + * Return whether a package should be dumped in the critical section. + */ + private static boolean isCriticalPackage(@Nullable ComponentName cname) { + if (cname == null) { + return false; + } + + for (int i = 0; i < CRITICAL_SECTION_COMPONENTS.length; i++) { + if (cname.equals(CRITICAL_SECTION_COMPONENTS[i])) { + return true; + } + } + return false; + } + + /** + * Return whether a package name is considered to be part of the platform and in the critical + * section. + * + * @hide + */ + public static boolean isPlatformCriticalPackage(@Nullable ComponentName.WithComponentName wcn) { + return (wcn != null) && isPlatformPackage(wcn.getComponentName()) && + isCriticalPackage(wcn.getComponentName()); + } + + /** + * Return whether a package name is considered to be part of the platform but not in the the + * critical section. + * + * @hide + */ + public static boolean isPlatformNonCriticalPackage( + @Nullable ComponentName.WithComponentName wcn) { + return (wcn != null) && isPlatformPackage(wcn.getComponentName()) && + !isCriticalPackage(wcn.getComponentName()); + } + + /** * Used for dumping providers and services. Return a predicate for a given filter string. * @hide */ @@ -238,6 +286,16 @@ public final class DumpUtils { return DumpUtils::isNonPlatformPackage; } + // Dump all platform-critical? + if ("all-platform-critical".equals(filterString)) { + return DumpUtils::isPlatformCriticalPackage; + } + + // Dump all platform-non-critical? + if ("all-platform-non-critical".equals(filterString)) { + return DumpUtils::isPlatformNonCriticalPackage; + } + // Is the filter a component name? If so, do an exact match. final ComponentName filterCname = ComponentName.unflattenFromString(filterString); if (filterCname != null) { diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp index 6df23f72bdd3..a1f2377041e8 100644 --- a/core/jni/android_net_LocalSocketImpl.cpp +++ b/core/jni/android_net_LocalSocketImpl.cpp @@ -58,6 +58,11 @@ socket_connect_local(JNIEnv *env, jobject object, int ret; int fd; + if (name == NULL) { + jniThrowNullPointerException(env, NULL); + return; + } + fd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (env->ExceptionCheck()) { diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index c15b7ee4fe04..109e65c4a1d0 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -285,10 +285,6 @@ static int statsLinesToNetworkStats(JNIEnv* env, jclass clazz, jobject stats, static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path, jint limitUid, jobjectArray limitIfacesObj, jint limitTag, jboolean useBpfStats) { - ScopedUtfChars path8(env, path); - if (path8.c_str() == NULL) { - return -1; - } std::vector<std::string> limitIfaces; if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) { @@ -308,6 +304,11 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstr if (parseBpfNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid) < 0) return -1; } else { + ScopedUtfChars path8(env, path); + if (path8.c_str() == NULL) { + ALOGE("the qtaguid legacy path is invalid: %s", path8.c_str()); + return -1; + } if (legacyReadNetworkStatsDetail(&lines, limitIfaces, limitTag, limitUid, path8.c_str()) < 0) return -1; diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 632e4396fab0..477b17e9c34b 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3463,4 +3463,12 @@ <!-- Whether or not swipe up gesture's opt-in setting is available on this device --> <bool name="config_swipe_up_gesture_setting_available">false</bool> + <!-- Pre-scale volume at volume step 1 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction> + + <!-- Pre-scale volume at volume step 2 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index2">70%</fraction> + + <!-- Pre-scale volume at volume step 3 for Absolute Volume --> + <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index de5dc43d6843..e9a54f1d7739 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3393,4 +3393,9 @@ <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" /> <java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" /> + + <!-- For Bluetooth AbsoluteVolume --> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" /> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" /> + <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" /> </resources> diff --git a/core/tests/coretests/src/android/net/LocalSocketTest.java b/core/tests/coretests/src/android/net/LocalSocketTest.java index 1349844c80cf..1286b137cc1f 100644 --- a/core/tests/coretests/src/android/net/LocalSocketTest.java +++ b/core/tests/coretests/src/android/net/LocalSocketTest.java @@ -22,6 +22,7 @@ import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.test.MoreAsserts; import android.test.suitebuilder.annotation.SmallTest; + import junit.framework.TestCase; import java.io.FileDescriptor; @@ -39,6 +40,20 @@ public class LocalSocketTest extends TestCase { ls = new LocalSocket(); + try { + ls.connect(new LocalSocketAddress(null)); + fail("Expected NullPointerException"); + } catch (NullPointerException e) { + // pass + } + + try { + ls.bind(new LocalSocketAddress(null)); + fail("Expected NullPointerException"); + } catch (NullPointerException e) { + // pass + } + ls.connect(new LocalSocketAddress("android.net.LocalSocketTest")); ls1 = ss.accept(); diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index cd9658348212..23be634da05f 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -456,6 +456,7 @@ public class SettingsBackupTest { Settings.Global.WFC_IMS_MODE, Settings.Global.WFC_IMS_ROAMING_ENABLED, Settings.Global.WFC_IMS_ROAMING_MODE, + Settings.Global.WIFI_ALWAYS_REQUESTED, Settings.Global.WIFI_BADGING_THRESHOLDS, Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS, Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED, diff --git a/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java index 45b19bccff88..a44b86074ee2 100644 --- a/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/util/DumpUtilsTest.java @@ -15,8 +15,11 @@ */ package com.android.internal.util; +import static com.android.internal.util.DumpUtils.CRITICAL_SECTION_COMPONENTS; import static com.android.internal.util.DumpUtils.filterRecord; import static com.android.internal.util.DumpUtils.isNonPlatformPackage; +import static com.android.internal.util.DumpUtils.isPlatformCriticalPackage; +import static com.android.internal.util.DumpUtils.isPlatformNonCriticalPackage; import static com.android.internal.util.DumpUtils.isPlatformPackage; import android.content.ComponentName; @@ -25,7 +28,7 @@ import junit.framework.TestCase; /** * Run with: - atest /android/pi-dev/frameworks/base/core/tests/coretests/src/com/android/internal/util/DumpTest.java + atest FrameworksCoreTests:DumpUtilsTest */ public class DumpUtilsTest extends TestCase { @@ -89,6 +92,32 @@ public class DumpUtilsTest extends TestCase { assertTrue(isNonPlatformPackage(wcn("com.google.def/abc"))); } + public void testIsPlatformCriticalPackage() { + for (final ComponentName componentName : CRITICAL_SECTION_COMPONENTS) { + assertTrue(isPlatformCriticalPackage(() -> componentName)); + assertTrue(isPlatformPackage(componentName)); + } + assertFalse(isPlatformCriticalPackage(wcn("com.google.p/abc"))); + assertFalse(isPlatformCriticalPackage(wcn("com.android.def/abc"))); + assertFalse(isPlatformCriticalPackage(wcn("com.android.abc"))); + assertFalse(isPlatformCriticalPackage(wcn("com.android"))); + assertFalse(isPlatformCriticalPackage(wcn(null))); + assertFalse(isPlatformCriticalPackage(null)); + } + + public void testIsPlatformNonCriticalPackage() { + for (final ComponentName componentName : CRITICAL_SECTION_COMPONENTS) { + assertFalse(isPlatformNonCriticalPackage(() -> componentName)); + } + assertTrue(isPlatformNonCriticalPackage(wcn("android/abc"))); + assertTrue(isPlatformNonCriticalPackage(wcn("android.abc/abc"))); + assertTrue(isPlatformNonCriticalPackage(wcn("com.android.def/abc"))); + + assertFalse(isPlatformNonCriticalPackage(wcn("com.google.def/abc"))); + assertFalse(isPlatformNonCriticalPackage(wcn(null))); + assertFalse(isPlatformNonCriticalPackage(null)); + } + public void testFilterRecord() { assertFalse(filterRecord(null).test(wcn("com.google.p/abc"))); assertFalse(filterRecord(null).test(wcn("com.android.p/abc"))); @@ -105,6 +134,19 @@ public class DumpUtilsTest extends TestCase { assertFalse(filterRecord("all-non-platform").test(wcn("com.android.p/abc"))); assertFalse(filterRecord("all-non-platform").test(wcn(null))); + for (final ComponentName componentName : CRITICAL_SECTION_COMPONENTS) { + assertTrue(filterRecord("all-platform-critical").test((() -> componentName))); + assertFalse(filterRecord("all-platform-non-critical").test((() -> componentName))); + assertTrue(filterRecord("all-platform").test((() -> componentName))); + } + assertFalse(filterRecord("all-platform-critical").test(wcn("com.google.p/abc"))); + assertFalse(filterRecord("all-platform-critical").test(wcn("com.android.p/abc"))); + assertFalse(filterRecord("all-platform-critical").test(wcn(null))); + + assertTrue(filterRecord("all-platform-non-critical").test(wcn("com.android.p/abc"))); + assertFalse(filterRecord("all-platform-non-critical").test(wcn("com.google.p/abc"))); + assertFalse(filterRecord("all-platform-non-critical").test(wcn(null))); + // Partial string match. assertTrue(filterRecord("abc").test(wcn("com.google.p/.abc"))); assertFalse(filterRecord("abc").test(wcn("com.google.p/.def"))); diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl index 522db3c9235e..b463dd84e75b 100644 --- a/data/keyboards/Vendor_054c_Product_0268.kl +++ b/data/keyboards/Vendor_054c_Product_0268.kl @@ -21,8 +21,6 @@ key 0x125 DPAD_RIGHT key 0x126 DPAD_DOWN key 0x127 DPAD_LEFT -key 0x120 BUTTON_SELECT -key 0x123 BUTTON_START key 0x12e BUTTON_A key 0x12d BUTTON_B key 0x12f BUTTON_X @@ -34,9 +32,6 @@ key 0x129 BUTTON_R2 key 0x121 BUTTON_THUMBL key 0x122 BUTTON_THUMBR -# PS key -key 0x2d0 BUTTON_MODE - # Left Analog Stick axis 0x00 X axis 0x01 Y @@ -74,3 +69,11 @@ axis 0x31 RTRIGGER # Square # axis 0x37 + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Select +key 0x120 BUTTON_SELECT +# Start +key 0x123 BUTTON_START +# PS key +key 0x2d0 BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl new file mode 100644 index 000000000000..3d93f0fec800 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_0268_Version_8000.kl @@ -0,0 +1,57 @@ +# 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. + +# +# Sony Playstation(R)3 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12 +# and when connected over Bluetooth +# + +key 0x220 DPAD_UP +key 0x223 DPAD_RIGHT +key 0x221 DPAD_DOWN +key 0x222 DPAD_LEFT + +key 0x130 BUTTON_A +key 0x131 BUTTON_B +key 0x134 BUTTON_X +key 0x133 BUTTON_Y +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 +key 0x13d BUTTON_THUMBL +key 0x13e BUTTON_THUMBR + +# left Analog Stick +axis 0x00 X +axis 0x01 Y + +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# L2 trigger +axis 0x02 LTRIGGER + +# R2 trigger +axis 0x05 RTRIGGER + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Select +key 0x13a BUTTON_SELECT +# Start +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl new file mode 100644 index 000000000000..3d93f0fec800 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_0268_Version_8100.kl @@ -0,0 +1,57 @@ +# 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. + +# +# Sony Playstation(R)3 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.12 +# and when connected over Bluetooth +# + +key 0x220 DPAD_UP +key 0x223 DPAD_RIGHT +key 0x221 DPAD_DOWN +key 0x222 DPAD_LEFT + +key 0x130 BUTTON_A +key 0x131 BUTTON_B +key 0x134 BUTTON_X +key 0x133 BUTTON_Y +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 +key 0x13d BUTTON_THUMBL +key 0x13e BUTTON_THUMBR + +# left Analog Stick +axis 0x00 X +axis 0x01 Y + +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# L2 trigger +axis 0x02 LTRIGGER + +# R2 trigger +axis 0x05 RTRIGGER + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Select +key 0x13a BUTTON_SELECT +# Start +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl new file mode 100644 index 000000000000..5fe35f7faefa --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_0268_Version_8111.kl @@ -0,0 +1,57 @@ +# 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. + +# +# Sony Playstation(R)3 Controller +# - Version 0x8111 is for Linux hid-sony driver >=4.12 and when +# connected over USB +# + +key 0x220 DPAD_UP +key 0x223 DPAD_RIGHT +key 0x221 DPAD_DOWN +key 0x222 DPAD_LEFT + +key 0x130 BUTTON_A +key 0x131 BUTTON_B +key 0x134 BUTTON_X +key 0x133 BUTTON_Y +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 +key 0x13d BUTTON_THUMBL +key 0x13e BUTTON_THUMBR + +# left Analog Stick +axis 0x00 X +axis 0x01 Y + +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# L2 trigger +axis 0x02 LTRIGGER + +# R2 trigger +axis 0x05 RTRIGGER + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Select +key 0x13a BUTTON_SELECT +# Start +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_05c4.kl b/data/keyboards/Vendor_054c_Product_05c4.kl index a1284a49dad6..cd7ab1faec2e 100644 --- a/data/keyboards/Vendor_054c_Product_05c4.kl +++ b/data/keyboards/Vendor_054c_Product_05c4.kl @@ -60,7 +60,6 @@ axis 0x11 HAT_Y key 0x138 BUTTON_SELECT # Options key 0x139 BUTTON_START - # PS key key 0x13c BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl new file mode 100644 index 000000000000..19fcb86eb403 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8000.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10 +# and when connected over Bluetooth +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl new file mode 100644 index 000000000000..19fcb86eb403 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8100.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10 +# and when connected over Bluetooth +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl new file mode 100644 index 000000000000..d38bdec5dada --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_05c4_Version_8111.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when +# connected over USB +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_09cc.kl b/data/keyboards/Vendor_054c_Product_09cc.kl index a1284a49dad6..cd7ab1faec2e 100644 --- a/data/keyboards/Vendor_054c_Product_09cc.kl +++ b/data/keyboards/Vendor_054c_Product_09cc.kl @@ -60,7 +60,6 @@ axis 0x11 HAT_Y key 0x138 BUTTON_SELECT # Options key 0x139 BUTTON_START - # PS key key 0x13c BUTTON_MODE diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl new file mode 100644 index 000000000000..19fcb86eb403 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8000.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10 +# and when connected over Bluetooth +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl new file mode 100644 index 000000000000..19fcb86eb403 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8100.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8000 and 0x8100 are for Linux hid-sony driver >=4.10 +# and when connected over Bluetooth +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl new file mode 100644 index 000000000000..d38bdec5dada --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_09cc_Version_8111.kl @@ -0,0 +1,68 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 Controller +# - Version 0x8111 is for Linux hid-sony driver >=4.10 and when +# connected over USB +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/data/keyboards/Vendor_054c_Product_0ba0.kl b/data/keyboards/Vendor_054c_Product_0ba0.kl new file mode 100644 index 000000000000..bc6fc3b5e455 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_0ba0.kl @@ -0,0 +1,70 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 USB Dongle +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x130 BUTTON_X +# Cross +key 0x131 BUTTON_A +# Circle +key 0x132 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x134 BUTTON_L1 +key 0x135 BUTTON_R1 +key 0x136 BUTTON_L2 +key 0x137 BUTTON_R2 + +# L2 axis +axis 0x03 LTRIGGER +# R2 axis +axis 0x04 RTRIGGER + + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x02 Z +axis 0x05 RZ + +# Left stick click +key 0x13a BUTTON_THUMBL +# Right stick click +key 0x13b BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x138 BUTTON_SELECT +# Options +key 0x139 BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# Touchpad press +# The touchpad for this joystick will become a separate input device in future releases +# and this button will be equivalent to left mouse button +# Therefore, map it to KEYCODE_BUTTON_1 here to allow apps to still handle this on earlier versions +key 0x13d BUTTON_1 diff --git a/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl new file mode 100644 index 000000000000..8b85a38b4318 --- /dev/null +++ b/data/keyboards/Vendor_054c_Product_0ba0_Version_8111.kl @@ -0,0 +1,67 @@ +# 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. + +# +# Sony Playstation(R) DualShock 4 USB Dongle +# - Version 0x8111 is for Linux hid-sony driver >=4.10 +# + + +# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html + +# Square +key 0x134 BUTTON_X +# Cross +key 0x130 BUTTON_A +# Circle +key 0x131 BUTTON_B +# Triangle +key 0x133 BUTTON_Y + +key 0x136 BUTTON_L1 +key 0x137 BUTTON_R1 +key 0x138 BUTTON_L2 +key 0x139 BUTTON_R2 + +# L2 axis +axis 0x02 LTRIGGER +# R2 axis +axis 0x05 RTRIGGER + +# Left Analog Stick +axis 0x00 X +axis 0x01 Y +# Right Analog Stick +axis 0x03 Z +axis 0x04 RZ + +# Left stick click +key 0x13d BUTTON_THUMBL +# Right stick click +key 0x13e BUTTON_THUMBR + +# Hat +axis 0x10 HAT_X +axis 0x11 HAT_Y + +# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt +# Share +key 0x13a BUTTON_SELECT +# Options +key 0x13b BUTTON_START +# PS key +key 0x13c BUTTON_MODE + +# In kernel versions >= 4.10, the touchpad is a separate input device, +# so the touchpad button click will not be covered by this layout. diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h index e4cd6a8ab6b8..6c9eee0b8835 100644 --- a/libs/androidfw/include/androidfw/Util.h +++ b/libs/androidfw/include/androidfw/Util.h @@ -47,11 +47,11 @@ class unique_cptr { constexpr unique_cptr() : ptr_(nullptr) {} constexpr unique_cptr(std::nullptr_t) : ptr_(nullptr) {} explicit unique_cptr(pointer ptr) : ptr_(ptr) {} - unique_cptr(unique_cptr&& o) : ptr_(o.ptr_) { o.ptr_ = nullptr; } + unique_cptr(unique_cptr&& o) noexcept : ptr_(o.ptr_) { o.ptr_ = nullptr; } ~unique_cptr() { std::free(reinterpret_cast<void*>(ptr_)); } - inline unique_cptr& operator=(unique_cptr&& o) { + inline unique_cptr& operator=(unique_cptr&& o) noexcept { if (&o == this) { return *this; } diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index e6d2a6f555ac..f2d50cd42523 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -146,7 +146,7 @@ void JankTracker::finishFrame(const FrameInfo& frame) { frame[FrameInfoIndex::IntendedVsync] + mFrameInterval); // If we hit the deadline, cool! - if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline) { + if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadline || totalDuration < mFrameInterval) { if (isTripleBuffered) { mData->reportJankType(JankType::kHighInputLatency); (*mGlobalData)->reportJankType(JankType::kHighInputLatency); diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 02e1f2f530d1..2eed70f023b1 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -159,8 +159,9 @@ public class MediaScanner implements AutoCloseable { public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild"; public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint"; - private static final String SYSTEM_SOUNDS_DIR = "/system/media/audio"; - private static final String PRODUCT_SOUNDS_DIR = "/product/media/audio"; + private static final String SYSTEM_SOUNDS_DIR = Environment.getRootDirectory() + "/media/audio"; + private static final String OEM_SOUNDS_DIR = Environment.getOemDirectory() + "/media/audio"; + private static final String PRODUCT_SOUNDS_DIR = Environment.getProductDirectory() + "/media/audio"; private static String sLastInternalScanFingerprint; private static final String[] ID3_GENRES = { @@ -1192,6 +1193,9 @@ public class MediaScanner implements AutoCloseable { if (path.startsWith(SYSTEM_SOUNDS_DIR + ALARMS_DIR) || path.startsWith(SYSTEM_SOUNDS_DIR + RINGTONES_DIR) || path.startsWith(SYSTEM_SOUNDS_DIR + NOTIFICATIONS_DIR) + || path.startsWith(OEM_SOUNDS_DIR + ALARMS_DIR) + || path.startsWith(OEM_SOUNDS_DIR + RINGTONES_DIR) + || path.startsWith(OEM_SOUNDS_DIR + NOTIFICATIONS_DIR) || path.startsWith(PRODUCT_SOUNDS_DIR + ALARMS_DIR) || path.startsWith(PRODUCT_SOUNDS_DIR + RINGTONES_DIR) || path.startsWith(PRODUCT_SOUNDS_DIR + NOTIFICATIONS_DIR)) { diff --git a/media/jni/OWNERS b/media/jni/OWNERS new file mode 100644 index 000000000000..bb91d4b26ecc --- /dev/null +++ b/media/jni/OWNERS @@ -0,0 +1,2 @@ +# extra for MTP related files +per-file android_mtp_*.cpp=marcone@google.com,jsharkey@android.com,jameswei@google.com,rmojumder@google.com diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS new file mode 100644 index 000000000000..1928ba811e7e --- /dev/null +++ b/media/tests/MtpTests/OWNERS @@ -0,0 +1,7 @@ +set noparent + +marcone@google.com +jsharkey@android.com +jameswei@google.com +rmojumder@google.com + diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index fd1212af3cfa..774a035e4b52 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -130,6 +130,22 @@ public class CaptivePortalLoginActivity extends Activity { mProbeSpec = null; } + mNetworkCallback = new NetworkCallback() { + @Override + public void onLost(Network lostNetwork) { + // If the network disappears while the app is up, exit. + if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED); + } + }; + mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkCallback); + + // If the network has disappeared, exit. + final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork); + if (networkCapabilities == null) { + finishAndRemoveTask(); + return; + } + // Also initializes proxy system properties. mNetwork = mNetwork.getPrivateDnsBypassingCopy(); mCm.bindProcessToNetwork(mNetwork); @@ -139,24 +155,6 @@ public class CaptivePortalLoginActivity extends Activity { // setContentView initializes the WebView logic which in turn reads the system properties. setContentView(R.layout.activity_captive_portal_login); - // Exit app if Network disappears. - final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork); - if (networkCapabilities == null) { - finishAndRemoveTask(); - return; - } - mNetworkCallback = new NetworkCallback() { - @Override - public void onLost(Network lostNetwork) { - if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED); - } - }; - final NetworkRequest.Builder builder = new NetworkRequest.Builder(); - for (int transportType : networkCapabilities.getTransportTypes()) { - builder.addTransportType(transportType); - } - mCm.registerNetworkCallback(builder.build(), mNetworkCallback); - getActionBar().setDisplayShowHomeEnabled(false); getActionBar().setElevation(0); // remove shadow getActionBar().setTitle(getHeaderTitle()); diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index a46c3e64c163..76a216d1be48 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -1125,4 +1125,7 @@ <!-- time label for event have that happened very recently [CHAR LIMIT=60] --> <string name="time_unit_just_now">Just now</string> + + <!-- The notice header of Third-party licenses. not translatable --> + <string name="notice_header" translatable="false"></string> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 541877cc28ca..3c5816096f8c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -105,7 +105,7 @@ public class A2dpProfile implements LocalBluetoothProfile { BluetoothProfile.A2DP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java index 0e0f63cb084c..656f23ffb70c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java @@ -99,7 +99,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile { BluetoothProfile.A2DP_SINK); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index e96c44db695b..8fa95977c5ce 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -250,7 +250,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int preferredProfiles = 0; for (LocalBluetoothProfile profile : mProfiles) { - if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) { + if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (profile.isPreferred(mDevice)) { ++preferredProfiles; connectInt(profile); @@ -736,7 +736,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> List<LocalBluetoothProfile> connectableProfiles = new ArrayList<LocalBluetoothProfile>(); for (LocalBluetoothProfile profile : mProfiles) { - if (profile.isConnectable()) { + if (profile.accessProfileEnabled()) { connectableProfiles.add(profile); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java index 7f838600c5ee..3bb8450207ab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java @@ -106,7 +106,7 @@ public class HeadsetProfile implements LocalBluetoothProfile { BluetoothProfile.HEADSET); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index 1d2fda94deaa..06d60e6e9d47 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -103,7 +103,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { BluetoothProfile.HEARING_AID); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java index 0857b019ee64..4ae9b328edaa 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java @@ -107,7 +107,7 @@ final class HfpClientProfile implements LocalBluetoothProfile { } @Override - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java index ca1eea522cd0..1c04e83f771e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java @@ -29,7 +29,7 @@ import com.android.settingslib.R; import java.util.List; /** - * HidProfile handles Bluetooth HID profile. + * HidDeviceProfile handles Bluetooth HID Device role */ public class HidDeviceProfile implements LocalBluetoothProfile { private static final String TAG = "HidDeviceProfile"; @@ -37,7 +37,6 @@ public class HidDeviceProfile implements LocalBluetoothProfile { private static final int ORDINAL = 18; // HID Device Profile is always preferred. private static final int PREFERRED_VALUE = -1; - private static final boolean DEBUG = true; private final LocalBluetoothAdapter mLocalAdapter; private final CachedBluetoothDeviceManager mDeviceManager; @@ -62,9 +61,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (DEBUG) { - Log.d(TAG,"Bluetooth service connected :-)"); - } + Log.d(TAG, "Bluetooth service connected :-), profile:" + profile); mService = (BluetoothHidDevice) proxy; // We just bound to the service, so refresh the UI for any connected HID devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -84,9 +81,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (DEBUG) { - Log.d(TAG, "Bluetooth service disconnected"); - } + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady = false; } } @@ -102,7 +97,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } @Override - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } @@ -113,6 +108,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { @Override public boolean connect(BluetoothDevice device) { + // Don't invoke method in service because settings is not allowed to connect this profile. return false; } @@ -129,11 +125,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { if (mService == null) { return BluetoothProfile.STATE_DISCONNECTED; } - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - - return !deviceList.isEmpty() && deviceList.contains(device) - ? mService.getConnectionState(device) - : BluetoothProfile.STATE_DISCONNECTED; + return mService.getConnectionState(device); } @Override @@ -188,9 +180,7 @@ public class HidDeviceProfile implements LocalBluetoothProfile { } protected void finalize() { - if (DEBUG) { - Log.d(TAG, "finalize()"); - } + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HID_DEVICE, diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java index dc17e44cb08d..1e064818cc72 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java @@ -95,7 +95,7 @@ public class HidProfile implements LocalBluetoothProfile { BluetoothProfile.HID_HOST); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java index 0447f378fca1..4b0ca7434f9a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java @@ -26,9 +26,9 @@ import android.bluetooth.BluetoothDevice; public interface LocalBluetoothProfile { /** - * Returns true if the user can initiate a connection, false otherwise. + * Return {@code true} if the user can initiate a connection for this profile in UI. */ - boolean isConnectable(); + boolean accessProfileEnabled(); /** * Returns true if the user can enable auto connection for this profile. diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index 08fbbedac19c..75cbb6589037 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -29,6 +29,7 @@ import android.bluetooth.BluetoothMapClient; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothPbap; import android.bluetooth.BluetoothPbapClient; +import android.bluetooth.BluetoothSap; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.content.Context; @@ -101,6 +102,7 @@ public class LocalBluetoothProfileManager { private final boolean mUsePbapPce; private final boolean mUseMapClient; private HearingAidProfile mHearingAidProfile; + private SapProfile mSapProfile; /** * Mapping from profile name, e.g. "HEADSET" to profile object. @@ -196,12 +198,14 @@ public class LocalBluetoothProfileManager { if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) { if (mA2dpSinkProfile == null) { if(DEBUG) Log.d(TAG, "Adding local A2DP Sink profile"); - mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this); + mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, + mDeviceManager, this); addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME, BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); } } else if (mA2dpSinkProfile != null) { - Log.w(TAG, "Warning: A2DP Sink profile was previously added but the UUID is now missing."); + Log.w(TAG, "Warning: A2DP Sink profile was previously added but the " + + "UUID is now missing."); } // Headset / Handsfree @@ -217,7 +221,8 @@ public class LocalBluetoothProfileManager { BluetoothHeadset.STATE_AUDIO_DISCONNECTED); } } else if (mHeadsetProfile != null) { - Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing."); + Log.w(TAG, "Warning: HEADSET profile was previously added but the " + + "UUID is now missing."); } // Headset HF @@ -249,7 +254,8 @@ public class LocalBluetoothProfileManager { } } else if (mMapClientProfile != null) { Log.w(TAG, - "Warning: MAP Client profile was previously added but the UUID is now missing."); + "Warning: MAP Client profile was previously added but the " + + "UUID is now missing."); } else { Log.d(TAG, "MAP Client Uuid not found."); } @@ -266,7 +272,7 @@ public class LocalBluetoothProfileManager { Log.w(TAG, "Warning: OPP profile was previously added but the UUID is now missing."); } - //PBAP Client + // PBAP Client if (mUsePbapPce) { if (mPbapClientProfile == null) { if(DEBUG) Log.d(TAG, "Adding local PBAP Client profile"); @@ -280,18 +286,27 @@ public class LocalBluetoothProfileManager { "Warning: PBAP Client profile was previously added but the UUID is now missing."); } - //Hearing Aid Client + // Hearing Aid Client if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) { if (mHearingAidProfile == null) { if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile"); - mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this); + mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, + mDeviceManager, this); addProfile(mHearingAidProfile, HearingAidProfile.NAME, BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); } } else if (mHearingAidProfile != null) { - Log.w(TAG, "Warning: Hearing Aid profile was previously added but the UUID is now missing."); + Log.w(TAG, "Warning: Hearing Aid profile was previously added but the " + + "UUID is now missing."); } + // SAP + if (mSapProfile == null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) { + Log.d(TAG, "Adding local SAP profile"); + mSapProfile = new SapProfile(mContext, mLocalAdapter, mDeviceManager, this); + addProfile(mSapProfile, SapProfile.NAME, + BluetoothSap.ACTION_CONNECTION_STATE_CHANGED); + } mEventManager.registerProfileIntentReceiver(); // There is no local SDP record for HID and Settings app doesn't control PBAP Server. @@ -635,6 +650,11 @@ public class LocalBluetoothProfileManager { removedProfiles.remove(mHearingAidProfile); } + if (mSapProfile != null && BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.SAP)) { + profiles.add(mSapProfile); + removedProfiles.remove(mSapProfile); + } + if (DEBUG) { Log.d(TAG,"New Profiles" + profiles.toString()); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java index ad0d8ba7ebab..57712e3cbb28 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java @@ -32,11 +32,10 @@ import java.util.ArrayList; import java.util.List; /** - * MapClientProfile handles Bluetooth MAP profile. + * MapClientProfile handles the Bluetooth MAP MCE role. */ public final class MapClientProfile implements LocalBluetoothProfile { private static final String TAG = "MapClientProfile"; - private static boolean V = false; private BluetoothMapClient mService; private boolean mIsProfileReady; @@ -61,7 +60,7 @@ public final class MapClientProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothMapClient) proxy; // We just bound to the service, so refresh the UI for any connected MAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -83,14 +82,14 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } } public boolean isProfileReady() { - if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady); + Log.d(TAG, "isProfileReady(): "+ mIsProfileReady); return mIsProfileReady; } @@ -109,7 +108,7 @@ public final class MapClientProfile implements LocalBluetoothProfile { BluetoothProfile.MAP_CLIENT); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } @@ -118,18 +117,16 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> connectedDevices = getConnectedDevices(); - if (connectedDevices != null && connectedDevices.contains(device)) { - // Connect to same device, Ignore it - Log.d(TAG,"Ignoring Connect"); - return true; + if (mService == null) { + return false; } return mService.connect(device); } public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } // Downgrade priority as user is disconnecting. if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -138,23 +135,30 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public int getConnectionStatus(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.STATE_DISCONNECTED; - + if (mService == null) { + return BluetoothProfile.STATE_DISCONNECTED; + } return mService.getConnectionState(device); } public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -165,7 +169,9 @@ public final class MapClientProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -203,11 +209,11 @@ public final class MapClientProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT, - mService); + mService); mService = null; }catch (Throwable t) { Log.w(TAG, "Error cleaning up MAP Client proxy", t); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java index 511c4ce678e2..e59a036731d9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java @@ -107,7 +107,7 @@ public class MapProfile implements LocalBluetoothProfile { BluetoothProfile.MAP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java index dfd16224ef8f..e1e5dbe29a1a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java @@ -32,7 +32,7 @@ final class OppProfile implements LocalBluetoothProfile { // Order of this profile in device profiles list private static final int ORDINAL = 2; - public boolean isConnectable() { + public boolean accessProfileEnabled() { return false; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java index b18b19b1e244..0d566c77eac2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java @@ -80,7 +80,7 @@ public class PanProfile implements LocalBluetoothProfile { BluetoothProfile.PAN); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java index bdbfc9df59dd..c83ff359b138 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java @@ -34,7 +34,6 @@ import java.util.List; public final class PbapClientProfile implements LocalBluetoothProfile { private static final String TAG = "PbapClientProfile"; - private static boolean V = false; private BluetoothPbapClient mService; private boolean mIsProfileReady; @@ -57,9 +56,7 @@ public final class PbapClientProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) { - Log.d(TAG,"Bluetooth service connected"); - } + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothPbapClient) proxy; // We just bound to the service, so refresh the UI for any connected PBAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -78,9 +75,7 @@ public final class PbapClientProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) { - Log.d(TAG,"Bluetooth service disconnected"); - } + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mIsProfileReady = false; } } @@ -115,7 +110,7 @@ public final class PbapClientProfile implements LocalBluetoothProfile { BluetoothProfile.PBAP_CLIENT); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } @@ -134,31 +129,16 @@ public final class PbapClientProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if (V) { - Log.d(TAG,"PBAPClientProfile got connect request"); - } + Log.d(TAG,"PBAPClientProfile got connect request"); if (mService == null) { return false; } - List<BluetoothDevice> srcs = getConnectedDevices(); - if (srcs != null) { - for (BluetoothDevice src : srcs) { - if (src.equals(device)) { - // Connect to same device, Ignore it - Log.d(TAG,"Ignoring Connect"); - return true; - } - } - } Log.d(TAG,"PBAPClientProfile attempting to connect to " + device.getAddress()); - return mService.connect(device); } public boolean disconnect(BluetoothDevice device) { - if (V) { - Log.d(TAG,"PBAPClientProfile got disconnect request"); - } + Log.d(TAG,"PBAPClientProfile got disconnect request"); if (mService == null) { return false; } @@ -221,9 +201,7 @@ public final class PbapClientProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) { - Log.d(TAG, "finalize()"); - } + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy( diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java index e9d8cb5a4b2b..adef0841cb2a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java @@ -80,7 +80,7 @@ public class PbapServerProfile implements LocalBluetoothProfile { BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener()); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java index 2c455d5f4c32..e83c62d7c222 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java @@ -36,7 +36,6 @@ import java.util.List; */ final class SapProfile implements LocalBluetoothProfile { private static final String TAG = "SapProfile"; - private static boolean V = true; private BluetoothSap mService; private boolean mIsProfileReady; @@ -59,7 +58,7 @@ final class SapProfile implements LocalBluetoothProfile { implements BluetoothProfile.ServiceListener { public void onServiceConnected(int profile, BluetoothProfile proxy) { - if (V) Log.d(TAG,"Bluetooth service connected"); + Log.d(TAG, "Bluetooth service connected, profile:" + profile); mService = (BluetoothSap) proxy; // We just bound to the service, so refresh the UI for any connected SAP devices. List<BluetoothDevice> deviceList = mService.getConnectedDevices(); @@ -81,7 +80,7 @@ final class SapProfile implements LocalBluetoothProfile { } public void onServiceDisconnected(int profile) { - if (V) Log.d(TAG,"Bluetooth service disconnected"); + Log.d(TAG, "Bluetooth service disconnected, profile:" + profile); mProfileManager.callServiceDisconnectedListeners(); mIsProfileReady=false; } @@ -106,7 +105,7 @@ final class SapProfile implements LocalBluetoothProfile { BluetoothProfile.SAP); } - public boolean isConnectable() { + public boolean accessProfileEnabled() { return true; } @@ -115,50 +114,47 @@ final class SapProfile implements LocalBluetoothProfile { } public boolean connect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> sinks = mService.getConnectedDevices(); - if (sinks != null) { - for (BluetoothDevice sink : sinks) { - mService.disconnect(sink); - } + if (mService == null) { + return false; } return mService.connect(device); } public boolean disconnect(BluetoothDevice device) { - if (mService == null) return false; - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) { - if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { - mService.setPriority(device, BluetoothProfile.PRIORITY_ON); - } - return mService.disconnect(device); - } else { + if (mService == null) { return false; } + if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { + mService.setPriority(device, BluetoothProfile.PRIORITY_ON); + } + return mService.disconnect(device); } public int getConnectionStatus(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.STATE_DISCONNECTED; - List<BluetoothDevice> deviceList = mService.getConnectedDevices(); - - return !deviceList.isEmpty() && deviceList.get(0).equals(device) - ? mService.getConnectionState(device) - : BluetoothProfile.STATE_DISCONNECTED; + if (mService == null) { + return BluetoothProfile.STATE_DISCONNECTED; + } + return mService.getConnectionState(device); } public boolean isPreferred(BluetoothDevice device) { - if (mService == null) return false; + if (mService == null) { + return false; + } return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; } public int getPreferred(BluetoothDevice device) { - if (mService == null) return BluetoothProfile.PRIORITY_OFF; + if (mService == null) { + return BluetoothProfile.PRIORITY_OFF; + } return mService.getPriority(device); } public void setPreferred(BluetoothDevice device, boolean preferred) { - if (mService == null) return; + if (mService == null) { + return; + } if (preferred) { if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -169,7 +165,9 @@ final class SapProfile implements LocalBluetoothProfile { } public List<BluetoothDevice> getConnectedDevices() { - if (mService == null) return new ArrayList<BluetoothDevice>(0); + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -207,11 +205,11 @@ final class SapProfile implements LocalBluetoothProfile { } protected void finalize() { - if (V) Log.d(TAG, "finalize()"); + Log.d(TAG, "finalize()"); if (mService != null) { try { BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.SAP, - mService); + mService); mService = null; }catch (Throwable t) { Log.w(TAG, "Error cleaning up SAP proxy", t); diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java index 42306f6d46d0..9870b3c9d754 100644 --- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java +++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java @@ -107,12 +107,13 @@ class LicenseHtmlGeneratorFromXml { mXmlFiles = xmlFiles; } - public static boolean generateHtml(List<File> xmlFiles, File outputFile) { + public static boolean generateHtml(List<File> xmlFiles, File outputFile, + String noticeHeader) { LicenseHtmlGeneratorFromXml genertor = new LicenseHtmlGeneratorFromXml(xmlFiles); - return genertor.generateHtml(outputFile); + return genertor.generateHtml(outputFile, noticeHeader); } - private boolean generateHtml(File outputFile) { + private boolean generateHtml(File outputFile, String noticeHeader) { for (File xmlFile : mXmlFiles) { parse(xmlFile); } @@ -125,7 +126,8 @@ class LicenseHtmlGeneratorFromXml { try { writer = new PrintWriter(outputFile); - generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer); + generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer, + noticeHeader); writer.flush(); writer.close(); @@ -239,13 +241,18 @@ class LicenseHtmlGeneratorFromXml { @VisibleForTesting static void generateHtml(Map<String, String> fileNameToContentIdMap, - Map<String, String> contentIdToFileContentMap, PrintWriter writer) { + Map<String, String> contentIdToFileContentMap, PrintWriter writer, + String noticeHeader) { List<String> fileNameList = new ArrayList(); fileNameList.addAll(fileNameToContentIdMap.keySet()); Collections.sort(fileNameList); writer.println(HTML_HEAD_STRING); + if (!TextUtils.isEmpty(noticeHeader)) { + writer.println(noticeHeader); + } + int count = 0; Map<String, Integer> contentIdToOrderMap = new HashMap(); List<ContentIdAndFileNames> contentIdAndFileNamesList = new ArrayList(); diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java index 2aaea657d29f..8b562f7066c3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java +++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoader.java @@ -21,6 +21,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; +import com.android.settingslib.R; import com.android.settingslib.utils.AsyncLoader; import java.io.File; @@ -108,6 +109,7 @@ public class LicenseHtmlLoader extends AsyncLoader<File> { @VisibleForTesting boolean generateHtmlFile(List<File> xmlFiles, File htmlFile) { - return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile); + return LicenseHtmlGeneratorFromXml.generateHtml(xmlFiles, htmlFile, + mContext.getString(R.string.notice_header)); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java new file mode 100644 index 000000000000..354d9261dcb5 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HidDeviceProfileTest.java @@ -0,0 +1,92 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHidDevice; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class HidDeviceProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothHidDevice mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private HidDeviceProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.HID_DEVICE)); + + mProfile = new HidDeviceProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.HID_DEVICE, mService); + } + + @Test + public void connect_shouldReturnFalse() { + assertThat(mProfile.connect(mBluetoothDevice)).isFalse(); + } + + @Test + public void disconnect_shouldDisconnectBluetoothHidDevice() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java new file mode 100644 index 000000000000..97c9f1817a64 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/MapClientProfileTest.java @@ -0,0 +1,93 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothMapClient; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class MapClientProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothMapClient mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private MapClientProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.MAP_CLIENT)); + + mProfile = new MapClientProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT, mService); + } + + @Test + public void connect_shouldConnectBluetoothMapClient() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothMapClient() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.java new file mode 100644 index 000000000000..45b52b2e11b6 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PbapClientProfileTest.java @@ -0,0 +1,93 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothPbapClient; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class PbapClientProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothPbapClient mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private PbapClientProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.PBAP_CLIENT)); + + mProfile = new PbapClientProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.PBAP_CLIENT, mService); + } + + @Test + public void connect_shouldConnectBluetoothPbapClient() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothPbapClient() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java new file mode 100644 index 000000000000..6ff3e7085b3c --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/SapProfileTest.java @@ -0,0 +1,93 @@ +/* + * 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.settingslib.bluetooth; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; + +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSap; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +@RunWith(SettingsLibRobolectricTestRunner.class) +public class SapProfileTest { + + @Mock + private LocalBluetoothAdapter mAdapter; + @Mock + private CachedBluetoothDeviceManager mDeviceManager; + @Mock + private LocalBluetoothProfileManager mProfileManager; + @Mock + private BluetoothSap mService; + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + @Mock + private BluetoothDevice mBluetoothDevice; + private BluetoothProfile.ServiceListener mServiceListener; + private SapProfile mProfile; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + doAnswer((invocation) -> { + mServiceListener = (BluetoothProfile.ServiceListener) invocation.getArguments()[1]; + return null; + }).when(mAdapter).getProfileProxy(any(Context.class), + any(BluetoothProfile.ServiceListener.class), eq(BluetoothProfile.SAP)); + + mProfile = new SapProfile(RuntimeEnvironment.application, mAdapter, + mDeviceManager, mProfileManager); + mServiceListener.onServiceConnected(BluetoothProfile.SAP, mService); + } + + @Test + public void connect_shouldConnectBluetoothSap() { + mProfile.connect(mBluetoothDevice); + verify(mService).connect(mBluetoothDevice); + } + + @Test + public void disconnect_shouldDisconnectBluetoothSap() { + mProfile.disconnect(mBluetoothDevice); + verify(mService).disconnect(mBluetoothDevice); + } + + @Test + public void getConnectionStatus_shouldReturnConnectionState() { + when(mService.getConnectionState(mBluetoothDevice)). + thenReturn(BluetoothProfile.STATE_CONNECTED); + assertThat(mProfile.getConnectionStatus(mBluetoothDevice)). + isEqualTo(BluetoothProfile.STATE_CONNECTED); + } +}
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java index 96b2a1433f53..b00476b24921 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java @@ -50,7 +50,7 @@ public class LicenseHtmlGeneratorFromXmlTest { + "<file-content contentId=\"0\"><![CDATA[license content #0]]></file-content>\n" + "</licenses2>"; - private static final String EXPECTED_HTML_STRING = + private static final String HTML_HEAD_STRING = "<html><head>\n" + "<style type=\"text/css\">\n" + "body { padding: 0; font-family: sans-serif; }\n" @@ -63,8 +63,12 @@ public class LicenseHtmlGeneratorFromXmlTest { + "</head>" + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n" + "<div class=\"toc\">\n" - + "<ul>\n" - + "<li><a href=\"#id0\">/file0</a></li>\n" + + "<ul>\n"; + + private static final String HTML_CUSTOM_HEADING = "Custom heading"; + + private static final String HTML_BODY_STRING = + "<li><a href=\"#id0\">/file0</a></li>\n" + "<li><a href=\"#id0\">/file1</a></li>\n" + "</ul>\n" + "</div><!-- table of contents -->\n" @@ -81,6 +85,11 @@ public class LicenseHtmlGeneratorFromXmlTest { + "</td></tr><!-- same-license -->\n" + "</table></body></html>\n"; + private static final String EXPECTED_HTML_STRING = HTML_HEAD_STRING + HTML_BODY_STRING; + + private static final String EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING = + HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_BODY_STRING; + @Test public void testParseValidXmlStream() throws XmlPullParserException, IOException { Map<String, String> fileNameToContentIdMap = new HashMap<String, String>(); @@ -117,7 +126,23 @@ public class LicenseHtmlGeneratorFromXmlTest { StringWriter output = new StringWriter(); LicenseHtmlGeneratorFromXml.generateHtml( - fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output)); + fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), ""); assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING); } + + @Test + public void testGenerateHtmlWithCustomHeading() { + Map<String, String> fileNameToContentIdMap = new HashMap<String, String>(); + Map<String, String> contentIdToFileContentMap = new HashMap<String, String>(); + + fileNameToContentIdMap.put("/file0", "0"); + fileNameToContentIdMap.put("/file1", "0"); + contentIdToFileContentMap.put("0", "license content #0"); + + StringWriter output = new StringWriter(); + LicenseHtmlGeneratorFromXml.generateHtml( + fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), + HTML_CUSTOM_HEADING); + assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING); + } } diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 4fc190d43056..2530abc765da 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -16,6 +16,8 @@ package com.android.shell; +import static android.content.pm.PackageManager.FEATURE_LEANBACK; +import static android.content.pm.PackageManager.FEATURE_TELEVISION; import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static com.android.shell.BugreportPrefs.STATE_HIDE; @@ -42,6 +44,7 @@ import java.util.zip.ZipOutputStream; import libcore.io.Streams; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ChooserActivity; import com.android.internal.logging.MetricsLogger; @@ -232,9 +235,11 @@ public class BugreportProgressService extends Service { */ private boolean mTakingScreenshot; + @GuardedBy("sNotificationBundle") private static final Bundle sNotificationBundle = new Bundle(); private boolean mIsWatch; + private boolean mIsTv; private int mLastProgressPercent; @@ -255,6 +260,9 @@ public class BugreportProgressService extends Service { final Configuration conf = mContext.getResources().getConfiguration(); mIsWatch = (conf.uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH; + PackageManager packageManager = getPackageManager(); + mIsTv = packageManager.hasSystemFeature(FEATURE_LEANBACK) + || packageManager.hasSystemFeature(FEATURE_TELEVISION); NotificationManager nm = NotificationManager.from(mContext); nm.createNotificationChannel( new NotificationChannel(NOTIFICATION_CHANNEL_ID, @@ -500,8 +508,8 @@ public class BugreportProgressService extends Service { .setProgress(info.max, info.progress, false) .setOngoing(true); - // Wear bugreport doesn't need the bug info dialog, screenshot and cancel action. - if (!mIsWatch) { + // Wear and ATV bugreport doesn't need the bug info dialog, screenshot and cancel action. + if (!(mIsWatch || mIsTv)) { final Action cancelAction = new Action.Builder(null, mContext.getString( com.android.internal.R.string.cancel), newCancelIntent(mContext, info)).build(); final Intent infoIntent = new Intent(mContext, BugreportProgressService.class); @@ -1053,10 +1061,12 @@ public class BugreportProgressService extends Service { } private static Notification.Builder newBaseNotification(Context context) { - if (sNotificationBundle.isEmpty()) { - // Rename notifcations from "Shell" to "Android System" - sNotificationBundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, - context.getString(com.android.internal.R.string.android_system_label)); + synchronized (sNotificationBundle) { + if (sNotificationBundle.isEmpty()) { + // Rename notifcations from "Shell" to "Android System" + sNotificationBundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, + context.getString(com.android.internal.R.string.android_system_label)); + } } return new Notification.Builder(context, NOTIFICATION_CHANNEL_ID) .addExtras(sNotificationBundle) diff --git a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java index 0734e0dae790..4fbc22663675 100644 --- a/packages/Shell/src/com/android/shell/BugreportStorageProvider.java +++ b/packages/Shell/src/com/android/shell/BugreportStorageProvider.java @@ -20,6 +20,7 @@ import android.database.Cursor; import android.database.MatrixCursor; import android.database.MatrixCursor.RowBuilder; import android.net.Uri; +import android.os.Bundle; import android.os.CancellationSignal; import android.os.FileUtils; import android.os.ParcelFileDescriptor; @@ -68,6 +69,18 @@ public class BugreportStorageProvider extends FileSystemProvider { } @Override + public Cursor queryChildDocuments( + String parentDocumentId, String[] projection, String sortOrder) + throws FileNotFoundException { + final Cursor c = super.queryChildDocuments(parentDocumentId, projection, sortOrder); + final Bundle extras = new Bundle(); + extras.putCharSequence(DocumentsContract.EXTRA_INFO, + getContext().getText(R.string.bugreport_confirm)); + c.setExtras(extras); + return c; + } + + @Override public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException { if (DOC_ID_ROOT.equals(documentId)) { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java index cd831d1e31f6..0c498bb8d2c7 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java @@ -24,8 +24,6 @@ import android.util.DisplayMetrics; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import sun.misc.Resource; - public class NavigationBarCompat { /** * Touch slopes and thresholds for quick step operations. Drag slop is the point where the diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 9e4810cb08ca..35abb0a523a1 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -342,12 +342,11 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe case SimPuk: // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); - if (securityMode != SecurityMode.None - || !mLockPatternUtils.isLockScreenDisabled( + if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser())) { - showSecurityScreen(securityMode); - } else { finish = true; + } else { + showSecurityScreen(securityMode); } break; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 760209024c57..953c99ff2474 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -35,6 +35,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_VPN; +import static android.os.Process.INVALID_UID; +import static android.system.OsConstants.IPPROTO_TCP; +import static android.system.OsConstants.IPPROTO_UDP; import static com.android.internal.util.Preconditions.checkNotNull; @@ -49,10 +52,12 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.database.ContentObserver; +import android.net.ConnectionInfo; import android.net.ConnectivityManager; import android.net.ConnectivityManager.PacketKeepalive; import android.net.IConnectivityManager; import android.net.IIpConnectivityMetrics; +import android.net.INetd; import android.net.INetdEventCallback; import android.net.INetworkManagementEventObserver; import android.net.INetworkPolicyListener; @@ -75,7 +80,6 @@ import android.net.NetworkSpecifier; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.NetworkWatchlistManager; -import android.net.Proxy; import android.net.ProxyInfo; import android.net.RouteInfo; import android.net.UidRange; @@ -83,7 +87,9 @@ import android.net.Uri; import android.net.VpnService; import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; +import android.net.netlink.InetDiagMessage; import android.net.util.MultinetworkPolicyTracker; +import android.net.util.NetdService; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -153,7 +159,6 @@ import com.android.server.connectivity.NetworkDiagnostics; import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.NetworkNotificationManager; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; -import com.android.server.connectivity.PacManager; import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.Tethering; @@ -256,7 +261,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // 0 is full bad, 100 is full good private int mDefaultInetConditionPublished = 0; - private INetworkManagementService mNetd; + private INetworkManagementService mNMS; + private INetd mNetd; private INetworkStatsService mStatsService; private INetworkPolicyManager mPolicyManager; private NetworkPolicyManagerInternal mPolicyManagerInternal; @@ -387,9 +393,9 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int EVENT_PROMPT_UNVALIDATED = 29; /** - * used internally to (re)configure mobile data always-on settings. + * used internally to (re)configure always-on networks. */ - private static final int EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON = 30; + private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30; /** * used to add a network listener with a pending intent @@ -745,6 +751,12 @@ public class ConnectivityService extends IConnectivityManager.Stub mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); + // The default WiFi request is a background request so that apps using WiFi are + // migrated to a better network (typically ethernet) when one comes up, instead + // of staying on WiFi forever. + mDefaultWifiRequest = createDefaultInternetRequestForTransport( + NetworkCapabilities.TRANSPORT_WIFI, NetworkRequest.Type.BACKGROUND_REQUEST); + mHandlerThread = new HandlerThread("ConnectivityServiceThread"); mHandlerThread.start(); mHandler = new InternalHandler(mHandlerThread.getLooper()); @@ -756,7 +768,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); mContext = checkNotNull(context, "missing Context"); - mNetd = checkNotNull(netManager, "missing INetworkManagementService"); + mNMS = checkNotNull(netManager, "missing INetworkManagementService"); mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); mPolicyManagerInternal = checkNotNull( @@ -764,6 +776,7 @@ public class ConnectivityService extends IConnectivityManager.Stub "missing NetworkPolicyManagerInternal"); mProxyTracker = new ProxyTracker(context, mHandler, EVENT_PROXY_HAS_CHANGED); + mNetd = NetdService.getInstance(); mKeyStore = KeyStore.getInstance(); mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); @@ -846,7 +859,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mTethering = makeTethering(); - mPermissionMonitor = new PermissionMonitor(mContext, mNetd); + mPermissionMonitor = new PermissionMonitor(mContext, mNMS); //set up the listener for user state for creating user VPNs IntentFilter intentFilter = new IntentFilter(); @@ -861,8 +874,8 @@ public class ConnectivityService extends IConnectivityManager.Stub new IntentFilter(Intent.ACTION_USER_PRESENT), null, null); try { - mNetd.registerObserver(mTethering); - mNetd.registerObserver(mDataActivityObserver); + mNMS.registerObserver(mTethering); + mNMS.registerObserver(mDataActivityObserver); } catch (RemoteException e) { loge("Error registering observer :" + e); } @@ -893,7 +906,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mMultipathPolicyTracker = new MultipathPolicyTracker(mContext, mHandler); - mDnsManager = new DnsManager(mContext, mNetd, mSystemProperties); + mDnsManager = new DnsManager(mContext, mNMS, mSystemProperties); registerPrivateDnsSettingsCallbacks(); } @@ -909,7 +922,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return mDefaultRequest; } }; - return new Tethering(mContext, mNetd, mStatsService, mPolicyManager, + return new Tethering(mContext, mNMS, mStatsService, mPolicyManager, IoThread.get().getLooper(), new MockableSystemProperties(), deps); } @@ -941,8 +954,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // 2. Give FakeSettingsProvider an alternative notification mechanism and have the test use it // by subclassing SettingsObserver. @VisibleForTesting - void updateMobileDataAlwaysOn() { - mHandler.sendEmptyMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON); + void updateAlwaysOnNetworks() { + mHandler.sendEmptyMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); } // See FakeSettingsProvider comment above. @@ -951,22 +964,30 @@ public class ConnectivityService extends IConnectivityManager.Stub mHandler.sendEmptyMessage(EVENT_PRIVATE_DNS_SETTINGS_CHANGED); } - private void handleMobileDataAlwaysOn() { + private void handleAlwaysOnNetworkRequest( + NetworkRequest networkRequest, String settingName, boolean defaultValue) { final boolean enable = toBool(Settings.Global.getInt( - mContext.getContentResolver(), Settings.Global.MOBILE_DATA_ALWAYS_ON, 1)); - final boolean isEnabled = (mNetworkRequests.get(mDefaultMobileDataRequest) != null); + mContext.getContentResolver(), settingName, encodeBool(defaultValue))); + final boolean isEnabled = (mNetworkRequests.get(networkRequest) != null); if (enable == isEnabled) { return; // Nothing to do. } if (enable) { handleRegisterNetworkRequest(new NetworkRequestInfo( - null, mDefaultMobileDataRequest, new Binder())); + null, networkRequest, new Binder())); } else { - handleReleaseNetworkRequest(mDefaultMobileDataRequest, Process.SYSTEM_UID); + handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID); } } + private void handleConfigureAlwaysOnNetworks() { + handleAlwaysOnNetworkRequest( + mDefaultMobileDataRequest,Settings.Global.MOBILE_DATA_ALWAYS_ON, true); + handleAlwaysOnNetworkRequest(mDefaultWifiRequest, Settings.Global.WIFI_ALWAYS_REQUESTED, + false); + } + private void registerSettingsCallbacks() { // Watch for global HTTP proxy changes. mSettingsObserver.observe( @@ -976,7 +997,12 @@ public class ConnectivityService extends IConnectivityManager.Stub // Watch for whether or not to keep mobile data always on. mSettingsObserver.observe( Settings.Global.getUriFor(Settings.Global.MOBILE_DATA_ALWAYS_ON), - EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON); + EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); + + // Watch for whether or not to keep wifi always on. + mSettingsObserver.observe( + Settings.Global.getUriFor(Settings.Global.WIFI_ALWAYS_REQUESTED), + EVENT_CONFIGURE_ALWAYS_ON_NETWORKS); } private void registerPrivateDnsSettingsCallbacks() { @@ -1473,6 +1499,20 @@ public class ConnectivityService extends IConnectivityManager.Stub }; /** + * Ensures that the system cannot call a particular method. + */ + private boolean disallowedBecauseSystemCaller() { + // TODO: start throwing a SecurityException when GnssLocationProvider stops calling + // requestRouteToHost. + if (isSystem(Binder.getCallingUid())) { + log("This method exists only for app backwards compatibility" + + " and must not be called by system services."); + return true; + } + return false; + } + + /** * Ensure that a network route exists to deliver traffic to the specified * host via the specified network interface. * @param networkType the type of the network over which traffic to the @@ -1483,6 +1523,9 @@ public class ConnectivityService extends IConnectivityManager.Stub */ @Override public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { + if (disallowedBecauseSystemCaller()) { + return false; + } enforceChangePermission(); if (mProtectedNetworks.contains(networkType)) { enforceConnectivityInternalPermission(); @@ -1560,7 +1603,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("Adding legacy route " + bestRoute + " for UID/PID " + uid + "/" + Binder.getCallingPid()); try { - mNetd.addLegacyRouteForNetId(netId, bestRoute, uid); + mNMS.addLegacyRouteForNetId(netId, bestRoute, uid); } catch (Exception e) { // never crash - catch them all if (DBG) loge("Exception trying to add a route: " + e); @@ -1680,6 +1723,11 @@ public class ConnectivityService extends IConnectivityManager.Stub "ConnectivityService"); } + private boolean checkNetworkStackPermission() { + return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission( + android.Manifest.permission.NETWORK_STACK); + } + private void enforceConnectivityRestrictedNetworksPermission() { try { mContext.enforceCallingOrSelfPermission( @@ -1806,8 +1854,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // for user to unlock device too. updateLockdownVpn(); - // Configure whether mobile data is always on. - mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON)); + // Create network requests for always-on networks. + mHandler.sendMessage(mHandler.obtainMessage(EVENT_CONFIGURE_ALWAYS_ON_NETWORKS)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_SYSTEM_READY)); @@ -1845,7 +1893,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) { try { - mNetd.addIdleTimer(iface, timeout, type); + mNMS.addIdleTimer(iface, timeout, type); } catch (Exception e) { // You shall not crash! loge("Exception in setupDataActivityTracking " + e); @@ -1864,7 +1912,7 @@ public class ConnectivityService extends IConnectivityManager.Stub caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) { try { // the call fails silently if no idle timer setup for this interface - mNetd.removeIdleTimer(iface); + mNMS.removeIdleTimer(iface); } catch (Exception e) { loge("Exception in removeDataActivityTracking " + e); } @@ -1872,6 +1920,18 @@ public class ConnectivityService extends IConnectivityManager.Stub } /** + * Update data activity tracking when network state is updated. + */ + private void updateDataActivityTracking(NetworkAgentInfo newNetwork, + NetworkAgentInfo oldNetwork) { + if (newNetwork != null) { + setupDataActivityTracking(newNetwork); + } + if (oldNetwork != null) { + removeDataActivityTracking(oldNetwork); + } + } + /** * Reads the network specific MTU size from resources. * and set it on it's iface. */ @@ -1899,7 +1959,7 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (VDBG) log("Setting MTU size: " + iface + ", " + mtu); - mNetd.setMtu(iface, mtu); + mNMS.setMtu(iface, mtu); } catch (Exception e) { Slog.e(TAG, "exception in setMtu()" + e); } @@ -2553,7 +2613,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } nai.clearLingerState(); if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { - removeDataActivityTracking(nai); + updateDataActivityTracking(null /* newNetwork */, nai); notifyLockdownVpn(nai); ensureNetworkTransitionWakelock(nai.name()); } @@ -2573,7 +2633,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // NetworkFactories, so network traffic isn't interrupted for an unnecessarily // long time. try { - mNetd.removeNetwork(nai.network.netId); + mNMS.removeNetwork(nai.network.netId); } catch (Exception e) { loge("Exception removing network: " + e); } @@ -2771,20 +2831,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - // TODO: remove this code once we know that the Slog.wtf is never hit. - // - // Find all networks that are satisfying this request and remove the request - // from their request lists. - // TODO - it's my understanding that for a request there is only a single - // network satisfying it, so this loop is wasteful - for (NetworkAgentInfo otherNai : mNetworkAgentInfos.values()) { - if (otherNai.isSatisfyingRequest(nri.request.requestId) && otherNai != nai) { - Slog.wtf(TAG, "Request " + nri.request + " satisfied by " + - otherNai.name() + ", but mNetworkAgentInfos says " + - (nai != null ? nai.name() : "null")); - } - } - // Maintain the illusion. When this request arrived, we might have pretended // that a network connected to serve it, even though the network was already // connected. Now that this request has gone away, we might have to pretend @@ -3098,8 +3144,8 @@ public class ConnectivityService extends IConnectivityManager.Stub handlePromptUnvalidated((Network) msg.obj); break; } - case EVENT_CONFIGURE_MOBILE_DATA_ALWAYS_ON: { - handleMobileDataAlwaysOn(); + case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: { + handleConfigureAlwaysOnNetworks(); break; } // Sent by KeepaliveTracker to process an app request on the state machine thread. @@ -3752,7 +3798,7 @@ public class ConnectivityService extends IConnectivityManager.Stub Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown"); return false; } - setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile)); + setLockdownTracker(new LockdownVpnTracker(mContext, mNMS, this, vpn, profile)); } else { setLockdownTracker(null); } @@ -4007,7 +4053,7 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Starting user already has a VPN"); return; } - userVpn = new Vpn(mHandler.getLooper(), mContext, mNetd, userId); + userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId); mVpns.put(userId, userVpn); if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { updateLockdownVpn(); @@ -4527,6 +4573,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // priority networks like Wi-Fi are active. private final NetworkRequest mDefaultMobileDataRequest; + // Request used to optionally keep wifi data active even when higher + // priority networks like ethernet are active. + private final NetworkRequest mDefaultWifiRequest; + private NetworkAgentInfo getNetworkForRequest(int requestId) { synchronized (mNetworkForRequestId) { return mNetworkForRequestId.get(requestId); @@ -4624,7 +4674,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mDnsManager.updatePrivateDnsStatus(netId, newLp); // Start or stop clat accordingly to network state. - networkAgent.updateClat(mNetd); + networkAgent.updateClat(mNMS); if (isDefaultNetwork(networkAgent)) { handleApplyDefaultProxy(newLp.getHttpProxy()); } else { @@ -4663,9 +4713,9 @@ public class ConnectivityService extends IConnectivityManager.Stub final String prefix = "iface:" + iface; try { if (add) { - mNetd.getNetdService().wakeupAddInterface(iface, prefix, mark, mask); + mNetd.wakeupAddInterface(iface, prefix, mark, mask); } else { - mNetd.getNetdService().wakeupDelInterface(iface, prefix, mark, mask); + mNetd.wakeupDelInterface(iface, prefix, mark, mask); } } catch (Exception e) { loge("Exception modifying wakeup packet monitoring: " + e); @@ -4681,7 +4731,7 @@ public class ConnectivityService extends IConnectivityManager.Stub for (String iface : interfaceDiff.added) { try { if (DBG) log("Adding iface " + iface + " to network " + netId); - mNetd.addInterfaceToNetwork(iface, netId); + mNMS.addInterfaceToNetwork(iface, netId); wakeupModifyInterface(iface, caps, true); } catch (Exception e) { loge("Exception adding interface: " + e); @@ -4691,7 +4741,7 @@ public class ConnectivityService extends IConnectivityManager.Stub try { if (DBG) log("Removing iface " + iface + " from network " + netId); wakeupModifyInterface(iface, caps, false); - mNetd.removeInterfaceFromNetwork(iface, netId); + mNMS.removeInterfaceFromNetwork(iface, netId); } catch (Exception e) { loge("Exception removing interface: " + e); } @@ -4715,7 +4765,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (route.hasGateway()) continue; if (VDBG) log("Adding Route [" + route + "] to network " + netId); try { - mNetd.addRoute(netId, route); + mNMS.addRoute(netId, route); } catch (Exception e) { if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) { loge("Exception in addRoute for non-gateway: " + e); @@ -4726,7 +4776,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (route.hasGateway() == false) continue; if (VDBG) log("Adding Route [" + route + "] to network " + netId); try { - mNetd.addRoute(netId, route); + mNMS.addRoute(netId, route); } catch (Exception e) { if ((route.getGateway() instanceof Inet4Address) || VDBG) { loge("Exception in addRoute for gateway: " + e); @@ -4737,7 +4787,7 @@ public class ConnectivityService extends IConnectivityManager.Stub for (RouteInfo route : routeDiff.removed) { if (VDBG) log("Removing Route [" + route + "] from network " + netId); try { - mNetd.removeRoute(netId, route); + mNMS.removeRoute(netId, route); } catch (Exception e) { loge("Exception in removeRoute: " + e); } @@ -4849,7 +4899,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final String newPermission = getNetworkPermission(newNc); if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) { try { - mNetd.setNetworkPermission(nai.network.netId, newPermission); + mNMS.setNetworkPermission(nai.network.netId, newPermission); } catch (RemoteException e) { loge("Exception in setNetworkPermission: " + e); } @@ -4909,12 +4959,12 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!newRanges.isEmpty()) { final UidRange[] addedRangesArray = new UidRange[newRanges.size()]; newRanges.toArray(addedRangesArray); - mNetd.addVpnUidRanges(nai.network.netId, addedRangesArray); + mNMS.addVpnUidRanges(nai.network.netId, addedRangesArray); } if (!prevRanges.isEmpty()) { final UidRange[] removedRangesArray = new UidRange[prevRanges.size()]; prevRanges.toArray(removedRangesArray); - mNetd.removeVpnUidRanges(nai.network.netId, removedRangesArray); + mNMS.removeVpnUidRanges(nai.network.netId, removedRangesArray); } } catch (Exception e) { // Never crash! @@ -5083,9 +5133,9 @@ public class ConnectivityService extends IConnectivityManager.Stub private void makeDefault(NetworkAgentInfo newNetwork) { if (DBG) log("Switching to new default network: " + newNetwork); - setupDataActivityTracking(newNetwork); + try { - mNetd.setDefaultNetId(newNetwork.network.netId); + mNMS.setDefaultNetId(newNetwork.network.netId); } catch (Exception e) { loge("Exception setting default network :" + e); } @@ -5258,6 +5308,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } if (isNewDefault) { + updateDataActivityTracking(newNetwork, oldDefaultNetwork); // Notify system services that this network is up. makeDefault(newNetwork); // Log 0 -> X and Y -> X default network transitions, where X is the new default. @@ -5480,12 +5531,12 @@ public class ConnectivityService extends IConnectivityManager.Stub try { // This should never fail. Specifying an already in use NetID will cause failure. if (networkAgent.isVPN()) { - mNetd.createVirtualNetwork(networkAgent.network.netId, + mNMS.createVirtualNetwork(networkAgent.network.netId, !networkAgent.linkProperties.getDnsServers().isEmpty(), (networkAgent.networkMisc == null || !networkAgent.networkMisc.allowBypass)); } else { - mNetd.createPhysicalNetwork(networkAgent.network.netId, + mNMS.createPhysicalNetwork(networkAgent.network.netId, getNetworkPermission(networkAgent.networkCapabilities)); } } catch (Exception e) { @@ -5922,4 +5973,49 @@ public class ConnectivityService extends IConnectivityManager.Stub pw.println(" Get airplane mode."); } } + + /** + * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission + * for testing. + */ + private Vpn enforceActiveVpnOrNetworkStackPermission() { + if (checkNetworkStackPermission()) { + return null; + } + final int uid = Binder.getCallingUid(); + final int user = UserHandle.getUserId(uid); + synchronized (mVpns) { + Vpn vpn = mVpns.get(user); + try { + if (vpn.getVpnInfo().ownerUid == uid) return vpn; + } catch (NullPointerException e) { + /* vpn is null, or VPN is not connected and getVpnInfo() is null. */ + } + } + throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK " + + "permission"); + } + + /** + * @param connectionInfo the connection to resolve. + * @return {@code uid} if the connection is found and the app has permission to observe it + * (e.g., if it is associated with the calling VPN app's tunnel) or {@code INVALID_UID} if the + * connection is not found. + */ + public int getConnectionOwnerUid(ConnectionInfo connectionInfo) { + final Vpn vpn = enforceActiveVpnOrNetworkStackPermission(); + if (connectionInfo.protocol != IPPROTO_TCP && connectionInfo.protocol != IPPROTO_UDP) { + throw new IllegalArgumentException("Unsupported protocol " + connectionInfo.protocol); + } + + final int uid = InetDiagMessage.getConnectionOwnerUid(connectionInfo.protocol, + connectionInfo.local, connectionInfo.remote); + + /* Filter out Uids not associated with the VPN. */ + if (vpn != null && !vpn.appliesToUid(uid)) { + return INVALID_UID; + } + + return uid; + } } diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 380f6a7e581e..a69d41683c29 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -1490,23 +1490,19 @@ public class IpSecService extends IIpSecService.Stub { } } - private static final String TUNNEL_OP = "STOPSHIP"; // = AppOpsManager.OP_MANAGE_IPSEC_TUNNELS; + private static final String TUNNEL_OP = AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS; private void enforceTunnelPermissions(String callingPackage) { checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels"); - if (false) { // STOPSHIP if this line is present - switch (getAppOpsManager().noteOp( - TUNNEL_OP, - Binder.getCallingUid(), callingPackage)) { - case AppOpsManager.MODE_DEFAULT: - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService"); - break; - case AppOpsManager.MODE_ALLOWED: - return; - default: - throw new SecurityException("Request to ignore AppOps for non-legacy API"); - } + switch (getAppOpsManager().noteOp(TUNNEL_OP, Binder.getCallingUid(), callingPackage)) { + case AppOpsManager.MODE_DEFAULT: + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService"); + break; + case AppOpsManager.MODE_ALLOWED: + return; + default: + throw new SecurityException("Request to ignore AppOps for non-legacy API"); } } diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 9c81748ea435..ab0a56516ff4 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -160,6 +160,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub private static final int MAX_UID_RANGES_PER_COMMAND = 10; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + /** * Name representing {@link #setGlobalAlert(long)} limit when delivered to * {@link INetworkManagementEventObserver#limitReached(String, String)}. @@ -1229,18 +1231,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void startTethering(String[] dhcpRange) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - // cmd is "tether start first_start first_stop second_start second_stop ..." // an odd number of addrs will fail - final Command cmd = new Command("tether", "start"); - for (String d : dhcpRange) { - cmd.appendArg(d); - } - try { - mConnector.execute(cmd); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.tetherStart(dhcpRange); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } @@ -1248,9 +1244,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void stopTethering() { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { - mConnector.execute("tether", "stop"); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.tetherStop(); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } @@ -1258,25 +1254,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub public boolean isTetheringStarted() { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - final NativeDaemonEvent event; try { - event = mConnector.execute("tether", "status"); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + final boolean isEnabled = mNetdService.tetherIsEnabled(); + return isEnabled; + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } - - // 210 Tethering services started - event.checkCode(TetherStatusResult); - return event.getMessage().endsWith("started"); } @Override public void tetherInterface(String iface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { - mConnector.execute("tether", "interface", "add", iface); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.tetherInterfaceAdd(iface); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } List<RouteInfo> routes = new ArrayList<>(); // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it @@ -1289,9 +1281,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void untetherInterface(String iface) { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { - mConnector.execute("tether", "interface", "remove", iface); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.tetherInterfaceRemove(iface); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } finally { removeInterfaceFromLocalNetwork(iface); } @@ -1301,11 +1293,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub public String[] listTetheredInterfaces() { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { - return NativeDaemonEvent.filterMessageList( - mConnector.executeForList("tether", "interface", "list"), - TetherInterfaceListResult); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + final List<String> result = mNetdService.tetherInterfaceList(); + return result.toArray(EMPTY_STRING_ARRAY); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } @@ -1314,16 +1305,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET; - final Command cmd = new Command("tether", "dns", "set", netId); - - for (String s : dns) { - cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress()); - } try { - mConnector.execute(cmd); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + mNetdService.tetherDnsSet(netId, dns); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } @@ -1331,10 +1317,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub public String[] getDnsForwarders() { mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); try { - return NativeDaemonEvent.filterMessageList( - mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); + final List<String> result = mNetdService.tetherDnsList(); + return result.toArray(EMPTY_STRING_ARRAY); + } catch (RemoteException | ServiceSpecificException e) { + throw new IllegalStateException(e); } } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 0955beda1df5..0f9fe83ba6a5 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -1644,6 +1644,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { intent.putExtras(data); // Pass the subscription along with the intent. intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); + intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } @@ -1698,6 +1699,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { intent.setAction(PhoneConstants.ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); + intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); } // If the phoneId is invalid, the broadcast is for overall call state. if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) { diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 59093c19d733..289143c87ac0 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -87,7 +87,7 @@ public class Watchdog extends Thread { "media.metrics", // system/bin/mediametrics "media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service "com.android.bluetooth", // Bluetooth service - "statsd", // Stats daemon + "/system/bin/statsd", // Stats daemon }; public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList( diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9d0a8653178a..6c9871129ba0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -717,8 +717,6 @@ public class ActivityManagerService extends IActivityManager.Stub // Whether we should use SCHED_FIFO for UI and RenderThreads. private boolean mUseFifoUiScheduling = false; - private static final String SYSUI_COMPONENT_NAME = "com.android.systemui/.SystemUIService"; - BroadcastQueue mFgBroadcastQueue; BroadcastQueue mBgBroadcastQueue; // Convenient for easy iteration over the queues. Foreground is first @@ -810,7 +808,7 @@ public class ActivityManagerService extends IActivityManager.Stub boolean asProto) { if (asProto) return; doDump(fd, pw, new String[]{"activities"}, asProto); - doDump(fd, pw, new String[]{"service", SYSUI_COMPONENT_NAME}, asProto); + doDump(fd, pw, new String[]{"service", "all-platform-critical"}, asProto); } @Override diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 0b9832d90f7d..6fa17d8d5c01 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -627,6 +627,13 @@ public class AudioService extends IAudioService.Stub // If absolute volume is supported in AVRCP device private boolean mAvrcpAbsVolSupported = false; + // Pre-scale for Bluetooth Absolute Volume + private float[] mPrescaleAbsoluteVolume = new float[] { + 0.5f, // Pre-scale for index 1 + 0.7f, // Pre-scale for index 2 + 0.85f, // Pre-scale for index 3 + }; + private static Long mLastDeviceConnectMsgTime = new Long(0); private NotificationManager mNm; @@ -878,6 +885,23 @@ public class AudioService extends IAudioService.Stub mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); mRecordMonitor.initMonitor(); + + final float[] preScale = new float[3]; + preScale[0] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1, + 1, 1); + preScale[1] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2, + 1, 1); + preScale[2] = mContext.getResources().getFraction( + com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3, + 1, 1); + for (int i = 0; i < preScale.length; i++) { + if (0.0f <= preScale[i] && preScale[i] <= 1.0f) { + mPrescaleAbsoluteVolume[i] = preScale[i]; + } + } + } public void systemReady() { @@ -4879,18 +4903,12 @@ public class AudioService extends IAudioService.Stub if (index == 0) { // 0% for volume 0 index = 0; - } else if (index == 1) { - // 50% for volume 1 - index = (int)(mIndexMax * 0.5) /10; - } else if (index == 2) { - // 70% for volume 2 - index = (int)(mIndexMax * 0.70) /10; - } else if (index == 3) { - // 85% for volume 3 - index = (int)(mIndexMax * 0.85) /10; + } else if (index > 0 && index <= 3) { + // Pre-scale for volume steps 1 2 and 3 + index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10; } else { // otherwise, full gain - index = (mIndexMax + 5)/10; + index = (mIndexMax + 5) / 10; } return index; } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 2a80f0e7c291..48082b64ddfc 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -163,8 +163,8 @@ public class Vpn { // TODO: create separate trackers for each unique VPN to support // automated reconnection - private Context mContext; - private NetworkInfo mNetworkInfo; + private final Context mContext; + private final NetworkInfo mNetworkInfo; private String mPackage; private int mOwnerUID; private String mInterface; diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java index 2b1d9196fe18..1e6bb04858a1 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -320,9 +320,8 @@ public class TetheringConfiguration { } private static boolean getEnableLegacyDhcpServer(Context ctx) { - // TODO: make the default false (0) and update javadoc in Settings.java final ContentResolver cr = ctx.getContentResolver(); - final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); + final int intVal = Settings.Global.getInt(cr, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); return intVal != 0; } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 451acf4cfc9c..7745e3c0ae1b 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -1879,30 +1879,36 @@ public class InputManagerService extends IInputManager.Stub // Read partner-provided list of excluded input devices XmlPullParser parser = null; // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system". - File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH); - FileReader confreader = null; - try { - confreader = new FileReader(confFile); - parser = Xml.newPullParser(); - parser.setInput(confreader); - XmlUtils.beginDocument(parser, "devices"); - - while (true) { - XmlUtils.nextElement(parser); - if (!"device".equals(parser.getName())) { - break; - } - String name = parser.getAttributeValue(null, "name"); - if (name != null) { - names.add(name); + final File[] baseDirs = { + Environment.getRootDirectory(), + Environment.getVendorDirectory() + }; + for (File baseDir: baseDirs) { + File confFile = new File(baseDir, EXCLUDED_DEVICES_PATH); + FileReader confreader = null; + try { + confreader = new FileReader(confFile); + parser = Xml.newPullParser(); + parser.setInput(confreader); + XmlUtils.beginDocument(parser, "devices"); + + while (true) { + XmlUtils.nextElement(parser); + if (!"device".equals(parser.getName())) { + break; + } + String name = parser.getAttributeValue(null, "name"); + if (name != null) { + names.add(name); + } } + } catch (FileNotFoundException e) { + // It's ok if the file does not exist. + } catch (Exception e) { + Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e); + } finally { + try { if (confreader != null) confreader.close(); } catch (IOException e) { } } - } catch (FileNotFoundException e) { - // It's ok if the file does not exist. - } catch (Exception e) { - Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e); - } finally { - try { if (confreader != null) confreader.close(); } catch (IOException e) { } } return names.toArray(new String[names.size()]); diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index 77ef63dd5aad..dea78630e4fe 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -53,10 +53,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { private final static String TAG = "OTADexopt"; private final static boolean DEBUG_DEXOPT = true; - // The synthetic library dependencies denoting "no checks." - private final static String[] NO_LIBRARIES = - new String[] { PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK }; - // The amount of "available" (free - low threshold) space necessary at the start of an OTA to // not bulk-delete unused apps' odex files. private final static long BULK_DELETE_THRESHOLD = 1024 * 1024 * 1024; // 1GB. @@ -288,8 +284,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub { throws InstallerException { final StringBuilder builder = new StringBuilder(); - // The current version. - builder.append("9 "); + // The current version. For v10, see b/115993344. + builder.append("10 "); builder.append("dexopt"); @@ -338,11 +334,6 @@ public class OtaDexoptService extends IOtaDexopt.Stub { collectingInstaller, mPackageManagerService.mInstallLock, mContext); String[] libraryDependencies = pkg.usesLibraryFiles; - if (pkg.isSystem()) { - // For system apps, we want to avoid classpaths checks. - libraryDependencies = NO_LIBRARIES; - } - optimizer.performDexOpt(pkg, libraryDependencies, null /* ISAs */, diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 271d205cb69b..fae4db9a81de 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -17529,7 +17529,8 @@ public class PackageManagerService extends IPackageManager.Stub // Prepare the application profiles for the new code paths. // This needs to be done before invoking dexopt so that any install-time profile // can be used for optimizations. - mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier())); + mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()), + /* updateReferenceProfileContent= */ true); // Check whether we need to dexopt the app. // @@ -22606,8 +22607,18 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); // // We also have to cover non system users because we do not call the usual install package // methods for them. + // + // NOTE: in order to speed up first boot time we only create the current profile and do not + // update the content of the reference profile. A system image should already be configured + // with the right profile keys and the profiles for the speed-profile prebuilds should + // already be copied. That's done in #performDexOptUpgrade. + // + // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of + // manually copying them in #performDexOptUpgrade. When we do that we should have a more + // granular check here and only update the existing profiles. if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) { - mArtManagerService.prepareAppProfiles(pkg, userId); + mArtManagerService.prepareAppProfiles(pkg, userId, + /* updateReferenceProfileContent= */ false); } if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 0ba78226a38f..833cc5bd91f2 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -389,7 +389,8 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { * - create the current primary profile to save time at app startup time. * - copy the profiles from the associated dex metadata file to the reference profile. */ - public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user) { + public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user, + boolean updateReferenceProfileContent) { final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); if (user < 0) { Slog.wtf(TAG, "Invalid user id: " + user); @@ -404,8 +405,14 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { for (int i = codePathsProfileNames.size() - 1; i >= 0; i--) { String codePath = codePathsProfileNames.keyAt(i); String profileName = codePathsProfileNames.valueAt(i); - File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); - String dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + String dexMetadataPath = null; + // Passing the dex metadata file to the prepare method will update the reference + // profile content. As such, we look for the dex metadata file only if we need to + // perform an update. + if (updateReferenceProfileContent) { + File dexMetadata = DexMetadataHelper.findDexMetadataForFile(new File(codePath)); + dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath(); + } synchronized (mInstaller) { boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId, profileName, codePath, dexMetadataPath); @@ -423,9 +430,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { /** * Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}. */ - public void prepareAppProfiles(PackageParser.Package pkg, int[] user) { + public void prepareAppProfiles(PackageParser.Package pkg, int[] user, + boolean updateReferenceProfileContent) { for (int i = 0; i < user.length; i++) { - prepareAppProfiles(pkg, user[i]); + prepareAppProfiles(pkg, user[i], updateReferenceProfileContent); } } diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java index e3e15907939a..602ce3b2a0c1 100644 --- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java +++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java @@ -93,7 +93,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { @GuardedBy("mPackageUseInfoMap") private final Map<String, PackageUseInfo> mPackageUseInfoMap; - public PackageDexUsage() { + /* package */ PackageDexUsage() { super("package-dex-usage.list", "PackageDexUsage_DiskWriter", /*lock*/ false); mPackageUseInfoMap = new HashMap<>(); } @@ -116,7 +116,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { * @return true if the dex load constitutes new information, or false if this information * has been seen before. */ - public boolean record(String owningPackageName, String dexPath, int ownerUserId, + /* package */ boolean record(String owningPackageName, String dexPath, int ownerUserId, String loaderIsa, boolean isUsedByOtherApps, boolean primaryOrSplit, String loadingPackageName, String classLoaderContext) { if (!PackageManagerServiceUtils.checkISA(loaderIsa)) { @@ -193,7 +193,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { * Convenience method for sync reads which does not force the user to pass a useless * (Void) null. */ - public void read() { + /* package */ void read() { read((Void) null); } @@ -558,7 +558,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { * Remove the usage data associated with package {@code packageName}. * @return true if the package usage was found and removed successfully. */ - public boolean removePackage(String packageName) { + /* package */ boolean removePackage(String packageName) { synchronized (mPackageUseInfoMap) { return mPackageUseInfoMap.remove(packageName) != null; } @@ -653,11 +653,12 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { return packages; } - public void clear() { + /* package */ void clear() { synchronized (mPackageUseInfoMap) { mPackageUseInfoMap.clear(); } } + // Creates a deep copy of the class' mPackageUseInfoMap. private Map<String, PackageUseInfo> clonePackageUseInfoMap() { Map<String, PackageUseInfo> clone = new HashMap<>(); @@ -679,7 +680,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> { throw new IllegalArgumentException("Unknown bool encoding: " + bool); } - public String dump() { + /* package */ String dump() { StringWriter sw = new StringWriter(); write(sw); return sw.toString(); diff --git a/services/core/java/com/android/server/pm/dex/TEST_MAPPING b/services/core/java/com/android/server/pm/dex/TEST_MAPPING new file mode 100644 index 000000000000..ad5255904d20 --- /dev/null +++ b/services/core/java/com/android/server/pm/dex/TEST_MAPPING @@ -0,0 +1,22 @@ +{ + "presubmit": [ + { + "name": "DexLoggerTests" + }, + { + "name": "DexManagerTests" + }, + { + "name": "DexoptOptionsTests" + }, + { + "name": "DexoptUtilsTest" + }, + { + "name": "PackageDexUsageTests" + }, + { + "name": "DexLoggerIntegrationTests" + } + ] +} diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 89efe12927ba..306f73aa704b 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -98,7 +98,6 @@ cc_defaults { "libsensorservicehidl", "libgui", "libusbhost", - "libsuspend", "libtinyalsa", "libEGL", "libGLESv2", @@ -130,6 +129,7 @@ cc_defaults { "android.hardware.vr@1.0", "android.frameworks.schedulerservice@1.0", "android.frameworks.sensorservice@1.0", + "android.system.suspend@1.0", ], static_libs: [ diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index 02ad6c71b586..0ff60e44b0ce 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -30,6 +30,8 @@ #include <android/hardware/power/1.0/IPower.h> #include <android/hardware/power/1.1/IPower.h> +#include <android/system/suspend/1.0/ISystemSuspend.h> +#include <android/system/suspend/1.0/ISystemSuspendCallback.h> #include <android_runtime/AndroidRuntime.h> #include <jni.h> @@ -39,7 +41,6 @@ #include <log/log.h> #include <utils/misc.h> #include <utils/Log.h> -#include <suspend/autosuspend.h> using android::hardware::Return; using android::hardware::Void; @@ -49,6 +50,8 @@ using android::hardware::power::V1_0::Status; using android::hardware::power::V1_1::PowerStateSubsystem; using android::hardware::power::V1_1::PowerStateSubsystemSleepState; using android::hardware::hidl_vec; +using android::system::suspend::V1_0::ISystemSuspend; +using android::system::suspend::V1_0::ISystemSuspendCallback; using IPowerV1_1 = android::hardware::power::V1_1::IPower; using IPowerV1_0 = android::hardware::power::V1_0::IPower; @@ -63,6 +66,7 @@ static sem_t wakeup_sem; extern sp<IPowerV1_0> getPowerHalV1_0(); extern sp<IPowerV1_1> getPowerHalV1_1(); extern bool processPowerHalReturn(const Return<void> &ret, const char* functionName); +extern sp<ISystemSuspend> getSuspendHal(); // Java methods used in getLowPowerStats static jmethodID jgetAndUpdatePlatformState = NULL; @@ -70,16 +74,19 @@ static jmethodID jgetSubsystem = NULL; static jmethodID jputVoter = NULL; static jmethodID jputState = NULL; -static void wakeup_callback(bool success) -{ - ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted"); - int ret = sem_post(&wakeup_sem); - if (ret < 0) { - char buf[80]; - strerror_r(errno, buf, sizeof(buf)); - ALOGE("Error posting wakeup sem: %s\n", buf); +class WakeupCallback : public ISystemSuspendCallback { +public: + Return<void> notifyWakeup(bool success) override { + ALOGV("In wakeup_callback: %s", success ? "resumed from suspend" : "suspend aborted"); + int ret = sem_post(&wakeup_sem); + if (ret < 0) { + char buf[80]; + strerror_r(errno, buf, sizeof(buf)); + ALOGE("Error posting wakeup sem: %s\n", buf); + } + return Void(); } -} +}; static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) { @@ -101,11 +108,14 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) return -1; } ALOGV("Registering callback..."); - autosuspend_set_wakeup_callback(&wakeup_callback); + sp<ISystemSuspend> suspendHal = getSuspendHal(); + suspendHal->registerCallback(new WakeupCallback()); } // Wait for wakeup. ALOGV("Waiting for wakeup..."); + // TODO(b/116747600): device can suspend and wakeup after sem_wait() finishes and before wakeup + // reason is recorded, i.e. BatteryStats might occasionally miss wakeup events. int ret = sem_wait(&wakeup_sem); if (ret < 0) { char buf[80]; diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp index b2d35d4153a0..0c9b5f4999a0 100644 --- a/services/core/jni/com_android_server_power_PowerManagerService.cpp +++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp @@ -19,6 +19,7 @@ //#define LOG_NDEBUG 0 #include <android/hardware/power/1.1/IPower.h> +#include <android/system/suspend/1.0/ISystemSuspend.h> #include <nativehelper/JNIHelp.h> #include "jni.h" @@ -35,7 +36,7 @@ #include <utils/Log.h> #include <hardware/power.h> #include <hardware_legacy/power.h> -#include <suspend/autosuspend.h> +#include <hidl/ServiceManagement.h> #include "com_android_server_power_PowerManagerService.h" @@ -44,6 +45,9 @@ using android::hardware::Void; using android::hardware::power::V1_0::PowerHint; using android::hardware::power::V1_0::Feature; using android::String8; +using android::system::suspend::V1_0::ISystemSuspend; +using android::system::suspend::V1_0::IWakeLock; +using android::system::suspend::V1_0::WakeLockType; using IPowerV1_1 = android::hardware::power::V1_1::IPower; using IPowerV1_0 = android::hardware::power::V1_0::IPower; @@ -171,6 +175,46 @@ void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t } } +static sp<ISystemSuspend> gSuspendHal = nullptr; +static sp<IWakeLock> gSuspendBlocker = nullptr; +static std::mutex gSuspendMutex; + +// Assume SystemSuspend HAL is always alive. +// TODO: Force device to restart if SystemSuspend HAL dies. +sp<ISystemSuspend> getSuspendHal() { + static std::once_flag suspendHalFlag; + std::call_once(suspendHalFlag, [](){ + ::android::hardware::details::waitForHwService(ISystemSuspend::descriptor, "default"); + gSuspendHal = ISystemSuspend::getService(); + assert(gSuspendHal != nullptr); + }); + return gSuspendHal; +} + +void enableAutoSuspend() { + static bool enabled = false; + + std::lock_guard<std::mutex> lock(gSuspendMutex); + if (!enabled) { + sp<ISystemSuspend> suspendHal = getSuspendHal(); + suspendHal->enableAutosuspend(); + enabled = true; + } + if (gSuspendBlocker) { + gSuspendBlocker->release(); + gSuspendBlocker.clear(); + } +} + +void disableAutoSuspend() { + std::lock_guard<std::mutex> lock(gSuspendMutex); + if (!gSuspendBlocker) { + sp<ISystemSuspend> suspendHal = getSuspendHal(); + gSuspendBlocker = suspendHal->acquireWakeLock(WakeLockType::PARTIAL, + "PowerManager.SuspendLockout"); + } +} + // ---------------------------------------------------------------------------- static void nativeInit(JNIEnv* env, jobject obj) { @@ -207,13 +251,13 @@ static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (enable) { android::base::Timer t; - autosuspend_enable(); + enableAutoSuspend(); if (t.duration() > 100ms) { ALOGD("Excessive delay in autosuspend_enable() while turning screen off"); } } else { android::base::Timer t; - autosuspend_disable(); + disableAutoSuspend(); if (t.duration() > 100ms) { ALOGD("Excessive delay in autosuspend_disable() while turning screen on"); } diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index 93c4829568f9..6c2a894a3a6a 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -390,7 +390,11 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface> [&result, &sidebandStream](Result res, const native_handle_t* handle) { result = res; if (res == Result::OK) { - sidebandStream = handle; + if (handle) { + sidebandStream = native_handle_clone(handle); + } else { + result = Result::UNKNOWN; + } } }); if (result != Result::OK) { @@ -398,7 +402,7 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface> result); return UNKNOWN_ERROR; } - connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, false); + connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, true); } connection.mSurface = surface; if (connection.mSurface != nullptr) { diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp index 05052047e0fb..47790ce68dc1 100644 --- a/services/devicepolicy/Android.bp +++ b/services/devicepolicy/Android.bp @@ -3,7 +3,6 @@ java_library_static { srcs: ["java/**/*.java"], libs: [ - "conscrypt", "services.core", ], } diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java index 77a3e2102452..6ba7d94117b1 100644 --- a/services/net/java/android/net/dhcp/DhcpPacket.java +++ b/services/net/java/android/net/dhcp/DhcpPacket.java @@ -1,5 +1,8 @@ package android.net.dhcp; +import static android.net.util.NetworkConstants.IPV4_MAX_MTU; +import static android.net.util.NetworkConstants.IPV4_MIN_MTU; + import android.annotation.Nullable; import android.net.DhcpResults; import android.net.LinkAddress; @@ -381,6 +384,26 @@ public abstract class DhcpPacket { } /** + * Returns whether a parameter is included in the parameter request list option of this packet. + * + * <p>If there is no parameter request list option in the packet, false is returned. + * + * @param paramId ID of the parameter, such as {@link #DHCP_MTU} or {@link #DHCP_HOST_NAME}. + */ + public boolean hasRequestedParam(byte paramId) { + if (mRequestedParams == null) { + return false; + } + + for (byte reqParam : mRequestedParams) { + if (reqParam == paramId) { + return true; + } + } + return false; + } + + /** * Creates a new L3 packet (including IP header) containing the * DHCP udp packet. This method relies upon the delegated method * finishPacket() to insert the per-packet contents. @@ -696,7 +719,11 @@ public abstract class DhcpPacket { addTlv(buf, DHCP_ROUTER, mGateways); addTlv(buf, DHCP_DNS_SERVER, mDnsServers); addTlv(buf, DHCP_DOMAIN_NAME, mDomainName); + addTlv(buf, DHCP_HOST_NAME, mHostName); addTlv(buf, DHCP_VENDOR_INFO, mVendorInfo); + if (mMtu != null && Short.toUnsignedInt(mMtu) >= IPV4_MIN_MTU) { + addTlv(buf, DHCP_MTU, mMtu); + } } /** @@ -1259,7 +1286,8 @@ public abstract class DhcpPacket { boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers, - Inet4Address dhcpServerIdentifier, String domainName, boolean metered) { + Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered, + short mtu) { DhcpPacket pkt = new DhcpOfferPacket( transactionId, (short) 0, broadcast, serverIpAddr, relayIp, INADDR_ANY /* clientIp */, yourIp, mac); @@ -1267,9 +1295,11 @@ public abstract class DhcpPacket { pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; pkt.mDomainName = domainName; + pkt.mHostName = hostname; pkt.mServerIdentifier = dhcpServerIdentifier; pkt.mSubnetMask = netMask; pkt.mBroadcastAddress = bcAddr; + pkt.mMtu = mtu; if (metered) { pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED; } @@ -1283,7 +1313,8 @@ public abstract class DhcpPacket { boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp, Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers, - Inet4Address dhcpServerIdentifier, String domainName, boolean metered) { + Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered, + short mtu) { DhcpPacket pkt = new DhcpAckPacket( transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp, mac); @@ -1291,9 +1322,11 @@ public abstract class DhcpPacket { pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; pkt.mDomainName = domainName; + pkt.mHostName = hostname; pkt.mSubnetMask = netMask; pkt.mServerIdentifier = dhcpServerIdentifier; pkt.mBroadcastAddress = bcAddr; + pkt.mMtu = mtu; if (metered) { pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED; } diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java index 2b3d577b0eae..cee6fa96bbc5 100644 --- a/services/net/java/android/net/dhcp/DhcpServer.java +++ b/services/net/java/android/net/dhcp/DhcpServer.java @@ -20,6 +20,7 @@ import static android.net.NetworkUtils.getBroadcastAddress; import static android.net.NetworkUtils.getPrefixMaskAsInet4Address; import static android.net.TrafficStats.TAG_SYSTEM_DHCP_SERVER; import static android.net.dhcp.DhcpPacket.DHCP_CLIENT; +import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME; import static android.net.dhcp.DhcpPacket.DHCP_SERVER; import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP; import static android.net.dhcp.DhcpPacket.INFINITE_LEASE; @@ -46,6 +47,7 @@ import android.os.Message; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; +import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.HexDump; @@ -350,6 +352,19 @@ public class DhcpServer { return isEmpty(request.mClientIp) && (request.mBroadcast || isEmpty(lease.getNetAddr())); } + /** + * Get the hostname from a lease if non-empty and requested in the incoming request. + * @param request The incoming request. + * @return The hostname, or null if not requested or empty. + */ + @Nullable + private static String getHostnameIfRequested(@NonNull DhcpPacket request, + @NonNull DhcpLease lease) { + return request.hasRequestedParam(DHCP_HOST_NAME) && !TextUtils.isEmpty(lease.getHostname()) + ? lease.getHostname() + : null; + } + private boolean transmitOffer(@NonNull DhcpPacket request, @NonNull DhcpLease lease, @NonNull MacAddress clientMac) { final boolean broadcastFlag = getBroadcastFlag(request, lease); @@ -358,12 +373,14 @@ public class DhcpServer { getPrefixMaskAsInet4Address(mServingParams.serverAddr.getPrefixLength()); final Inet4Address broadcastAddr = getBroadcastAddress( mServingParams.getServerInet4Addr(), mServingParams.serverAddr.getPrefixLength()); + final String hostname = getHostnameIfRequested(request, lease); final ByteBuffer offerPacket = DhcpPacket.buildOfferPacket( ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp, lease.getNetAddr(), request.mClientMac, timeout, prefixMask, broadcastAddr, new ArrayList<>(mServingParams.defaultRouters), new ArrayList<>(mServingParams.dnsServers), - mServingParams.getServerInet4Addr(), null /* domainName */, mServingParams.metered); + mServingParams.getServerInet4Addr(), null /* domainName */, hostname, + mServingParams.metered, (short) mServingParams.linkMtu); return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag); } @@ -374,13 +391,15 @@ public class DhcpServer { // transmitOffer above final boolean broadcastFlag = getBroadcastFlag(request, lease); final int timeout = getLeaseTimeout(lease); + final String hostname = getHostnameIfRequested(request, lease); final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp, lease.getNetAddr(), request.mClientIp, request.mClientMac, timeout, mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(), new ArrayList<>(mServingParams.defaultRouters), new ArrayList<>(mServingParams.dnsServers), - mServingParams.getServerInet4Addr(), null /* domainName */, mServingParams.metered); + mServingParams.getServerInet4Addr(), null /* domainName */, hostname, + mServingParams.metered, (short) mServingParams.linkMtu); return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag); } diff --git a/services/net/java/android/net/netlink/InetDiagMessage.java b/services/net/java/android/net/netlink/InetDiagMessage.java new file mode 100644 index 000000000000..af9e601da9ec --- /dev/null +++ b/services/net/java/android/net/netlink/InetDiagMessage.java @@ -0,0 +1,187 @@ +/* + * 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.net.netlink; + +import static android.os.Process.INVALID_UID; +import static android.net.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY; +import static android.net.netlink.NetlinkSocket.DEFAULT_RECV_BUFSIZE; +import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; +import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.IPPROTO_UDP; +import static android.system.OsConstants.NETLINK_INET_DIAG; + +import android.os.Build; +import android.os.Process; +import android.system.ErrnoException; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.InterruptedIOException; +import java.net.DatagramSocket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetSocketAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * A NetlinkMessage subclass for netlink inet_diag messages. + * + * see also: <linux_src>/include/uapi/linux/inet_diag.h + * + * @hide + */ +public class InetDiagMessage extends NetlinkMessage { + public static final String TAG = "InetDiagMessage"; + private static final int TIMEOUT_MS = 500; + + public static byte[] InetDiagReqV2(int protocol, InetSocketAddress local, + InetSocketAddress remote, int family, short flags) { + final byte[] bytes = new byte[StructNlMsgHdr.STRUCT_SIZE + StructInetDiagReqV2.STRUCT_SIZE]; + final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); + byteBuffer.order(ByteOrder.nativeOrder()); + + final StructNlMsgHdr nlMsgHdr = new StructNlMsgHdr(); + nlMsgHdr.nlmsg_len = bytes.length; + nlMsgHdr.nlmsg_type = SOCK_DIAG_BY_FAMILY; + nlMsgHdr.nlmsg_flags = flags; + nlMsgHdr.pack(byteBuffer); + + final StructInetDiagReqV2 inetDiagReqV2 = new StructInetDiagReqV2(protocol, local, remote, + family); + inetDiagReqV2.pack(byteBuffer); + return bytes; + } + + public StructInetDiagMsg mStructInetDiagMsg; + + private InetDiagMessage(StructNlMsgHdr header) { + super(header); + mStructInetDiagMsg = new StructInetDiagMsg(); + } + + public static InetDiagMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) { + final InetDiagMessage msg = new InetDiagMessage(header); + msg.mStructInetDiagMsg = StructInetDiagMsg.parse(byteBuffer); + return msg; + } + + private static int lookupUidByFamily(int protocol, InetSocketAddress local, + InetSocketAddress remote, int family, short flags, + FileDescriptor fd) + throws ErrnoException, InterruptedIOException { + byte[] msg = InetDiagReqV2(protocol, local, remote, family, flags); + NetlinkSocket.sendMessage(fd, msg, 0, msg.length, TIMEOUT_MS); + ByteBuffer response = NetlinkSocket.recvMessage(fd, DEFAULT_RECV_BUFSIZE, TIMEOUT_MS); + + final NetlinkMessage nlMsg = NetlinkMessage.parse(response); + final StructNlMsgHdr hdr = nlMsg.getHeader(); + if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) { + return INVALID_UID; + } + if (nlMsg instanceof InetDiagMessage) { + return ((InetDiagMessage) nlMsg).mStructInetDiagMsg.idiag_uid; + } + return INVALID_UID; + } + + private static final int FAMILY[] = {AF_INET6, AF_INET}; + + private static int lookupUid(int protocol, InetSocketAddress local, + InetSocketAddress remote, FileDescriptor fd) + throws ErrnoException, InterruptedIOException { + int uid; + + for (int family : FAMILY) { + /** + * For exact match lookup, swap local and remote for UDP lookups due to kernel + * bug which will not be fixed. See aosp/755889 and + * https://www.mail-archive.com/netdev@vger.kernel.org/msg248638.html + */ + if (protocol == IPPROTO_UDP) { + uid = lookupUidByFamily(protocol, remote, local, family, NLM_F_REQUEST, fd); + } else { + uid = lookupUidByFamily(protocol, local, remote, family, NLM_F_REQUEST, fd); + } + if (uid != INVALID_UID) { + return uid; + } + } + + /** + * For UDP it's possible for a socket to send packets to arbitrary destinations, even if the + * socket is not connected (and even if the socket is connected to a different destination). + * If we want this API to work for such packets, then on miss we need to do a second lookup + * with only the local address and port filled in. + * Always use flags == NLM_F_REQUEST | NLM_F_DUMP for wildcard. + */ + if (protocol == IPPROTO_UDP) { + try { + InetSocketAddress wildcard = new InetSocketAddress( + Inet6Address.getByName("::"), 0); + uid = lookupUidByFamily(protocol, local, wildcard, AF_INET6, + (short) (NLM_F_REQUEST | NLM_F_DUMP), fd); + if (uid != INVALID_UID) { + return uid; + } + wildcard = new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), 0); + uid = lookupUidByFamily(protocol, local, wildcard, AF_INET, + (short) (NLM_F_REQUEST | NLM_F_DUMP), fd); + if (uid != INVALID_UID) { + return uid; + } + } catch (UnknownHostException e) { + Log.e(TAG, e.toString()); + } + } + return INVALID_UID; + } + + /** + * Use an inet_diag socket to look up the UID associated with the input local and remote + * address/port and protocol of a connection. + */ + public static int getConnectionOwnerUid(int protocol, InetSocketAddress local, + InetSocketAddress remote) { + try { + final FileDescriptor fd = NetlinkSocket.forProto(NETLINK_INET_DIAG); + NetlinkSocket.connectToKernel(fd); + + return lookupUid(protocol, local, remote, fd); + + } catch (ErrnoException | SocketException | IllegalArgumentException + | InterruptedIOException e) { + Log.e(TAG, e.toString()); + } + return INVALID_UID; + } + + @Override + public String toString() { + return "InetDiagMessage{ " + + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, " + + "inet_diag_msg{" + + (mStructInetDiagMsg == null ? "" : mStructInetDiagMsg.toString()) + "} " + + "}"; + } +} diff --git a/services/net/java/android/net/netlink/NetlinkConstants.java b/services/net/java/android/net/netlink/NetlinkConstants.java index e331701efbce..fc1551c87b6b 100644 --- a/services/net/java/android/net/netlink/NetlinkConstants.java +++ b/services/net/java/android/net/netlink/NetlinkConstants.java @@ -54,6 +54,12 @@ public class NetlinkConstants { return String.valueOf(family); } + public static String stringForProtocol(int protocol) { + if (protocol == OsConstants.IPPROTO_TCP) { return "IPPROTO_TCP"; } + if (protocol == OsConstants.IPPROTO_UDP) { return "IPPROTO_UDP"; } + return String.valueOf(protocol); + } + public static String hexify(byte[] bytes) { if (bytes == null) { return "(null)"; } return HexDump.toHexString(bytes); @@ -90,6 +96,9 @@ public class NetlinkConstants { public static final short RTM_GETRULE = 34; public static final short RTM_NEWNDUSEROPT = 68; + /* see <linux_src>/include/uapi/linux/sock_diag.h */ + public static final short SOCK_DIAG_BY_FAMILY = 20; + public static String stringForNlMsgType(short nlm_type) { switch (nlm_type) { case NLMSG_NOOP: return "NLMSG_NOOP"; diff --git a/services/net/java/android/net/netlink/NetlinkMessage.java b/services/net/java/android/net/netlink/NetlinkMessage.java index 3bf75cabea17..a325db800813 100644 --- a/services/net/java/android/net/netlink/NetlinkMessage.java +++ b/services/net/java/android/net/netlink/NetlinkMessage.java @@ -69,6 +69,8 @@ public class NetlinkMessage { case NetlinkConstants.RTM_DELNEIGH: case NetlinkConstants.RTM_GETNEIGH: return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer); + case NetlinkConstants.SOCK_DIAG_BY_FAMILY: + return (NetlinkMessage) InetDiagMessage.parse(nlmsghdr, byteBuffer); default: if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) { // Netlink control message. Just parse the header for now, diff --git a/services/net/java/android/net/netlink/StructInetDiagMsg.java b/services/net/java/android/net/netlink/StructInetDiagMsg.java new file mode 100644 index 000000000000..da824ad01efa --- /dev/null +++ b/services/net/java/android/net/netlink/StructInetDiagMsg.java @@ -0,0 +1,67 @@ +/* + * 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.net.netlink; + +import static java.nio.ByteOrder.BIG_ENDIAN; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import java.net.Inet4Address; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import android.util.Log; + +/** + * struct inet_diag_msg + * + * see <linux_src>/include/uapi/linux/inet_diag.h + * + * struct inet_diag_msg { + * __u8 idiag_family; + * __u8 idiag_state; + * __u8 idiag_timer; + * __u8 idiag_retrans; + * struct inet_diag_sockid id; + * __u32 idiag_expires; + * __u32 idiag_rqueue; + * __u32 idiag_wqueue; + * __u32 idiag_uid; + * __u32 idiag_inode; + * }; + * + * @hide + */ +public class StructInetDiagMsg { + public static final int STRUCT_SIZE = 4 + StructInetDiagSockId.STRUCT_SIZE + 20; + private static final int IDIAG_UID_OFFSET = StructNlMsgHdr.STRUCT_SIZE + 4 + + StructInetDiagSockId.STRUCT_SIZE + 12; + public int idiag_uid; + + public static StructInetDiagMsg parse(ByteBuffer byteBuffer) { + StructInetDiagMsg struct = new StructInetDiagMsg(); + struct.idiag_uid = byteBuffer.getInt(IDIAG_UID_OFFSET); + return struct; + } + + @Override + public String toString() { + return "StructInetDiagMsg{ " + + "idiag_uid{" + idiag_uid + "}, " + + "}"; + } +} diff --git a/services/net/java/android/net/netlink/StructInetDiagReqV2.java b/services/net/java/android/net/netlink/StructInetDiagReqV2.java new file mode 100644 index 000000000000..49a93258e714 --- /dev/null +++ b/services/net/java/android/net/netlink/StructInetDiagReqV2.java @@ -0,0 +1,80 @@ +/* + * 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.net.netlink; + +import static java.nio.ByteOrder.BIG_ENDIAN; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * struct inet_diag_req_v2 + * + * see <linux_src>/include/uapi/linux/inet_diag.h + * + * struct inet_diag_req_v2 { + * __u8 sdiag_family; + * __u8 sdiag_protocol; + * __u8 idiag_ext; + * __u8 pad; + * __u32 idiag_states; + * struct inet_diag_sockid id; + * }; + * + * @hide + */ +public class StructInetDiagReqV2 { + public static final int STRUCT_SIZE = 8 + StructInetDiagSockId.STRUCT_SIZE; + + private final byte sdiag_family; + private final byte sdiag_protocol; + private final StructInetDiagSockId id; + private final int INET_DIAG_REQ_V2_ALL_STATES = (int) 0xffffffff; + + + public StructInetDiagReqV2(int protocol, InetSocketAddress local, InetSocketAddress remote, + int family) { + sdiag_family = (byte) family; + sdiag_protocol = (byte) protocol; + id = new StructInetDiagSockId(local, remote); + } + + public void pack(ByteBuffer byteBuffer) { + // The ByteOrder must have already been set by the caller. + byteBuffer.put((byte) sdiag_family); + byteBuffer.put((byte) sdiag_protocol); + byteBuffer.put((byte) 0); + byteBuffer.put((byte) 0); + byteBuffer.putInt(INET_DIAG_REQ_V2_ALL_STATES); + id.pack(byteBuffer); + } + + @Override + public String toString() { + final String familyStr = NetlinkConstants.stringForAddressFamily(sdiag_family); + final String protocolStr = NetlinkConstants.stringForAddressFamily(sdiag_protocol); + + return "StructInetDiagReqV2{ " + + "sdiag_family{" + familyStr + "}, " + + "sdiag_protocol{" + protocolStr + "}, " + + "idiag_ext{" + 0 + ")}, " + + "pad{" + 0 + "}, " + + "idiag_states{" + Integer.toHexString(INET_DIAG_REQ_V2_ALL_STATES) + "}, " + + id.toString() + + "}"; + } +} diff --git a/services/net/java/android/net/netlink/StructInetDiagSockId.java b/services/net/java/android/net/netlink/StructInetDiagSockId.java new file mode 100644 index 000000000000..2e9fa253463d --- /dev/null +++ b/services/net/java/android/net/netlink/StructInetDiagSockId.java @@ -0,0 +1,86 @@ +/* + * 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.net.netlink; + +import static java.nio.ByteOrder.BIG_ENDIAN; + +import java.net.Inet4Address; +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * struct inet_diag_req_v2 + * + * see <linux_src>/include/uapi/linux/inet_diag.h + * + * struct inet_diag_sockid { + * __be16 idiag_sport; + * __be16 idiag_dport; + * __be32 idiag_src[4]; + * __be32 idiag_dst[4]; + * __u32 idiag_if; + * __u32 idiag_cookie[2]; + * #define INET_DIAG_NOCOOKIE (~0U) + * }; + * + * @hide + */ +public class StructInetDiagSockId { + public static final int STRUCT_SIZE = 48; + + private final InetSocketAddress mLocSocketAddress; + private final InetSocketAddress mRemSocketAddress; + private final byte[] INET_DIAG_NOCOOKIE = new byte[]{ + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; + private final byte[] IPV4_PADDING = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + public StructInetDiagSockId(InetSocketAddress loc, InetSocketAddress rem) { + mLocSocketAddress = loc; + mRemSocketAddress = rem; + } + + public void pack(ByteBuffer byteBuffer) { + byteBuffer.order(BIG_ENDIAN); + byteBuffer.putShort((short) mLocSocketAddress.getPort()); + byteBuffer.putShort((short) mRemSocketAddress.getPort()); + byteBuffer.put(mLocSocketAddress.getAddress().getAddress()); + if (mLocSocketAddress.getAddress() instanceof Inet4Address) { + byteBuffer.put(IPV4_PADDING); + } + byteBuffer.put(mRemSocketAddress.getAddress().getAddress()); + if (mRemSocketAddress.getAddress() instanceof Inet4Address) { + byteBuffer.put(IPV4_PADDING); + } + byteBuffer.order(ByteOrder.nativeOrder()); + byteBuffer.putInt(0); + byteBuffer.put(INET_DIAG_NOCOOKIE); + } + + @Override + public String toString() { + return "StructInetDiagSockId{ " + + "idiag_sport{" + mLocSocketAddress.getPort() + "}, " + + "idiag_dport{" + mRemSocketAddress.getPort() + "}, " + + "idiag_src{" + mLocSocketAddress.getAddress().getHostAddress() + "}, " + + "idiag_dst{" + mRemSocketAddress.getAddress().getHostAddress() + "}, " + + "idiag_if{" + 0 + "} " + + "idiag_cookie{INET_DIAG_NOCOOKIE}" + + "}"; + } +} diff --git a/services/net/java/android/net/util/SharedLog.java b/services/net/java/android/net/util/SharedLog.java index f7bf393f367b..5a73a4e492ee 100644 --- a/services/net/java/android/net/util/SharedLog.java +++ b/services/net/java/android/net/util/SharedLog.java @@ -17,6 +17,7 @@ package android.net.util; import android.annotation.NonNull; +import android.annotation.Nullable; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; @@ -92,10 +93,17 @@ public class SharedLog { } /** - * Log an error due to an exception, with the exception stacktrace. + * Log an error due to an exception, with the exception stacktrace if provided. + * + * <p>The error and exception message appear in the shared log, but the stacktrace is only + * logged in general log output (logcat). */ - public void e(@NonNull String msg, @NonNull Throwable e) { - Log.e(mTag, record(Category.ERROR, msg + ": " + e.getMessage()), e); + public void e(@NonNull String msg, @Nullable Throwable exception) { + if (exception == null) { + e(msg); + return; + } + Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception); } public void i(String msg) { diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk index bf7836d42008..00ebae6613cc 100644 --- a/services/tests/servicestests/Android.mk +++ b/services/tests/servicestests/Android.mk @@ -57,6 +57,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \ libbacktrace \ libbase \ libbinder \ + libbinderthreadstate \ libc++ \ libcutils \ liblog \ diff --git a/services/tests/uiservicestests/Android.mk b/services/tests/uiservicestests/Android.mk index b98bc8937aa9..3fa776cc3180 100644 --- a/services/tests/uiservicestests/Android.mk +++ b/services/tests/uiservicestests/Android.mk @@ -45,6 +45,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \ libbacktrace \ libbase \ libbinder \ + libbinderthreadstate \ libc++ \ libcutils \ liblog \ diff --git a/services/tests/wmtests/Android.mk b/services/tests/wmtests/Android.mk index 0f8b18ab92cf..cd289740ea1e 100644 --- a/services/tests/wmtests/Android.mk +++ b/services/tests/wmtests/Android.mk @@ -14,9 +14,14 @@ LOCAL_SRC_FILES := \ $(call all-java-files-under, ../servicestests/utils) LOCAL_STATIC_JAVA_LIBRARIES := \ - androidx-test \ + frameworks-base-testutils \ + services.core \ + android-support-test \ mockito-target-minus-junit4 \ platform-test-annotations \ + truth-prebuilt \ + testables \ + ub-uiautomator \ LOCAL_JAVA_LIBRARIES := \ android.test.mock \ diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index 1fb947309028..7e4bd42c8c55 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -22,10 +22,30 @@ android:minSdkVersion="1" android:targetSdkVersion="28" /> - <application android:testOnly="true" /> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> + <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> + <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> + <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> + <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> + <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" /> + <uses-permission android:name="android.permission.READ_FRAME_BUFFER" /> + <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" /> + <uses-permission android:name="android.permission.REORDER_TASKS" /> + <uses-permission android:name="android.permission.MANAGE_USERS" /> + + <application android:testOnly="true"> + <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityA" /> + <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityB" /> + <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" /> + <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" /> + <activity android:name="com.android.server.am.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" /> + <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity" /> + </application> <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" + android:name="android.support.test.runner.AndroidJUnitRunner" android:label="Window Manager Tests" android:targetPackage="com.android.frameworks.wmtests" /> </manifest> diff --git a/services/tests/wmtests/AndroidTest.xml b/services/tests/wmtests/AndroidTest.xml index 2717ef901216..38a62ae9bbe3 100644 --- a/services/tests/wmtests/AndroidTest.xml +++ b/services/tests/wmtests/AndroidTest.xml @@ -24,9 +24,9 @@ </target_preparer> <option name="test-tag" value="WmTests" /> - <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.wmtests" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - <option name="hidden-api-checks" value="false" /> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java index f741c70e4821..089dc61fc250 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java @@ -16,6 +16,16 @@ package com.android.server.am; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; + +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import android.app.ActivityOptions; import android.content.pm.ActivityInfo; import android.graphics.Rect; @@ -24,26 +34,16 @@ import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import com.android.server.am.LaunchParamsController.LaunchParams; -import org.junit.runner.RunWith; + import org.junit.Before; import org.junit.Test; - -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.doAnswer; - -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; +import org.junit.runner.RunWith; /** * Tests for exercising resizing bounds due to activity options. * * Build/Install/Run: - * atest FrameworksServicesTests:ActivityLaunchParamsModifierTests + * atest WmTests:ActivityLaunchParamsModifierTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/wmtests/src/com/android/server/am/ActivityManagerInternalTest.java index bce87dc58819..f393d14e1cfb 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityManagerInternalTest.java @@ -33,17 +33,8 @@ import org.mockito.MockitoAnnotations; /** * Test class for {@link ActivityManagerInternal}. * - * To run the tests, use - * - * runtest -c com.android.server.am.ActivityManagerInternalTest frameworks-services - * - * or the following steps: - * - * Build: m FrameworksServicesTests - * Install: adb install -r \ - * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk - * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerInternalTest -w \ - * com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner + * Build/Install/Run: + * atest WmTests:ActivityManagerInternalTest */ @RunWith(AndroidJUnit4.class) public class ActivityManagerInternalTest { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/wmtests/src/com/android/server/am/ActivityManagerServiceTest.java index c70d1e18c871..c41197dca2d7 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -28,6 +28,7 @@ import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.util.DebugUtils.valueToString; + import static com.android.server.am.ActivityManagerInternalTest.CustomThread; import static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG; import static com.android.server.am.ActivityManagerService.Injector; @@ -88,17 +89,8 @@ import java.util.function.Function; /** * Test class for {@link ActivityManagerService}. * - * To run the tests, use - * - * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services - * - * or the following steps: - * - * Build: m FrameworksServicesTests - * Install: adb install -r \ - * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk - * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \ - * com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner + * Build/Install/Run: + * atest WmTests:ActivityManagerServiceTest */ @SmallTest @RunWith(AndroidJUnit4.class) @@ -830,4 +822,4 @@ public class ActivityManagerServiceTest { mRestricted = restricted; } } -}
\ No newline at end of file +} diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/wmtests/src/com/android/server/am/ActivityManagerTest.java index ba25b1659bd2..a2f942e7f96e 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityManagerTest.java @@ -18,13 +18,18 @@ package com.android.server.am; import android.app.ActivityManager; import android.app.IActivityManager; -import android.os.ServiceManager; -import android.os.UserHandle; import android.os.RemoteException; +import android.os.UserHandle; import android.test.AndroidTestCase; import java.util.List; +/** + * Tests for {@link ActivityManager}. + * + * Build/Install/Run: + * atest WmTests:ActivityManagerTest + */ public class ActivityManagerTest extends AndroidTestCase { IActivityManager service; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityRecordTests.java index 5ee1c405bb0e..616cc0f4007f 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityRecordTests.java @@ -22,11 +22,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.view.Display.DEFAULT_DISPLAY; -import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; -import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; -import static com.android.server.am.ActivityStack.ActivityState.FINISHING; import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING; -import static com.android.server.am.ActivityStack.ActivityState.PAUSED; import static com.android.server.am.ActivityStack.ActivityState.PAUSING; import static com.android.server.am.ActivityStack.ActivityState.STOPPED; import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING; @@ -57,17 +53,16 @@ import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.util.MutableBoolean; -import org.junit.runner.RunWith; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; /** * Tests for the {@link ActivityRecord} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.am.ActivityRecordTests + * atest WmTests:com.android.server.am.ActivityRecordTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityStackSupervisorTests.java index 1ce41a641935..2209b66e3ed6 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -62,7 +62,7 @@ import java.util.ArrayList; * Tests for the {@link ActivityStackSupervisor} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests + * atest WmTests:ActivityStackSupervisorTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityStackTests.java index 01425ed51b55..cac264b81198 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityStackTests.java @@ -33,13 +33,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import android.content.pm.ActivityInfo; import android.os.UserHandle; @@ -47,15 +43,15 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import org.junit.runner.RunWith; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link ActivityStack} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.am.ActivityStackTests + * atest WmTests:ActivityStackTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityStartControllerTests.java index 7948e4cfcaaa..37a5a17caf47 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityStartControllerTests.java @@ -19,6 +19,13 @@ package com.android.server.am; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + import android.content.Intent; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; @@ -27,15 +34,8 @@ import android.support.test.runner.AndroidJUnit4; import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch; import com.android.server.am.ActivityStarter.Factory; -import org.junit.runner.RunWith; import org.junit.Test; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.times; +import org.junit.runner.RunWith; import java.util.Random; @@ -43,7 +43,7 @@ import java.util.Random; * Tests for the {@link ActivityStartController} class. * * Build/Install/Run: - * atest FrameworksServicesTests:ActivityStartControllerTests + * atest WmTests:ActivityStartControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/am/ActivityStartInterceptorTest.java index b4b34c507942..8f2d2844fc9e 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityStartInterceptorTest.java @@ -55,7 +55,7 @@ import org.mockito.MockitoAnnotations; * Unit tests for {@link ActivityStartInterceptorTest}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.am.ActivityStartInterceptorTest + * bit WmTests:ActivityStartInterceptorTest */ @SmallTest public class ActivityStartInterceptorTest { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/am/ActivityStarterTests.java index 1520859d4aac..048df43916e0 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityStarterTests.java @@ -32,10 +32,26 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; +import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; + +import static com.android.server.am.ActivityManagerService.ANIMATE; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyObject; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import android.app.ActivityOptions; import android.app.IApplicationThread; -import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.WindowLayout; @@ -50,39 +66,18 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.Gravity; -import org.junit.runner.RunWith; -import org.junit.Test; - -import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; -import static com.android.server.am.ActivityManagerService.ANIMATE; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyObject; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.times; - import com.android.internal.os.BatteryStatsImpl; -import com.android.server.am.ActivityStarter.Factory; import com.android.server.am.LaunchParamsController.LaunchParamsModifier; import com.android.server.am.TaskRecord.TaskRecordFactory; -import java.util.ArrayList; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link ActivityStarter} class. * * Build/Install/Run: - * atest FrameworksServicesTests:ActivityStarterTests + * atest WmTests:ActivityStarterTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/am/ActivityTestsBase.java index 1cd111fce0ec..d9a346b6c589 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/am/ActivityTestsBase.java @@ -21,21 +21,17 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.view.Display.DEFAULT_DISPLAY; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; + import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import android.app.ActivityOptions; -import com.android.server.wm.DisplayWindowController; - -import org.junit.Rule; -import org.mockito.invocation.InvocationOnMock; - import android.app.IApplicationThread; import android.content.ComponentName; import android.content.Context; @@ -52,20 +48,21 @@ import android.service.voice.IVoiceInteractionSession; import android.support.test.InstrumentationRegistry; import android.testing.DexmakerShareClassLoaderRule; - import com.android.internal.app.IVoiceInteractor; - import com.android.server.AttributeCache; import com.android.server.wm.AppWindowContainerController; +import com.android.server.wm.DisplayWindowController; import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.StackWindowController; import com.android.server.wm.TaskWindowContainerController; import com.android.server.wm.WindowManagerService; import com.android.server.wm.WindowTestUtils; + import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.mockito.MockitoAnnotations; - +import org.mockito.invocation.InvocationOnMock; /** * A base class to handle common operations in activity related unit tests. diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/wmtests/src/com/android/server/am/AppErrorDialogTest.java index 3d11c4c84ff1..2289dfc08d0c 100644 --- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java +++ b/services/tests/wmtests/src/com/android/server/am/AppErrorDialogTest.java @@ -32,7 +32,10 @@ import org.junit.runner.RunWith; import java.io.File; /** - * runtest -c com.android.server.am.AppErrorDialogTest frameworks-services + * Tests for {@link AppErrorDialog}. + * + * Build/Install/Run: + * atest WmTests:AppErrorDialogTest */ @RunWith(AndroidJUnit4.class) @SmallTest diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/am/AssistDataRequesterTest.java index ce88d849a1d4..285a84f5972b 100644 --- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java +++ b/services/tests/wmtests/src/com/android/server/am/AssistDataRequesterTest.java @@ -62,7 +62,8 @@ import java.util.concurrent.TimeUnit; * Note: Currently, we only support fetching the screenshot for the current application, so the * screenshot checks are hardcoded accordingly. * - * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java + * Build/Install/Run: + * atest WmTests:AssistDataRequesterTest */ @MediumTest @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/am/ClientLifecycleManagerTests.java index ef6d5e81b472..3098db267a74 100644 --- a/services/tests/servicestests/src/com/android/server/am/ClientLifecycleManagerTests.java +++ b/services/tests/wmtests/src/com/android/server/am/ClientLifecycleManagerTests.java @@ -1,3 +1,19 @@ +/* + * 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.server.am; import static org.mockito.Mockito.mock; @@ -15,6 +31,12 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Test class for {@link ClientLifecycleManager}. + * + * Build/Install/Run: + * atest WmTests:ClientLifecycleManagerTests + */ @RunWith(AndroidJUnit4.class) @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/wmtests/src/com/android/server/am/CoreSettingsObserverTest.java index da30c11be81a..adf3f940820a 100644 --- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java +++ b/services/tests/wmtests/src/com/android/server/am/CoreSettingsObserverTest.java @@ -37,7 +37,6 @@ import com.android.server.AppOpsService; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -48,17 +47,8 @@ import java.io.File; /** * Test class for {@link CoreSettingsObserver}. * - * To run the tests, use - * - * runtest -c com.android.server.am.CoreSettingsObserverTest frameworks-services - * - * or the following steps: - * - * Build: m FrameworksServicesTests - * Install: adb install -r \ - * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk - * Run: adb shell am instrument -e class com.android.server.am.CoreSettingsObserverTest -w \ - * com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner + * Build/Install/Run: + * atest WmTests:CoreSettingsObserverTest */ @SmallTest @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java b/services/tests/wmtests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java index d9b3e1c0173b..b1e0b51366bd 100644 --- a/services/tests/servicestests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java +++ b/services/tests/wmtests/src/com/android/server/am/GlobalSettingsToPropertiesMapperTest.java @@ -36,6 +36,9 @@ import java.util.Map; /** * Tests for {@link GlobalSettingsToPropertiesMapper} + * + * Build/Install/Run: + * atest WmTests:GlobalSettingsToPropertiesMapperTest */ @RunWith(AndroidJUnit4.class) @SmallTest diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/am/LaunchParamsControllerTests.java index 161c2875bf49..5f2bc4d3fea4 100644 --- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/am/LaunchParamsControllerTests.java @@ -16,20 +16,14 @@ package com.android.server.am; -import android.app.ActivityOptions; -import android.content.pm.ActivityInfo.WindowLayout; -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; - -import com.android.server.am.LaunchParamsController.LaunchParams; -import org.junit.runner.RunWith; -import org.junit.Before; -import org.junit.Test; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import com.android.server.am.LaunchParamsController.LaunchParamsModifier; +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doNothing; @@ -40,18 +34,24 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE; -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP; +import android.app.ActivityOptions; +import android.content.pm.ActivityInfo.WindowLayout; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.MediumTest; +import android.support.test.runner.AndroidJUnit4; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import com.android.server.am.LaunchParamsController.LaunchParams; +import com.android.server.am.LaunchParamsController.LaunchParamsModifier; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for exercising {@link LaunchParamsController}. * * Build/Install/Run: - * atest FrameworksServicesTests:LaunchParamsControllerTests + * atest WmTests:LaunchParamsControllerTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/am/LockTaskControllerTest.java index f46d712df65b..a2e976922b7b 100644 --- a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/am/LockTaskControllerTest.java @@ -35,9 +35,20 @@ import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_LOCKED; import static com.android.server.am.LockTaskController.STATUS_BAR_MASK_PINNED; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.app.StatusBarManager; import android.app.admin.DevicePolicyManager; @@ -76,7 +87,7 @@ import org.mockito.verification.VerificationMode; * Unit tests for {@link LockTaskController}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.am.LockTaskControllerTest + * bit WmTests:LockTaskControllerTest */ @Presubmit @SmallTest diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/wmtests/src/com/android/server/am/MemoryStatUtilTest.java index 5518ca5bd8cc..18b0988f9726 100644 --- a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java +++ b/services/tests/wmtests/src/com/android/server/am/MemoryStatUtilTest.java @@ -16,9 +16,9 @@ package com.android.server.am; +import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg; import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs; -import static com.android.server.am.MemoryStatUtil.MemoryStat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -29,6 +29,12 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Tests for {@link MemoryStatUtil}. + * + * Build/Install/Run: + * atest WmTests:MemoryStatUtilTest + */ @RunWith(AndroidJUnit4.class) @SmallTest public class MemoryStatUtilTest { diff --git a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java index 2baf9952cb9e..f812ee6f1fda 100644 --- a/services/tests/servicestests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java +++ b/services/tests/wmtests/src/com/android/server/am/PendingRemoteAnimationRegistryTest.java @@ -20,14 +20,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import android.annotation.Nullable; import android.app.ActivityOptions; -import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import android.util.ArrayMap; import android.view.RemoteAnimationAdapter; import com.android.server.testutils.OffsettableClock; @@ -40,7 +37,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; /** - * atest PendingRemoteAnimationRegistryTest + * Tests for {@link PendingRemoteAnimationRegistry}. + * + * Build/Install/Run: + * atest WmTests:PendingRemoteAnimationRegistryTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/wmtests/src/com/android/server/am/PersistentConnectionTest.java index 54f93a88a387..5c42081d4655 100644 --- a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java +++ b/services/tests/wmtests/src/com/android/server/am/PersistentConnectionTest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.android.server.am; import static org.mockito.ArgumentMatchers.any; @@ -41,6 +42,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +/** + * Tests for {@link PersistentConnection}. + * + * Build/Install/Run: + * atest WmTests:PersistentConnectionTest + */ @SmallTest public class PersistentConnectionTest extends AndroidTestCase { private static class MyConnection extends PersistentConnection<IDeviceAdminService> { diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/am/RecentTasksTest.java index b73ac8934cb0..739467a48d16 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/am/RecentTasksTest.java @@ -35,16 +35,12 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static java.lang.Integer.MAX_VALUE; -import android.annotation.TestApi; import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; -import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; @@ -53,7 +49,6 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; -import android.os.Debug; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; @@ -80,7 +75,10 @@ import java.util.Random; import java.util.Set; /** - * atest FrameworksServicesTests:RecentTasksTest + * Tests for {@link RecentTasks}. + * + * Build/Install/Run: + * atest WmTests:RecentTasksTest */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/am/RecentsAnimationTest.java index eefd973112f5..ee576e310982 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/am/RecentsAnimationTest.java @@ -16,15 +16,13 @@ package com.android.server.am; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; -import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; + import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; + import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; @@ -39,13 +37,18 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.view.IRecentsAnimationRunner; + import com.android.server.AttributeCache; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; /** - * atest FrameworksServicesTests:RecentsAnimationTest + * Tests for {@link RecentsAnimation}. + * + * Build/Install/Run: + * atest WmTests:RecentsAnimationTest */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/am/RunningTasksTest.java index c6ce7e1188e8..4e5fbd8f8279 100644 --- a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/am/RunningTasksTest.java @@ -41,8 +41,11 @@ import org.junit.runner.RunWith; import java.util.ArrayList; -/** - * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java + /** + * Tests for {@link RunningTasks}. + * + * Build/Install/Run: + * atest WmTests:RunningTasksTest */ @MediumTest @Presubmit @@ -123,4 +126,4 @@ public class RunningTasksTest extends ActivityTestsBase { .build(); return task; } -}
\ No newline at end of file +} diff --git a/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/am/SafeActivityOptionsTest.java index 168bc1782d56..3f05c8c7e9f5 100644 --- a/services/tests/servicestests/src/com/android/server/am/SafeActivityOptionsTest.java +++ b/services/tests/wmtests/src/com/android/server/am/SafeActivityOptionsTest.java @@ -27,6 +27,12 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Tests for {@link SafeActivityOptions}. + * + * Build/Install/Run: + * atest WmTests:SafeActivityOptionsTest + */ @MediumTest @Presubmit @FlakyTest diff --git a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/am/TaskLaunchParamsModifierTests.java index 3d323f0eb783..7fb63d3d4355 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/am/TaskLaunchParamsModifierTests.java @@ -16,37 +16,29 @@ package com.android.server.am; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; + +import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; + +import static org.junit.Assert.assertEquals; + import android.content.pm.ActivityInfo.WindowLayout; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; - import android.view.Gravity; -import org.junit.runner.RunWith; import org.junit.Before; import org.junit.Test; - -import org.mockito.invocation.InvocationOnMock; - -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; - -import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.doAnswer; -import static org.junit.Assert.assertEquals; - +import org.junit.runner.RunWith; /** * Tests for exercising resizing task bounds. * * Build/Install/Run: - * atest FrameworksServicesTests:TaskLaunchParamsModifierTests + * atest WmTests:TaskLaunchParamsModifierTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/wmtests/src/com/android/server/am/TaskPersisterTest.java index 9e6055d55e0f..cdafb5258a34 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java +++ b/services/tests/wmtests/src/com/android/server/am/TaskPersisterTest.java @@ -17,20 +17,16 @@ package com.android.server.am; import android.content.pm.UserInfo; -import android.os.Environment; import android.os.UserHandle; import android.os.UserManager; import android.test.AndroidTestCase; -import android.util.Log; import android.util.SparseBooleanArray; -import com.android.server.am.TaskPersister; - -import java.io.File; -import java.util.Random; - /** - * atest FrameworksServicesTests:TaskPersisterTest + * Tests for {@link TaskPersister}. + * + * Build/Install/Run: + * atest WmTests:TaskPersisterTest */ public class TaskPersisterTest extends AndroidTestCase { private static final String TEST_USER_NAME = "AM-Test-User"; diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/am/TaskRecordTests.java index 057fdc8c10bb..dbb3e7ee4183 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/am/TaskRecordTests.java @@ -29,20 +29,16 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.content.res.XmlResourceParser; import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.service.voice.IVoiceInteractionSession; -import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.util.Xml; -import com.android.frameworks.servicestests.R; import com.android.internal.app.IVoiceInteractor; import com.android.server.am.TaskRecord.TaskRecordFactory; -import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,15 +53,13 @@ import java.io.FileReader; import java.io.IOException; import java.io.OutputStream; import java.io.Reader; -import java.nio.file.Files; import java.util.ArrayList; -import java.util.Comparator; /** * Tests for exercising {@link TaskRecord}. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.am.TaskRecordTests + * atest WmTests:TaskRecordTests */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/am/TaskStackChangedListenerTest.java index 0359096892bb..28689cb701c9 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java +++ b/services/tests/wmtests/src/com/android/server/am/TaskStackChangedListenerTest.java @@ -17,6 +17,7 @@ package com.android.server.am; import static android.support.test.InstrumentationRegistry.getInstrumentation; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -32,23 +33,30 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.content.res.Resources.Theme; import android.os.RemoteException; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.text.TextUtils; -import android.util.Pair; + import com.android.internal.annotations.GuardedBy; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; + import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * Tests for {@link TaskStackListener}. + * + * Build/Install/Run: + * atest WmTests:TaskStackChangedListenerTest + */ @MediumTest @RunWith(AndroidJUnit4.class) public class TaskStackChangedListenerTest { diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/wmtests/src/com/android/server/am/UserControllerTest.java index cc4f51987523..fb5ded51489f 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/am/UserControllerTest.java @@ -16,6 +16,30 @@ package com.android.server.am; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; + +import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG; +import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG; +import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG; +import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG; +import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG; +import static com.android.server.am.UserController.SYSTEM_USER_START_MSG; +import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + import android.app.IUserSwitchObserver; import android.content.Context; import android.content.IIntentReceiver; @@ -48,30 +72,11 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; -import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG; -import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG; -import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG; -import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG; -import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG; -import static com.android.server.am.UserController.SYSTEM_USER_START_MSG; -import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; - /** - * Usage: bit FrameworksServicesTests:com.android.server.am.UserControllerTest + * Tests for {@link UserController}. + * + * Build/Install/Run: + * atest WmTests:UserControllerTest */ @Presubmit public class UserControllerTest extends AndroidTestCase { diff --git a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java b/services/tests/wmtests/src/com/android/server/policy/FakeWindowState.java index 7487d4490d9a..7487d4490d9a 100644 --- a/services/tests/servicestests/src/com/android/server/policy/FakeWindowState.java +++ b/services/tests/wmtests/src/com/android/server/policy/FakeWindowState.java diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java index 7e18ce78c9d1..7e18ce78c9d1 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java +++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerInsetsTest.java diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java index 97a716f6bd99..97a716f6bd99 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java +++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTest.java index 30665b56c8dc..30665b56c8dc 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTest.java +++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTest.java diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTestBase.java index 2c47a9432eff..2c47a9432eff 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java +++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTestBase.java diff --git a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java index 164c80b2427a..a396946db247 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java @@ -18,13 +18,10 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; + import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -33,12 +30,9 @@ import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -46,7 +40,7 @@ import org.mockito.MockitoAnnotations; * Tests for the {@link TaskStack} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.AnimatingAppWindowTokenRegistryTest + * atest WmTests:AnimatingAppWindowTokenRegistryTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java index be7d781799fa..6b3266d2f0a0 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -20,6 +20,7 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; + import static org.junit.Assert.assertEquals; import android.content.Context; @@ -36,7 +37,8 @@ import org.junit.runner.RunWith; /** * Test class for {@link AppTransition}. * - * atest AppTransitionTests + * Build/Install/Run: + * atest WmTests:AppTransitionTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowContainerControllerTests.java index e0645b1f4bfb..09a084737def 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowContainerControllerTests.java @@ -16,30 +16,32 @@ package com.android.server.wm; -import android.support.test.filters.FlakyTest; -import org.junit.Test; - -import android.platform.test.annotations.Presubmit; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.EMPTY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + import com.android.server.wm.WindowTestUtils.TestTaskWindowContainerController; +import org.junit.Test; + /** * Test class for {@link AppWindowContainerController}. * - * atest FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests + * Build/Install/Run: + * atest WmTests:AppWindowContainerControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index f6599dcaf87e..8dedb584ae59 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -16,16 +16,6 @@ package com.android.server.wm; -import org.junit.Test; -import org.junit.runner.RunWith; - -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.FlakyTest; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; -import android.view.Surface; -import android.view.WindowManager; - import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; @@ -38,15 +28,27 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_UNSET; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.Surface; +import android.view.WindowManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + /** * Tests for the {@link AppWindowToken} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests + * atest WmTests:AppWindowTokenTests */ @SmallTest // TODO: b/68267650 diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java index ff631e74e004..7fbb4ee3b0b4 100644 --- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BoundsAnimationControllerTests.java @@ -21,6 +21,12 @@ import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_ import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_START; import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Rect; @@ -32,23 +38,12 @@ import android.support.test.annotation.UiThreadTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import com.android.server.wm.BoundsAnimationController.BoundsAnimator; import com.android.server.wm.WindowManagerInternal.AppTransitionListener; import org.junit.Test; import org.junit.runner.RunWith; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import com.android.server.wm.BoundsAnimationController.BoundsAnimator; - /** * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks * depending on the various interactions. @@ -60,7 +55,7 @@ import com.android.server.wm.BoundsAnimationController.BoundsAnimator; * appropriately. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests + * bit WmTests:BoundsAnimationControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java index 192e1564ae8d..6a6f9543842f 100644 --- a/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ConfigurationContainerTests.java @@ -17,7 +17,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -28,6 +27,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; import static android.content.res.Configuration.EMPTY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -35,6 +35,7 @@ import android.content.res.Configuration; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; @@ -45,7 +46,7 @@ import java.util.List; * Test class for {@link ConfigurationContainer}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests + * atest WmTests:ConfigurationContainerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java index 6769e40dca78..a12a802f0920 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java @@ -38,8 +38,10 @@ import org.junit.Test; import org.junit.runner.RunWith; /** + * Tests for {@link Dimmer}. + * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.DimmerTests; + * atest WmTests:DimmerTests; */ @Presubmit @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index ac196f9c80dc..a9744ea2dc1a 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -28,6 +28,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; + import static com.android.server.wm.WindowContainer.POSITION_TOP; import static org.hamcrest.Matchers.is; @@ -38,9 +39,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import org.junit.Test; -import org.junit.runner.RunWith; - import android.annotation.SuppressLint; import android.content.res.Configuration; import android.graphics.Rect; @@ -57,6 +55,9 @@ import android.view.Surface; import com.android.server.wm.utils.WmDisplayCutout; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -67,7 +68,7 @@ import java.util.List; * Tests for the {@link DisplayContent} class. * * Build/Install/Run: - * atest com.android.server.wm.DisplayContentTests + * atest WmTests:DisplayContentTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index a09656c7dc92..68b09982be98 100644 --- a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; + import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; @@ -39,19 +40,23 @@ import android.view.InputChannel; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; + import com.android.internal.annotations.GuardedBy; import com.android.server.LocalServices; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + /** * Tests for the {@link DragDropController} class. * - * atest com.android.server.wm.DragDropControllerTests + * Build/Install/Run: + * atest WmTests:DragDropControllerTests */ @SmallTest @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/PinnedStackControllerTest.java index 96745fa5956e..f0faf28fd129 100644 --- a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/PinnedStackControllerTest.java @@ -2,6 +2,15 @@ package com.android.server.wm; import static android.view.Display.DEFAULT_DISPLAY; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; @@ -14,15 +23,12 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - +/** + * Tests for {@link PinnedStackController}. + * + * Build/Install/Run: + * atest WmTests:PinnedStackControllerTest + */ @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index a2af9b80fe36..fdebaa6df18c 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -19,8 +19,10 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; + import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; + import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; @@ -35,7 +37,9 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.IRecentsAnimationRunner; import android.view.SurfaceControl; + import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,7 +47,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; /** - * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest + * Tests for {@link RecentsAnimationController}. + * + * Build/Install/Run: + * atest WmTests:RecentsAnimationControllerTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 95361f03fe4b..383e53fafeea 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -31,7 +31,6 @@ import android.graphics.Rect; import android.os.Binder; import android.os.IInterface; import android.platform.test.annotations.Presubmit; -import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.IRemoteAnimationFinishedCallback; @@ -53,7 +52,10 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; /** - * atest FrameworksServicesTests:com.android.server.wm.RemoteAnimationControllerTest + * Tests for {@link RemoteAnimationController}. + * + * Build/Install/Run: + * atest WmTests:RemoteAnimationControllerTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 204e26cee532..317f36cc2077 100644 --- a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -1,22 +1,21 @@ package com.android.server.wm; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.junit.Assert.assertTrue; import android.content.res.Configuration; import android.graphics.Rect; - import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link RootWindowContainer} class. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests + * atest WmTests:RootWindowContainerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java index a2ccee46e0c9..7e7cfed991ba 100644 --- a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ScreenDecorWindowTests.java @@ -32,6 +32,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + import static org.junit.Assert.assertEquals; import android.app.Activity; @@ -70,7 +71,7 @@ import java.util.function.BooleanSupplier; * Tests for the {@link android.view.WindowManager.LayoutParams#PRIVATE_FLAG_IS_SCREEN_DECOR} flag. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.ScreenDecorWindowTests + * atest WmTests:ScreenDecorWindowTests */ // TODO: Add test for FLAG_FULLSCREEN which hides the status bar and also other flags. // TODO: Test non-Activity windows. diff --git a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/StackWindowControllerTests.java index ab0a2bd86dd8..fb2986c0212d 100644 --- a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/StackWindowControllerTests.java @@ -16,25 +16,24 @@ package com.android.server.wm; -import android.graphics.Rect; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Test class for {@link StackWindowController}. * * Build/Install/Run: - * atest FrameworksServicesTests:StackWindowControllerTests + * atest WmTests:StackWindowControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java index edac8a5202d7..9ea370284fc2 100644 --- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -24,11 +23,11 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.animation.AnimationHandler; +import static java.util.concurrent.TimeUnit.SECONDS; + import android.animation.AnimationHandler.AnimationFrameCallbackProvider; import android.animation.ValueAnimator; import android.graphics.Matrix; @@ -37,7 +36,6 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import android.util.Log; import android.view.Choreographer; import android.view.Choreographer.FrameCallback; import android.view.SurfaceControl; @@ -46,7 +44,6 @@ import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import com.android.server.wm.LocalAnimationAdapter.AnimationSpec; -import com.android.server.wm.SurfaceAnimationRunner.AnimatorFactory; import org.junit.Before; import org.junit.Rule; @@ -61,7 +58,8 @@ import java.util.concurrent.CountDownLatch; /** * Test class for {@link SurfaceAnimationRunner}. * - * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimationRunnerTest + * Build/Install/Run: + * atest WmTests:SurfaceAnimationRunnerTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java index 16b84581de39..66f4b194a5ac 100644 --- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java @@ -46,12 +46,11 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.util.ArrayList; - /** * Test class for {@link SurfaceAnimatorTest}. * - * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimatorTest + * Build/Install/Run: + * atest WmTests:SurfaceAnimatorTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java index 7bf7dd78711c..ae730895f5d7 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java @@ -16,10 +16,14 @@ package com.android.server.wm; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; +import static com.android.server.wm.TaskPositioner.MIN_ASPECT; +import static com.android.server.wm.WindowManagerService.dipToPixel; +import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; +import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import android.graphics.Rect; import android.support.test.filters.SmallTest; @@ -28,18 +32,16 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; -import static com.android.server.wm.TaskPositioner.MIN_ASPECT; -import static com.android.server.wm.WindowManagerService.dipToPixel; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP; -import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link TaskPositioner} class. * - * runtest frameworks-services -c com.android.server.wm.TaskPositionerTests + * Build/Install/Run: + * atest WmTests:TaskPositionerTests */ @SmallTest @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java index 6070516669b5..659ec41c30c4 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -30,6 +31,7 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.InputChannel; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,7 +39,8 @@ import org.junit.runner.RunWith; /** * Tests for the {@link TaskPositioningController} class. * - * atest com.android.server.wm.TaskPositioningControllerTests + * Build/Install/Run: + * atest WmTests:TaskPositioningControllerTests */ @SmallTest @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java index 649de4a783fa..1aefa277e84f 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; + import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; @@ -31,7 +32,8 @@ import org.junit.runner.RunWith; /** * Test class for {@link TaskSnapshotCache}. * - * runtest frameworks-services -c com.android.server.wm.TaskSnapshotCacheTest + * Build/Install/Run: + * atest WmTests:TaskSnapshotCacheTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java index 5650050f0420..77521a652ca3 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java @@ -19,10 +19,11 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.TRANSIT_UNSET; -import static com.android.server.wm.TaskSnapshotController.*; + +import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME; +import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL; + import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; @@ -30,13 +31,15 @@ import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; import com.google.android.collect.Sets; + import org.junit.Test; import org.junit.runner.RunWith; /** * Test class for {@link TaskSnapshotController}. * - * runtest frameworks-services -c com.android.server.wm.TaskSnapshotControllerTest + * Build/Install/Run: + * atest WmTests:TaskSnapshotControllerTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java index 325d42aa6293..ed81dafe3205 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java @@ -18,12 +18,12 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import android.app.ActivityManager.TaskSnapshot; import android.content.res.Configuration; @@ -33,8 +33,8 @@ import android.platform.test.annotations.Presubmit; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; - import android.view.View; + import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem; import org.junit.Test; @@ -45,7 +45,8 @@ import java.io.File; /** * Test class for {@link TaskSnapshotPersister} and {@link TaskSnapshotLoader} * - * atest FrameworksServicesTests:TaskSnapshotPersisterLoaderTest + * Build/Install/Run: + * atest WmTests:TaskSnapshotPersisterLoaderTest */ @MediumTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java index 8b8604365fa1..8b8604365fa1 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java index b19373efd1b0..287fff554a61 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; + import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; @@ -47,7 +48,8 @@ import org.junit.runner.RunWith; /** * Test class for {@link TaskSnapshotSurface}. * - * runtest frameworks-services -c com.android.server.wm.TaskSnapshotSurfaceTest + * Build/Install/Run: + * atest WmTests:TaskSnapshotSurfaceTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java index ca1994f85ccf..e66b0d9c841d 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java @@ -18,26 +18,25 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.Before; -import org.junit.After; - import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + /** * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests + * atest WmTests:TaskStackContainersTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java index eaf71f0dc5b3..0deb4af542c4 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java @@ -16,27 +16,24 @@ package com.android.server.wm; -import org.junit.Test; -import org.junit.runner.RunWith; - -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; + +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link TaskStack} class. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.TaskStackTests + * atest WmTests:TaskStackTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskWindowContainerControllerTests.java index 1dd9365825cf..e734bc0615c6 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskWindowContainerControllerTests.java @@ -16,22 +16,23 @@ package com.android.server.wm; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - /** * Test class for {@link TaskWindowContainerController}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests + * atest WmTests:TaskWindowContainerControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java index 353aa7deb534..032f4162b48e 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java @@ -16,8 +16,6 @@ package com.android.server.wm; -import com.android.internal.os.IResultReceiver; - import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -27,6 +25,8 @@ import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IWindow; +import com.android.internal.os.IResultReceiver; + public class TestIWindow extends IWindow.Stub { @Override public void executeCommand(String command, String parameters, diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java index ee028ba4262b..ee028ba4262b 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java index a5c47deb2c06..903352b7bec5 100644 --- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java @@ -29,7 +29,8 @@ import org.junit.runner.RunWith; /** * Test class for {@link AppTransition}. * - * runtest frameworks-services -c com.android.server.wm.UnknownAppVisibilityControllerTest + * Build/Install/Run: + * atest WmTests:UnknownAppVisibilityControllerTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java index 71ead204c9df..71ead204c9df 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowAnimationSpecTest.java index ca520ed76be6..aac905e8ffd4 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowAnimationSpecTest.java @@ -40,7 +40,8 @@ import org.junit.runner.RunWith; /** * Tests for the {@link WindowAnimationSpec} class. * - * atest FrameworksServicesTests:com.android.server.wm.WindowAnimationSpecTest + * Build/Install/Run: + * atest WmTests:WindowAnimationSpecTest */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java index 513c1ecda990..9c59a1748dbf 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java @@ -16,7 +16,16 @@ package com.android.server.wm; -import org.junit.Test; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS; +import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE; +import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import android.app.WindowConfiguration; import android.content.res.Configuration; @@ -27,22 +36,13 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.DisplayInfo; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS; -import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE; -import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; +import org.junit.Test; /** * Test class to for {@link android.app.WindowConfiguration}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests + * atest WmTests:WindowConfigurationTests */ @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java index 502cb6e27c68..05f7c347f0b8 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java @@ -16,26 +16,26 @@ package com.android.server.wm; -import android.app.WindowConfiguration; -import android.content.res.Configuration; -import android.support.test.filters.FlakyTest; -import org.junit.Test; - -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.content.res.Configuration.EMPTY; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.res.Configuration; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; + /** * Test class for {@link WindowContainerController}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests + * atest WmTests:WindowContainerControllerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 6c7830e5cf79..5beeee151497 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -16,20 +16,6 @@ package com.android.server.wm; -import android.support.test.filters.FlakyTest; -import android.view.SurfaceControl; -import android.view.SurfaceSession; -import org.junit.Test; -import org.junit.runner.RunWith; - -import android.content.res.Configuration; -import android.graphics.Rect; -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - -import java.util.Comparator; - import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; @@ -44,7 +30,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; - import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.eq; @@ -53,11 +38,25 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import android.content.res.Configuration; +import android.graphics.Rect; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.SurfaceControl; +import android.view.SurfaceSession; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Comparator; + /** * Test class for {@link WindowContainer}. * * Build/Install/Run: - * atest FrameworksServicesTests:com.android.server.wm.WindowContainerTests + * atest WmTests:WindowContainerTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java index e07639933b7a..e1acd78c5bc6 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java @@ -20,9 +20,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; + +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Matchers.eq; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; @@ -31,12 +32,13 @@ import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; - import java.util.function.Consumer; /** * Tests for {@link WindowContainer#forAllWindows} and various implementations. + * + * Build/Install/Run: + * atest WmTests:WindowContainerTraversalTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java index 5a563320f9cb..6a00de473a85 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java @@ -16,9 +16,12 @@ package com.android.server.wm; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import static android.view.DisplayCutout.fromBoundingRect; +import static android.view.WindowManager.LayoutParams.FILL_PARENT; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import android.app.ActivityManager.TaskDescription; import android.content.res.Configuration; @@ -31,18 +34,17 @@ import android.view.Gravity; import android.view.IWindow; import android.view.WindowManager; -import static android.view.DisplayCutout.fromBoundingRect; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; -import static android.view.WindowManager.LayoutParams.FILL_PARENT; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import com.android.server.wm.utils.WmDisplayCutout; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + /** * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery. * - * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests + * Build/Install/Run: + * atest WmTests:WindowFrameTests */ @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java index d91079e3bb1b..d91079e3bb1b 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRuleTest.java index 6cf6d7bc96ec..6cf6d7bc96ec 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRuleTest.java diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 85e846db60b7..0f07e7eb3090 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -16,17 +16,6 @@ package com.android.server.wm; -import android.view.WindowManager; -import org.junit.Test; -import org.junit.runner.RunWith; - -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.FlakyTest; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - -import java.util.LinkedList; - import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; @@ -55,10 +44,22 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.WindowManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.LinkedList; + /** * Tests for the {@link WindowState} class. * - * atest FrameworksServicesTests:com.android.server.wm.WindowStateTests + * Build/Install/Run: + * atest WmTests:WindowStateTests */ @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowSurfacePlacerTest.java index e173b7db2da7..13f791634e4f 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowSurfacePlacerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowSurfacePlacerTest.java @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.TRANSIT_TASK_CLOSE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; + import static junit.framework.Assert.assertEquals; import android.platform.test.annotations.Presubmit; @@ -31,6 +32,12 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Tests for {@link WindowSurfacePlacer}. + * + * Build/Install/Run: + * atest WmTests:WindowSurfacePlacerTest + */ @SmallTest @Presubmit @RunWith(AndroidJUnit4.class) diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java index 2e4740b57255..6ab9c3010dd5 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java @@ -16,21 +16,12 @@ package com.android.server.wm; -import android.app.ActivityManager; -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.os.Binder; -import android.os.IBinder; -import android.view.IApplicationToken; -import android.view.IWindow; -import android.view.WindowManager; - import static android.app.AppOpsManager.OP_NONE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.server.wm.WindowContainer.POSITION_TOP; + import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyFloat; @@ -39,6 +30,15 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.ActivityManager; +import android.content.res.Configuration; +import android.graphics.Rect; +import android.os.Binder; +import android.os.IBinder; +import android.view.IApplicationToken; +import android.view.IWindow; +import android.view.WindowManager; + import org.mockito.invocation.InvocationOnMock; /** diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 473a287e3d9c..473a287e3d9c 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index e3b717435052..5ea87b14f746 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -16,29 +16,29 @@ package com.android.server.wm; -import org.junit.Test; -import org.junit.runner.RunWith; - -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.FlakyTest; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; - import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; + +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; /** * Tests for the {@link WindowToken} class. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests + * atest WmTests:WindowTokenTests */ @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java index 50852548f525..f60ae75b85f2 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java @@ -30,13 +30,12 @@ import static org.mockito.Mockito.verifyZeroInteractions; import android.content.Context; import android.platform.test.annotations.Presubmit; import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.proto.ProtoOutputStream; import com.android.internal.util.Preconditions; -import com.android.server.wm.WindowManagerTraceProto; import org.junit.After; import org.junit.Before; @@ -54,7 +53,7 @@ import java.nio.charset.StandardCharsets; * Test class for {@link WindowTracing}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.WindowTracingTest + * atest WmTests:WindowTracingTest */ @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java index 547be551c842..a730b5cf84e6 100644 --- a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java @@ -27,15 +27,14 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; import android.platform.test.annotations.Presubmit; -import android.support.test.filters.SmallTest; import android.support.test.filters.FlakyTest; +import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -51,7 +50,7 @@ import java.util.LinkedList; * Tests for the {@link WindowLayersController} class. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.ZOrderingTests + * atest WmTests:ZOrderingTests */ @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/CoordinateTransformsTest.java index 40a10e04c893..f0f3023f1f17 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/CoordinateTransformsTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/CoordinateTransformsTest.java @@ -21,10 +21,11 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; -import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates; +import static com.android.server.wm.utils.CoordinateTransforms + .transformPhysicalToLogicalCoordinates; import static org.hamcrest.Matchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; import android.graphics.Matrix; import android.graphics.Point; @@ -35,6 +36,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; +/** + * Tests for {@link CoordinateTransforms}. + * + * Build/Install/Run: + * atest WmTests:CoordinateTransformsTest + */ public class CoordinateTransformsTest { private static final int W = 200; @@ -95,4 +102,4 @@ public class CoordinateTransformsTest { public interface DevicePointAssertable { void mapsToLogicalPoint(int x, int y); } -}
\ No newline at end of file +} diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/InsetUtilsTest.java index d0f0fe315bcf..ff3d883056e4 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/InsetUtilsTest.java @@ -22,11 +22,16 @@ import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; -import android.util.Pair; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Tests for {@link InsetUtils}. + * + * Build/Install/Run: + * atest WmTests:InsetUtilsTest + */ @RunWith(AndroidJUnit4.class) @SmallTest @Presubmit diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java index 6bbc7eb56688..c800fa2fe6b1 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/RotationCacheTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java @@ -29,13 +29,16 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.Pair; -import com.android.server.wm.utils.RotationCache.RotationDependentComputation; - -import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +/** + * Tests for {@link RotationCache}. + * + * Build/Install/Run: + * atest WmTests:RotationCacheTest + */ @RunWith(AndroidJUnit4.class) @SmallTest @FlakyTest(bugId = 74078662) diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java index f7addf6c77f9..f4c208b4ce0e 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java @@ -16,7 +16,6 @@ package com.android.server.wm.utils; - import static android.view.DisplayCutout.NO_CUTOUT; import static android.view.DisplayCutout.fromBoundingRect; @@ -38,7 +37,8 @@ import java.util.Arrays; /** * Tests for {@link WmDisplayCutout} * - * Run with: atest WmDisplayCutoutTest + * Build/Install/Run: + * atest WmTests:WmDisplayCutoutTest */ @RunWith(AndroidJUnit4.class) @SmallTest diff --git a/startop/tools/view_compiler/Android.bp b/startop/tools/view_compiler/Android.bp new file mode 100644 index 000000000000..c3e91849e636 --- /dev/null +++ b/startop/tools/view_compiler/Android.bp @@ -0,0 +1,49 @@ +// +// 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. +// + +cc_library_host_static { + name: "libviewcompiler", + srcs: [ + "java_lang_builder.cc", + "util.cc", + ], + static_libs: [ + "libbase" + ] +} + +cc_binary_host { + name: "viewcompiler", + srcs: [ + "main.cc", + ], + static_libs: [ + "libbase", + "libtinyxml2", + "libgflags", + "libviewcompiler", + ], +} + +cc_test_host { + name: "view-compiler-tests", + srcs: [ + "util_test.cc", + ], + static_libs: [ + "libviewcompiler", + ] +} diff --git a/startop/tools/view_compiler/README.md b/startop/tools/view_compiler/README.md new file mode 100644 index 000000000000..56595016cbb9 --- /dev/null +++ b/startop/tools/view_compiler/README.md @@ -0,0 +1,25 @@ +# View Compiler + +This directory contains an experimental compiler for layout files. + +It will take a layout XML file and produce a CompiledLayout.java file with a +specialized layout inflation function. + +To use it, let's assume you had a layout in `my_layout.xml` and your app was in +the Java language package `com.example.myapp`. Run the following command: + + viewcompiler my_layout.xml --package com.example.myapp --out CompiledView.java + +This will produce a `CompiledView.java`, which can then be compiled into your +Android app. Then to use it, in places where you would have inflated +`R.layouts.my_layout`, instead call `CompiledView.inflate`. + +Precompiling views like this generally improves the time needed to inflate them. + +This tool is still in its early stages and has a number of limitations. +* Currently only one layout can be compiled at a time. +* `merge` and `include` nodes are not supported. +* View compilation is a manual process that requires code changes in the + application. +* This only works for apps that do not use a custom layout inflater. +* Other limitations yet to be discovered. diff --git a/startop/tools/view_compiler/TEST_MAPPING b/startop/tools/view_compiler/TEST_MAPPING new file mode 100644 index 000000000000..cc4b17a7a65a --- /dev/null +++ b/startop/tools/view_compiler/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "view-compiler-tests" + } + ] +} diff --git a/startop/tools/view_compiler/java_lang_builder.cc b/startop/tools/view_compiler/java_lang_builder.cc new file mode 100644 index 000000000000..0b8754fc7096 --- /dev/null +++ b/startop/tools/view_compiler/java_lang_builder.cc @@ -0,0 +1,115 @@ +/* + * 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. + */ + +#include "java_lang_builder.h" + +#include "android-base/stringprintf.h" + +using android::base::StringPrintf; +using std::string; + +void JavaLangViewBuilder::Start() const { + out_ << StringPrintf("package %s;\n", package_.c_str()) + << "import android.content.Context;\n" + "import android.content.res.Resources;\n" + "import android.content.res.XmlResourceParser;\n" + "import android.util.AttributeSet;\n" + "import android.util.Xml;\n" + "import android.view.*;\n" + "import android.widget.*;\n" + "\n" + "public final class CompiledView {\n" + "\n" + "static <T extends View> T createView(Context context, AttributeSet attrs, View parent, " + "String name, LayoutInflater.Factory factory, LayoutInflater.Factory2 factory2) {" + "\n" + " if (factory2 != null) {\n" + " return (T)factory2.onCreateView(parent, name, context, attrs);\n" + " } else if (factory != null) {\n" + " return (T)factory.onCreateView(name, context, attrs);\n" + " }\n" + // TODO: find a way to call the private factory + " return null;\n" + "}\n" + "\n" + " public static View inflate(Context context) {\n" + " try {\n" + " LayoutInflater inflater = LayoutInflater.from(context);\n" + " LayoutInflater.Factory factory = inflater.getFactory();\n" + " LayoutInflater.Factory2 factory2 = inflater.getFactory2();\n" + " Resources res = context.getResources();\n" + << StringPrintf(" XmlResourceParser xml = res.getLayout(%s.R.layout.%s);\n", + package_.c_str(), + layout_name_.c_str()) + << " AttributeSet attrs = Xml.asAttributeSet(xml);\n" + // The Java-language XmlPullParser needs a call to next to find the start document tag. + " xml.next(); // start document\n"; +} + +void JavaLangViewBuilder::Finish() const { + out_ << " } catch (Exception e) {\n" + " return null;\n" + " }\n" // end try + " }\n" // end inflate + "}\n"; // end CompiledView +} + +void JavaLangViewBuilder::StartView(const string& class_name) { + const string view_var = MakeVar("view"); + const string layout_var = MakeVar("layout"); + std::string parent = "null"; + if (!view_stack_.empty()) { + const StackEntry& parent_entry = view_stack_.back(); + parent = parent_entry.view_var; + } + out_ << " xml.next(); // <" << class_name << ">\n" + << StringPrintf(" %s %s = createView(context, attrs, %s, \"%s\", factory, factory2);\n", + class_name.c_str(), + view_var.c_str(), + parent.c_str(), + class_name.c_str()) + << StringPrintf(" if (%s == null) %s = new %s(context, attrs);\n", + view_var.c_str(), + view_var.c_str(), + class_name.c_str()); + if (!view_stack_.empty()) { + out_ << StringPrintf(" ViewGroup.LayoutParams %s = %s.generateLayoutParams(attrs);\n", + layout_var.c_str(), + parent.c_str()); + } + view_stack_.push_back({class_name, view_var, layout_var}); +} + +void JavaLangViewBuilder::FinishView() { + const StackEntry var = view_stack_.back(); + view_stack_.pop_back(); + if (!view_stack_.empty()) { + const string& parent = view_stack_.back().view_var; + out_ << StringPrintf(" xml.next(); // </%s>\n", var.class_name.c_str()) + << StringPrintf(" %s.addView(%s, %s);\n", + parent.c_str(), + var.view_var.c_str(), + var.layout_params_var.c_str()); + } else { + out_ << StringPrintf(" return %s;\n", var.view_var.c_str()); + } +} + +const std::string JavaLangViewBuilder::MakeVar(std::string prefix) { + std::stringstream v; + v << prefix << view_id_++; + return v.str(); +} diff --git a/startop/tools/view_compiler/java_lang_builder.h b/startop/tools/view_compiler/java_lang_builder.h new file mode 100644 index 000000000000..c8d20b23cd13 --- /dev/null +++ b/startop/tools/view_compiler/java_lang_builder.h @@ -0,0 +1,65 @@ +/* + * 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. + */ +#ifndef JAVA_LANG_BUILDER_H_ +#define JAVA_LANG_BUILDER_H_ + +#include <iostream> +#include <sstream> +#include <vector> + +// Build Java language code to instantiate views. +// +// This has a very small interface to make it easier to generate additional +// backends, such as a direct-to-DEX version. +class JavaLangViewBuilder { + public: + JavaLangViewBuilder(std::string package, std::string layout_name, std::ostream& out = std::cout) + : package_(package), layout_name_(layout_name), out_(out) {} + + // Begin generating a class. Adds the package boilerplate, etc. + void Start() const; + // Finish generating a class, closing off any open curly braces, etc. + void Finish() const; + + // Begin creating a view (i.e. process the opening tag) + void StartView(const std::string& class_name); + // Finish a view, after all of its child nodes have been processed. + void FinishView(); + + private: + const std::string MakeVar(std::string prefix); + + std::string const package_; + std::string const layout_name_; + + std::ostream& out_; + + size_t view_id_ = 0; + + struct StackEntry { + // The class name for this view object + const std::string class_name; + + // The variable name that is holding the view object + const std::string view_var; + + // The variable name that holds the object's layout parameters + const std::string layout_params_var; + }; + std::vector<StackEntry> view_stack_; +}; + +#endif // JAVA_LANG_BUILDER_H_ diff --git a/startop/tools/view_compiler/main.cc b/startop/tools/view_compiler/main.cc new file mode 100644 index 000000000000..0ad7e24feb3b --- /dev/null +++ b/startop/tools/view_compiler/main.cc @@ -0,0 +1,105 @@ +/* + * 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. + */ + +#include "gflags/gflags.h" + +#include "java_lang_builder.h" +#include "util.h" + +#include "tinyxml2.h" + +#include <fstream> +#include <iostream> +#include <sstream> +#include <string> +#include <vector> + +using namespace tinyxml2; +using std::string; + +constexpr char kStdoutFilename[]{"stdout"}; + +DEFINE_string(package, "", "The package name for the generated class (required)"); +DEFINE_string(out, kStdoutFilename, "Where to write the generated class"); + +namespace { +class ViewCompilerXmlVisitor : public XMLVisitor { + public: + ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {} + + bool VisitEnter(const XMLDocument& /*doc*/) override { + builder_->Start(); + return true; + } + + bool VisitExit(const XMLDocument& /*doc*/) override { + builder_->Finish(); + return true; + } + + bool VisitEnter(const XMLElement& element, const XMLAttribute* /*firstAttribute*/) override { + builder_->StartView(element.Name()); + return true; + } + + bool VisitExit(const XMLElement& /*element*/) override { + builder_->FinishView(); + return true; + } + + private: + JavaLangViewBuilder* builder_; +}; +} // end namespace + +int main(int argc, char** argv) { + constexpr size_t kProgramName = 0; + constexpr size_t kFileNameParam = 1; + constexpr size_t kNumRequiredArgs = 2; + + gflags::SetUsageMessage( + "Compile XML layout files into equivalent Java language code\n" + "\n" + " example usage: viewcompiler layout.xml --package com.example.androidapp"); + gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags*/ true); + + gflags::CommandLineFlagInfo cmd = gflags::GetCommandLineFlagInfoOrDie("package"); + if (argc != kNumRequiredArgs || cmd.is_default) { + gflags::ShowUsageWithFlags(argv[kProgramName]); + return 1; + } + + const char* const filename = argv[kFileNameParam]; + const string layout_name = FindLayoutNameFromFilename(filename); + + // We want to generate Java language code to inflate exactly this layout. This means + // generating code to walk the resource XML too. + + XMLDocument xml; + xml.LoadFile(filename); + + std::ofstream outfile; + if (FLAGS_out != kStdoutFilename) { + outfile.open(FLAGS_out); + } + JavaLangViewBuilder builder{ + FLAGS_package, layout_name, FLAGS_out == kStdoutFilename ? std::cout : outfile}; + + ViewCompilerXmlVisitor visitor{&builder}; + xml.Accept(&visitor); + + return 0; +}
\ No newline at end of file diff --git a/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java b/startop/tools/view_compiler/util.cc index 023e4ab6636f..69df41dff3d7 100644 --- a/services/tests/wmtests/src/com/android/server/am/DummyAmTests.java +++ b/startop/tools/view_compiler/util.cc @@ -14,33 +14,19 @@ * limitations under the License. */ -package com.android.server.am; +#include "util.h" -import android.platform.test.annotations.Presubmit; +using std::string; -import org.junit.Test; +// TODO: see if we can borrow this from somewhere else, like aapt2. +string FindLayoutNameFromFilename(const string& filename) { + size_t start = filename.rfind("/"); + if (start == string::npos) { + start = 0; + } else { + start++; // advance past '/' character + } + size_t end = filename.find(".", start); -import androidx.test.filters.FlakyTest; - -/** - * Dummy test for com.android.server.am. - * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests. - */ -public class DummyAmTests { - - @Presubmit - @Test - public void preSubmitTest() {} - - @FlakyTest - @Presubmit - @Test - public void flakyPreSubmitTest() {} - - @Test - public void postSubmitTest() {} - - @FlakyTest - @Test - public void flakyPostSubmitTest() {} + return filename.substr(start, end - start); } diff --git a/startop/tools/view_compiler/util.h b/startop/tools/view_compiler/util.h new file mode 100644 index 000000000000..03e093920bfa --- /dev/null +++ b/startop/tools/view_compiler/util.h @@ -0,0 +1,23 @@ +/* + * 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. + */ +#ifndef UTIL_H_ +#define UTIL_H_ + +#include <string> + +std::string FindLayoutNameFromFilename(const std::string& filename); + +#endif // UTIL_H_ diff --git a/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java b/startop/tools/view_compiler/util_test.cc index aecb2783badd..d1540d3a6e43 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DummyWmTests.java +++ b/startop/tools/view_compiler/util_test.cc @@ -14,33 +14,15 @@ * limitations under the License. */ -package com.android.server.wm; +#include "util.h" -import android.platform.test.annotations.Presubmit; +#include "gtest/gtest.h" -import org.junit.Test; +using std::string; -import androidx.test.filters.FlakyTest; - -/** - * Dummy test for com.android.server.wm - * TODO(b/113800711): Remove this class once the actual tests are moved from servicestests. - */ -public class DummyWmTests { - - @Presubmit - @Test - public void preSubmitTest() {} - - @FlakyTest - @Presubmit - @Test - public void flakyPreSubmitTest() {} - - @Test - public void postSubmitTest() {} - - @FlakyTest - @Test - public void flakyPostSubmitTest() {} +TEST(UtilTest, FindLayoutNameFromFilename) { + EXPECT_EQ("bar", ::FindLayoutNameFromFilename("foo/bar.xml")); + EXPECT_EQ("bar", ::FindLayoutNameFromFilename("bar.xml")); + EXPECT_EQ("bar", ::FindLayoutNameFromFilename("./foo/bar.xml")); + EXPECT_EQ("bar", ::FindLayoutNameFromFilename("/foo/bar.xml")); } diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 096cf37d4c65..08bc9bcc4003 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -141,6 +141,8 @@ public final class Call { * The caller must specify the {@link #EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE} to indicate to * Telecom which {@link PhoneAccountHandle} the {@link Call} should be handed over to. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_REQUEST_HANDOVER = "android.telecom.event.REQUEST_HANDOVER"; @@ -149,6 +151,8 @@ public final class Call { * Extra key used with the {@link #EVENT_REQUEST_HANDOVER} call event. Specifies the * {@link PhoneAccountHandle} to which a call should be handed over to. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.HANDOVER_PHONE_ACCOUNT_HANDLE"; @@ -161,6 +165,8 @@ public final class Call { * {@link VideoProfile#STATE_BIDIRECTIONAL}, {@link VideoProfile#STATE_RX_ENABLED}, and * {@link VideoProfile#STATE_TX_ENABLED}. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_VIDEO_STATE = "android.telecom.extra.HANDOVER_VIDEO_STATE"; @@ -176,6 +182,8 @@ public final class Call { * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)} * is called to initate the handover. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EXTRA_HANDOVER_EXTRAS = "android.telecom.extra.HANDOVER_EXTRAS"; @@ -186,6 +194,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_COMPLETE = "android.telecom.event.HANDOVER_COMPLETE"; @@ -198,6 +208,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_SOURCE_DISCONNECTED = "android.telecom.event.HANDOVER_SOURCE_DISCONNECTED"; @@ -209,6 +221,8 @@ public final class Call { * <p> * A handover is initiated with the {@link #EVENT_REQUEST_HANDOVER} call event. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; @@ -434,8 +448,15 @@ public final class Call { */ public static final int PROPERTY_RTT = 0x00000400; + /** + * Indicates that the call has been identified as the network as an emergency call. This + * property may be set for both incoming and outgoing calls which the network identifies as + * emergency calls. + */ + public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 0x00000800; + //****************************************************************************************** - // Next PROPERTY value: 0x00000800 + // Next PROPERTY value: 0x00001000 //****************************************************************************************** private final String mTelecomCallId; @@ -601,6 +622,9 @@ public final class Call { if(hasProperty(properties, PROPERTY_ASSISTED_DIALING_USED)) { builder.append(" PROPERTY_ASSISTED_DIALING_USED"); } + if (hasProperty(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) { + builder.append(" PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL"); + } builder.append("]"); return builder.toString(); } diff --git a/telecomm/java/android/telecom/CallRedirectionService.java b/telecomm/java/android/telecom/CallRedirectionService.java index 9c874bf305b1..b906d0bf3136 100644 --- a/telecomm/java/android/telecom/CallRedirectionService.java +++ b/telecomm/java/android/telecom/CallRedirectionService.java @@ -63,6 +63,10 @@ public abstract class CallRedirectionService extends Service { /** * Telecom calls this method to inform the implemented {@link CallRedirectionService} of * a new outgoing call which is being placed. + * + * The implemented {@link CallRedirectionService} can call {@link #placeCallUnmodified()}, + * {@link #redirectCall(Uri, PhoneAccountHandle)}, and {@link #cancelCall()} only from here. + * * @param handle the phone number dialed by the user * @param targetPhoneAccount the {@link PhoneAccountHandle} on which the call will be placed. */ @@ -72,6 +76,9 @@ public abstract class CallRedirectionService extends Service { * The implemented {@link CallRedirectionService} calls this method to response a request * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that no changes * are required to the outgoing call, and that the call should be placed as-is. + * + * This can only be called from implemented {@link #onPlaceCall(Uri, PhoneAccountHandle)}. + * */ public final void placeCallUnmodified() { try { @@ -84,6 +91,9 @@ public abstract class CallRedirectionService extends Service { * The implemented {@link CallRedirectionService} calls this method to response a request * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that changes * are required to the phone number or/and {@link PhoneAccountHandle} for the outgoing call. + * + * This can only be called from implemented {@link #onPlaceCall(Uri, PhoneAccountHandle)}. + * * @param handle the new phone number to dial * @param targetPhoneAccount the {@link PhoneAccountHandle} to use when placing the call. * If {@code null}, no change will be made to the @@ -100,6 +110,9 @@ public abstract class CallRedirectionService extends Service { * The implemented {@link CallRedirectionService} calls this method to response a request * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that an outgoing * call should be canceled entirely. + * + * This can only be called from implemented {@link #onPlaceCall(Uri, PhoneAccountHandle)}. + * */ public final void cancelCall() { try { @@ -144,7 +157,6 @@ public abstract class CallRedirectionService extends Service { @Override public void placeCall(ICallRedirectionAdapter adapter, Uri handle, PhoneAccountHandle targetPhoneAccount) { - Log.v(this, "placeCall"); SomeArgs args = SomeArgs.obtain(); args.arg1 = adapter; args.arg2 = handle; @@ -154,14 +166,12 @@ public abstract class CallRedirectionService extends Service { } @Override - public IBinder onBind(Intent intent) { - Log.v(this, "onBind"); + public final IBinder onBind(Intent intent) { return new CallRedirectionBinder(); } @Override - public boolean onUnbind(Intent intent) { - Log.v(this, "onUnbind"); + public final boolean onUnbind(Intent intent) { return false; } } diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 024bd303304f..a39e885204b7 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -22,6 +22,8 @@ import android.annotation.SystemApi; import android.os.Bundle; import android.os.SystemClock; import android.telecom.Connection.VideoProvider; +import android.telephony.ServiceState; +import android.telephony.TelephonyManager; import android.util.ArraySet; import java.util.ArrayList; @@ -573,6 +575,20 @@ public abstract class Conference extends Conferenceable { } /** + * Updates RIL voice radio technology used for current conference after its creation. + * + * @hide + */ + public void updateCallRadioTechAfterCreation() { + final Connection primaryConnection = getPrimaryConnection(); + if (primaryConnection != null) { + setCallRadioTech(primaryConnection.getCallRadioTech()); + } else { + Log.w(this, "No primary connection found while updateCallRadioTechAfterCreation"); + } + } + + /** * @hide * @deprecated Use {@link #setConnectionTime}. */ @@ -652,6 +668,37 @@ public abstract class Conference extends Conferenceable { } /** + * Sets RIL voice radio technology used for current conference. + * + * @param vrat the RIL voice radio technology used for current conference, + * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. + * + * @hide + */ + public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) { + putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE, + ServiceState.rilRadioTechnologyToNetworkType(vrat)); + } + + /** + * Returns RIL voice radio technology used for current conference. + * + * @return the RIL voice radio technology used for current conference, + * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. + * + * @hide + */ + public final @ServiceState.RilRadioTechnology int getCallRadioTech() { + int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + Bundle extras = getExtras(); + if (extras != null) { + voiceNetworkType = extras.getInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE, + TelephonyManager.NETWORK_TYPE_UNKNOWN); + } + return ServiceState.networkTypeToRilRadioTechnology(voiceNetworkType); + } + + /** * Inform this Conference that the state of its audio output has been changed externally. * * @param state The new audio state. diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 5d5b15d346d3..ee1ca5f120e8 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -38,6 +38,8 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.SystemClock; +import android.telephony.ServiceState; +import android.telephony.TelephonyManager; import android.util.ArraySet; import android.view.Surface; @@ -411,6 +413,13 @@ public abstract class Connection extends Conferenceable { */ public static final int PROPERTY_ASSISTED_DIALING_USED = 1 << 9; + /** + * Set by the framework to indicate that the network has identified a Connection as an emergency + * call. + * @hide + */ + public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1 << 10; + //********************************************************************************************** // Next PROPERTY value: 1<<10 //********************************************************************************************** @@ -584,6 +593,8 @@ public abstract class Connection extends Conferenceable { * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has * successfully completed. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_COMPLETE = "android.telecom.event.HANDOVER_COMPLETE"; @@ -593,6 +604,8 @@ public abstract class Connection extends Conferenceable { * {@link Call#EVENT_REQUEST_HANDOVER} that the handover from this {@link Connection} has failed * to complete. * @hide + * @deprecated Use {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} and its associated + * APIs instead. */ public static final String EVENT_HANDOVER_FAILED = "android.telecom.event.HANDOVER_FAILED"; @@ -800,6 +813,10 @@ public abstract class Connection extends Conferenceable { builder.append(isLong ? " PROPERTY_IS_RTT" : " rtt"); } + if (can(properties, PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL)) { + builder.append(isLong ? " PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL" : " ecall"); + } + builder.append("]"); return builder.toString(); } @@ -1879,6 +1896,24 @@ public abstract class Connection extends Conferenceable { } /** + * Returns RIL voice radio technology used for current connection. + * + * @return the RIL voice radio technology used for current connection, + * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. + * + * @hide + */ + public final @ServiceState.RilRadioTechnology int getCallRadioTech() { + int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + Bundle extras = getExtras(); + if (extras != null) { + voiceNetworkType = extras.getInt(TelecomManager.EXTRA_CALL_NETWORK_TYPE, + TelephonyManager.NETWORK_TYPE_UNKNOWN); + } + return ServiceState.networkTypeToRilRadioTechnology(voiceNetworkType); + } + + /** * @return The status hints for this connection. */ public final StatusHints getStatusHints() { @@ -2312,6 +2347,26 @@ public abstract class Connection extends Conferenceable { } /** + * Sets RIL voice radio technology used for current connection. + * + * @param vrat the RIL Voice Radio Technology used for current connection, + * see {@code RIL_RADIO_TECHNOLOGY_*} in {@link android.telephony.ServiceState}. + * + * @hide + */ + public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) { + putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE, + ServiceState.rilRadioTechnologyToNetworkType(vrat)); + // Propagates the call radio technology to its parent {@link android.telecom.Conference} + // This action only covers non-IMS CS conference calls. + // For IMS PS call conference call, it can be updated via its host connection + // {@link #Listener.onExtrasChanged} event. + if (getConference() != null) { + getConference().setCallRadioTech(vrat); + } + } + + /** * Sets the label and icon status to display in the in-call UI. * * @param statusHints The status label and icon to set. diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 4e2282337ccd..d33a537f2194 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -317,6 +317,15 @@ public class TelecomManager { "android.telecom.extra.CALL_TECHNOLOGY_TYPE"; /** + * Optional extra for communicating the call network technology used by a + * {@link android.telecom.Connection} to Telecom and InCallUI. + * + * @see {@code NETWORK_TYPE_*} in {@link android.telephony.TelephonyManager}. + */ + public static final String EXTRA_CALL_NETWORK_TYPE = + "android.telecom.extra.CALL_NETWORK_TYPE"; + + /** * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the * package name of the app specifying an alternative gateway for the call. * The value is a string. @@ -1875,6 +1884,43 @@ public class TelecomManager { } } + /** + * Determines if there is an ongoing emergency call. This can be either an outgoing emergency + * call, as identified by the dialed number, or because a call was identified by the network + * as an emergency call. + * @return {@code true} if there is an ongoing emergency call, {@code false} otherwise. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean isInEmergencyCall() { + try { + if (isServiceConnected()) { + return getTelecomService().isInEmergencyCall(); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException isInEmergencyCall: " + e); + return false; + } + return false; + } + + /** + * Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity. + * @param intent The {@link Intent#ACTION_CALL} intent to handle. + * @hide + */ + public void handleCallIntent(Intent intent) { + try { + if (isServiceConnected()) { + getTelecomService().handleCallIntent(intent); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException handleCallIntent: " + e); + } + + } + private ITelecomService getTelecomService() { if (mTelecomServiceOverride != null) { return mTelecomServiceOverride; diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index b4e7d56bc642..df7d6832833a 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -279,4 +279,14 @@ interface ITelecomService { * @see TelecomServiceImpl#acceptHandover */ void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct); + + /** + * @see TelecomServiceImpl#isInEmergencyCall + */ + boolean isInEmergencyCall(); + + /** + * @see TelecomServiceImpl#handleCallIntent + */ + void handleCallIntent(in Intent intent); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 8e1cd5928a54..6eaecc6760bc 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -271,6 +271,14 @@ public class CarrierConfigManager { KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; /** + * Do only allow auto selection in Advanced Network Settings when in home network. + * Manual selection is allowed when in roaming network. + * @hide + */ + public static final String + KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network"; + + /** * Control whether users receive a simplified network settings UI and improved network * selection. */ @@ -1087,6 +1095,15 @@ public class CarrierConfigManager { public static final String KEY_WFC_DATA_SPN_FORMAT_IDX_INT = "wfc_data_spn_format_idx_int"; /** + * Use root locale when reading wfcSpnFormats. + * + * If true, then the root locale will always be used when reading wfcSpnFormats. This means the + * non localized version of wfcSpnFormats will be used. + * @hide + */ + public static final String KEY_WFC_SPN_USE_ROOT_LOCALE = "wfc_spn_use_root_locale"; + + /** * The Component Name of the activity that can setup the emergency addrees for WiFi Calling * as per carrier requirement. * @hide @@ -1616,11 +1633,21 @@ public class CarrierConfigManager { * When {@code false}, use default title for Enhanced 4G LTE Mode settings. * When {@code true}, use the variant. * @hide + * @deprecated use {@link #KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT}. */ + @Deprecated public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL = "enhanced_4g_lte_title_variant_bool"; /** + * The index indicates the carrier specified title string of Enahnce 4G LTE Mode settings. + * Default value is 0, which indicates the default title string. + * @hide + */ + public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT = + "enhanced_4g_lte_title_variant_int"; + + /** * Indicates whether the carrier wants to notify the user when handover of an LTE video call to * WIFI fails. * <p> @@ -1957,6 +1984,17 @@ public class CarrierConfigManager { "skip_cf_fail_to_disable_dialog_bool"; /** + * Flag specifying whether operator supports including no reply condition timer option on + * CFNRy (3GPP TS 24.082 3: Call Forwarding on No Reply) in the call forwarding settings UI. + * {@code true} - include no reply condition timer option on CFNRy + * {@code false} - don't include no reply condition timer option on CFNRy + * + * @hide + */ + public static final String KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL = + "support_no_reply_timer_for_cfnry_bool"; + + /** * List of the FAC (feature access codes) to dial as a normal call. * @hide */ @@ -2096,6 +2134,16 @@ public class CarrierConfigManager { public static final String KEY_CALL_REDIRECTION_SERVICE_COMPONENT_NAME_STRING = "call_redirection_service_component_name_string"; + /** + * Flag specifying whether to show notification(call blocking disabled) when Enhanced Call + * Blocking(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL) is enabled and making emergency call. + * When true, notification is shown always. + * When false, notification is shown only when any setting of "Enhanced Blocked number" is + * enabled. + */ + public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = + "show_call_blocking_disabled_notification_always_bool"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -2152,6 +2200,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true); sDefaults.putBoolean(KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL, false); sDefaults.putBoolean(KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, false); + sDefaults.putBoolean(KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL, false); sDefaults.putBoolean(KEY_SIMPLIFIED_NETWORK_SETTINGS_BOOL, false); sDefaults.putBoolean(KEY_HIDE_SIM_LOCK_SETTINGS_BOOL, false); @@ -2274,6 +2323,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY, null); sDefaults.putInt(KEY_WFC_SPN_FORMAT_IDX_INT, 0); sDefaults.putInt(KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 0); + sDefaults.putBoolean(KEY_WFC_SPN_USE_ROOT_LOCALE, false); sDefaults.putString(KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false); sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false); @@ -2380,6 +2430,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null); sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false); + sDefaults.putInt(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0); sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false); sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null); sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false); @@ -2409,6 +2460,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL, false); sDefaults.putBoolean(KEY_RTT_SUPPORTED_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_CHARGE_INDICATION_BOOL, false); + sDefaults.putBoolean(KEY_SUPPORT_NO_REPLY_TIMER_FOR_CFNRY_BOOL, true); sDefaults.putStringArray(KEY_FEATURE_ACCESS_CODES_STRING_ARRAY, null); sDefaults.putBoolean(KEY_IDENTIFY_HIGH_DEFINITION_CALLS_IN_CALL_LOG_BOOL, false); sDefaults.putBoolean(KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL, false); @@ -2432,6 +2484,7 @@ public class CarrierConfigManager { }); sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false); } /** diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java new file mode 100644 index 000000000000..e3737976adf7 --- /dev/null +++ b/telephony/java/android/telephony/MbmsGroupCallSession.java @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; +import android.telephony.mbms.GroupCall; +import android.telephony.mbms.GroupCallCallback; +import android.telephony.mbms.InternalGroupCallCallback; +import android.telephony.mbms.InternalGroupCallSessionCallback; +import android.telephony.mbms.MbmsErrors; +import android.telephony.mbms.MbmsGroupCallSessionCallback; +import android.telephony.mbms.MbmsUtils; +import android.telephony.mbms.vendor.IMbmsGroupCallService; +import android.util.ArraySet; +import android.util.Log; + +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +/** + * This class provides functionality for accessing group call functionality over MBMS. + */ +public class MbmsGroupCallSession implements AutoCloseable { + private static final String LOG_TAG = "MbmsGroupCallSession"; + + /** + * Service action which must be handled by the middleware implementing the MBMS group call + * interface. + * @hide + */ + @SystemApi + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String MBMS_GROUP_CALL_SERVICE_ACTION = + "android.telephony.action.EmbmsGroupCall"; + + /** + * Metadata key that specifies the component name of the service to bind to for group calls. + * @hide + */ + @TestApi + public static final String MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA = + "mbms-group-call-service-override"; + + private static AtomicBoolean sIsInitialized = new AtomicBoolean(false); + + private AtomicReference<IMbmsGroupCallService> mService = new AtomicReference<>(null); + private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() { + @Override + public void binderDied() { + sIsInitialized.set(false); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Received death notification"); + } + }; + + private InternalGroupCallSessionCallback mInternalCallback; + private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>(); + + private final Context mContext; + private int mSubscriptionId; + + /** @hide */ + private MbmsGroupCallSession(Context context, Executor executor, int subscriptionId, + MbmsGroupCallSessionCallback callback) { + mContext = context; + mSubscriptionId = subscriptionId; + mInternalCallback = new InternalGroupCallSessionCallback(callback, executor); + } + + /** + * Create a new {@link MbmsGroupCallSession} using the given subscription ID. + * + * You may only have one instance of {@link MbmsGroupCallSession} per UID. If you call this + * method while there is an active instance of {@link MbmsGroupCallSession} in your process + * (in other words, one that has not had {@link #close()} called on it), this method will + * throw an {@link IllegalStateException}. If you call this method in a different process + * running under the same UID, an error will be indicated via + * {@link MbmsGroupCallSessionCallback#onError(int, String)}. + * + * Note that initialization may fail asynchronously. If you wish to try again after you + * receive such an asynchronous error, you must call {@link #close()} on the instance of + * {@link MbmsGroupCallSession} that you received before calling this method again. + * + * @param context The {@link Context} to use. + * @param executor The executor on which you wish to execute callbacks. + * @param subscriptionId The subscription ID to use. + * @param callback A callback object on which you wish to receive results of asynchronous + * operations. + * @return An instance of {@link MbmsGroupCallSession}, or null if an error occurred. + */ + public static @Nullable MbmsGroupCallSession create(@NonNull Context context, + @NonNull Executor executor, int subscriptionId, + final @NonNull MbmsGroupCallSessionCallback callback) { + if (!sIsInitialized.compareAndSet(false, true)) { + throw new IllegalStateException("Cannot create two instances of MbmsGroupCallSession"); + } + MbmsGroupCallSession session = new MbmsGroupCallSession(context, executor, + subscriptionId, callback); + + final int result = session.bindAndInitialize(); + if (result != MbmsErrors.SUCCESS) { + sIsInitialized.set(false); + executor.execute(new Runnable() { + @Override + public void run() { + callback.onError(result, null); + } + }); + return null; + } + return session; + } + + /** + * Create a new {@link MbmsGroupCallSession} using the system default data subscription ID. + * See {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)}. + */ + public static MbmsGroupCallSession create(@NonNull Context context, + @NonNull Executor executor, @NonNull MbmsGroupCallSessionCallback callback) { + return create(context, executor, SubscriptionManager.getDefaultSubscriptionId(), callback); + } + + /** + * Terminates this instance. Also terminates + * any group calls spawned from this instance as if + * {@link GroupCall#close()} had been called on them. After this method returns, + * no further callbacks originating from the middleware will be enqueued on the provided + * instance of {@link MbmsGroupCallSessionCallback}, but callbacks that have already been + * enqueued will still be delivered. + * + * It is safe to call {@link #create(Context, Executor, int, MbmsGroupCallSessionCallback)} to + * obtain another instance of {@link MbmsGroupCallSession} immediately after this method + * returns. + * + * May throw an {@link IllegalStateException} + */ + public void close() { + try { + IMbmsGroupCallService groupCallService = mService.get(); + if (groupCallService == null) { + // Ignore and return, assume already disposed. + return; + } + groupCallService.dispose(mSubscriptionId); + for (GroupCall s : mKnownActiveGroupCalls) { + s.getCallback().stop(); + } + mKnownActiveGroupCalls.clear(); + } catch (RemoteException e) { + // Ignore for now + } finally { + mService.set(null); + sIsInitialized.set(false); + mInternalCallback.stop(); + } + } + + /** + * Starts the requested group call, reporting status to the indicated callback. + * Returns an object used to control that call. + * + * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException} + * + * Asynchronous errors through the callback include any of the errors in + * {@link MbmsErrors.GeneralErrors}. + * + * @param executor The executor on which you wish to execute callbacks for this stream. + * @param tmgi The TMGI, an identifier for the group call you want to join. + * @param saiArray An array of SAIs for the group call that should be negotiated separately with + * the carrier. + * @param frequencyArray An array of frequencies for the group call that should be negotiated + * separately with the carrier. + * @param callback The callback that you want to receive information about the call on. + * @return An instance of {@link GroupCall} through which the call can be controlled. + * May be {@code null} if an error occurred. + */ + public @Nullable GroupCall startGroupCall(@NonNull Executor executor, long tmgi, int[] saiArray, + int[] frequencyArray, @NonNull GroupCallCallback callback) { + IMbmsGroupCallService groupCallService = mService.get(); + if (groupCallService == null) { + throw new IllegalStateException("Middleware not yet bound"); + } + + InternalGroupCallCallback serviceCallback = new InternalGroupCallCallback( + callback, executor); + + GroupCall serviceForApp = new GroupCall(mSubscriptionId, + groupCallService, this, tmgi, serviceCallback); + mKnownActiveGroupCalls.add(serviceForApp); + + try { + int returnCode = groupCallService.startGroupCall( + mSubscriptionId, tmgi, saiArray, frequencyArray, serviceCallback); + if (returnCode == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return an unknown error code"); + } + if (returnCode != MbmsErrors.SUCCESS) { + mInternalCallback.onError(returnCode, null); + return null; + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService.set(null); + sIsInitialized.set(false); + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + return null; + } + + return serviceForApp; + } + + /** @hide */ + public void onGroupCallStopped(GroupCall service) { + mKnownActiveGroupCalls.remove(service); + } + + private int bindAndInitialize() { + return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, + new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + IMbmsGroupCallService groupCallService = + IMbmsGroupCallService.Stub.asInterface(service); + int result; + try { + result = groupCallService.initialize(mInternalCallback, + mSubscriptionId); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Service died before initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Runtime exception during initialization"); + mInternalCallback.onError( + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + e.toString()); + sIsInitialized.set(false); + return; + } + if (result == MbmsErrors.UNKNOWN) { + // Unbind and throw an obvious error + close(); + throw new IllegalStateException("Middleware must not return" + + " an unknown error code"); + } + if (result != MbmsErrors.SUCCESS) { + mInternalCallback.onError(result, + "Error returned during initialization"); + sIsInitialized.set(false); + return; + } + try { + groupCallService.asBinder().linkToDeath(mDeathRecipient, 0); + } catch (RemoteException e) { + mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST, + "Middleware lost during initialization"); + sIsInitialized.set(false); + return; + } + mService.set(groupCallService); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + sIsInitialized.set(false); + mService.set(null); + } + }); + } +} diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java index 8e99518d78b8..79298fd54c50 100644 --- a/telephony/java/android/telephony/NeighboringCellInfo.java +++ b/telephony/java/android/telephony/NeighboringCellInfo.java @@ -32,7 +32,12 @@ import android.os.Parcelable; /** * Represents the neighboring cell information, including * Received Signal Strength and Cell ID location. + * + * @deprecated This class should not be used by any app targeting + * {@link Build.VERSION_CODES.Q Android Q} or higher. Instead callers should use + * {@Link android.telephony.CellInfo CellInfo}. */ +@Deprecated public class NeighboringCellInfo implements Parcelable { /** diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java index 7c7d7a0397ad..202da6817cb5 100644 --- a/telephony/java/android/telephony/NetworkScan.java +++ b/telephony/java/android/telephony/NetworkScan.java @@ -16,11 +16,10 @@ package android.telephony; +import android.annotation.IntDef; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; -import android.annotation.IntDef; -import android.util.Log; import com.android.internal.telephony.ITelephony; @@ -113,6 +112,8 @@ public class NetworkScan { } try { telephony.stopNetworkScan(mSubId, mScanId); + } catch (IllegalArgumentException ex) { + Rlog.d(TAG, "stopNetworkScan - no active scan for ScanID=" + mScanId); } catch (RemoteException ex) { Rlog.e(TAG, "stopNetworkScan RemoteException", ex); } catch (RuntimeException ex) { diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index f2b73dccee2d..7469186a5d51 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -24,6 +24,7 @@ import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.telephony.AccessNetworkConstants.AccessNetworkType; +import android.telephony.NetworkRegistrationState.Domain; import android.text.TextUtils; import java.lang.annotation.Retention; @@ -1595,7 +1596,7 @@ public class ServiceState implements Parcelable { /** * Get all of the available network registration states. * - * @return List of registration states + * @return List of {@link NetworkRegistrationState} * @hide */ @SystemApi @@ -1606,14 +1607,30 @@ public class ServiceState implements Parcelable { } /** - * Get the network registration states with given transport type. + * Get the network registration states for the transport type. * - * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType} - * @return List of registration states. + * @param transportType The {@link AccessNetworkConstants.TransportType transport type} + * @return List of {@link NetworkRegistrationState} * @hide + * + * @deprecated Use {@link #getNetworkRegistrationStatesFromTransportType(int)} */ + @Deprecated @SystemApi public List<NetworkRegistrationState> getNetworkRegistrationStates(int transportType) { + return getNetworkRegistrationStatesForTransportType(transportType); + } + + /** + * Get the network registration states for the transport type. + * + * @param transportType The {@link AccessNetworkConstants.TransportType transport type} + * @return List of {@link NetworkRegistrationState} + * @hide + */ + @SystemApi + public List<NetworkRegistrationState> getNetworkRegistrationStatesForTransportType( + int transportType) { List<NetworkRegistrationState> list = new ArrayList<>(); synchronized (mNetworkRegistrationStates) { @@ -1628,16 +1645,57 @@ public class ServiceState implements Parcelable { } /** - * Get the network registration states with given transport type and domain. + * Get the network registration states for the network domain. * - * @param domain The network domain. Must be {@link NetworkRegistrationState#DOMAIN_CS} or - * {@link NetworkRegistrationState#DOMAIN_PS}. - * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType} - * @return The matching NetworkRegistrationState. + * @param domain The network {@link NetworkRegistrationState.Domain domain} + * @return List of {@link NetworkRegistrationState} * @hide */ @SystemApi - public NetworkRegistrationState getNetworkRegistrationStates(int domain, int transportType) { + public List<NetworkRegistrationState> getNetworkRegistrationStatesForDomain( + @Domain int domain) { + List<NetworkRegistrationState> list = new ArrayList<>(); + + synchronized (mNetworkRegistrationStates) { + for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) { + if (networkRegistrationState.getDomain() == domain) { + list.add(networkRegistrationState); + } + } + } + + return list; + } + + /** + * Get the network registration state for the transport type and network domain. + * + * @param domain The network {@link NetworkRegistrationState.Domain domain} + * @param transportType The {@link AccessNetworkConstants.TransportType transport type} + * @return The matching {@link NetworkRegistrationState} + * @hide + * + * @deprecated Use {@link #getNetworkRegistrationState(int, int)} + */ + @Deprecated + @SystemApi + public NetworkRegistrationState getNetworkRegistrationStates(@Domain int domain, + int transportType) { + return getNetworkRegistrationState(domain, transportType); + } + + /** + * Get the network registration state for the transport type and network domain. + * + * @param domain The network {@link NetworkRegistrationState.Domain domain} + * @param transportType The {@link AccessNetworkConstants.TransportType transport type} + * @return The matching {@link NetworkRegistrationState} + * @hide + * + */ + @SystemApi + public NetworkRegistrationState getNetworkRegistrationState(@Domain int domain, + int transportType) { synchronized (mNetworkRegistrationStates) { for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) { if (networkRegistrationState.getTransportType() == transportType @@ -1669,5 +1727,4 @@ public class ServiceState implements Parcelable { mNetworkRegistrationStates.add(regState); } } - } diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index ec266229b83a..22c1e58449de 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -33,11 +33,13 @@ import android.graphics.Typeface; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import java.util.Arrays; import java.util.List; +import java.util.Objects; /** * A Parcelable class for Subscription Information. @@ -552,11 +554,49 @@ public class SubscriptionInfo implements Parcelable { String cardIdToPrint = givePrintableIccid(mCardId); return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex + " displayName=" + mDisplayName + " carrierName=" + mCarrierName - + " nameSource=" + mNameSource + " iconTint=" + mIconTint + + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc - + " mnc " + mMnc + " isEmbedded " + mIsEmbedded + + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded + " accessRules " + Arrays.toString(mAccessRules) + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic + " parentSubId=" + mParentSubId + "}"; } -} + + @Override + public int hashCode() { + return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded, + mIsOpportunistic, mParentSubId, mIccId, mNumber, mMcc, mMnc, mCountryIso, + mCardId, mDisplayName, mCarrierName, mAccessRules); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + + SubscriptionInfo toCompare; + try { + toCompare = (SubscriptionInfo) obj; + } catch (ClassCastException ex) { + return false; + } + + return mId == toCompare.mId + && mSimSlotIndex == toCompare.mSimSlotIndex + && mNameSource == toCompare.mNameSource + && mIconTint == toCompare.mIconTint + && mDataRoaming == toCompare.mDataRoaming + && mIsEmbedded == toCompare.mIsEmbedded + && mIsOpportunistic == toCompare.mIsOpportunistic + && mParentSubId == toCompare.mParentSubId + && Objects.equals(mIccId, toCompare.mIccId) + && Objects.equals(mNumber, toCompare.mNumber) + && Objects.equals(mMcc, toCompare.mMcc) + && Objects.equals(mMnc, toCompare.mMnc) + && Objects.equals(mCountryIso, toCompare.mCountryIso) + && Objects.equals(mCardId, toCompare.mCardId) + && TextUtils.equals(mDisplayName, toCompare.mDisplayName) + && TextUtils.equals(mCarrierName, toCompare.mCarrierName) + && Arrays.equals(mAccessRules, toCompare.mAccessRules); + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 0c8280b9e086..3ef80c2efcb5 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -59,6 +59,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -1810,6 +1811,19 @@ public class SubscriptionManager { */ @UnsupportedAppUsage public static Resources getResourcesForSubId(Context context, int subId) { + return getResourcesForSubId(context, subId, false); + } + + /** + * Returns the resources associated with Subscription. + * @param context Context object + * @param subId Subscription Id of Subscription who's resources are required + * @param useRootLocale if root locale should be used. Localized locale is used if false. + * @return Resources associated with Subscription. + * @hide + */ + public static Resources getResourcesForSubId(Context context, int subId, + boolean useRootLocale) { final SubscriptionInfo subInfo = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); @@ -1821,6 +1835,11 @@ public class SubscriptionManager { newConfig.mnc = subInfo.getMnc(); if (newConfig.mnc == 0) newConfig.mnc = Configuration.MNC_ZERO; } + + if (useRootLocale) { + newConfig.setLocale(Locale.ROOT); + } + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); DisplayMetrics newMetrics = new DisplayMetrics(); newMetrics.setTo(metrics); @@ -1828,6 +1847,19 @@ public class SubscriptionManager { } /** + * Checks if the supplied subscription ID corresponds to an active subscription. + * + * @param subscriptionId the subscription ID. + * @return {@code true} if the supplied subscription ID corresponds to an active subscription; + * {@code false} if it does not correspond to an active subscription; or throw a + * SecurityException if the caller hasn't got the right permission. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public boolean isActiveSubscriptionId(int subscriptionId) { + return isActiveSubId(subscriptionId); + } + + /** * @return true if the sub ID is active. i.e. The sub ID corresponds to a known subscription * and the SIM providing the subscription is present in a slot and in "LOADED" state. * @hide @@ -1837,7 +1869,7 @@ public class SubscriptionManager { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - return iSub.isActiveSubId(subId); + return iSub.isActiveSubId(subId, mContext.getOpPackageName()); } } catch (RemoteException ex) { } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index ebe05e8b27db..f83ea68af1c5 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -16,6 +16,8 @@ package android.telephony; +import static android.content.Context.TELECOM_SERVICE; + import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; @@ -67,6 +69,7 @@ import com.android.internal.telephony.CellNetworkScanResult; import com.android.internal.telephony.IPhoneSubInfo; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.ITelephonyRegistry; +import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; import com.android.internal.telephony.TelephonyProperties; @@ -1576,6 +1579,7 @@ public class TelephonyManager { * * @return List of NeighboringCellInfo or null if info unavailable. * + * @removed * @deprecated Use {@link #getAllCellInfo} which returns a superset of the information * from NeighboringCellInfo, including LTE cell information. */ @@ -2088,10 +2092,37 @@ public class TelephonyManager { /** Max network type number. Update as new types are added. Don't add negative types. {@hide} */ public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_LTE_CA; + + /** @hide */ + @IntDef({ + NETWORK_TYPE_UNKNOWN, + NETWORK_TYPE_GPRS, + NETWORK_TYPE_EDGE, + NETWORK_TYPE_UMTS, + NETWORK_TYPE_CDMA, + NETWORK_TYPE_EVDO_0, + NETWORK_TYPE_EVDO_A, + NETWORK_TYPE_1xRTT, + NETWORK_TYPE_HSDPA, + NETWORK_TYPE_HSUPA, + NETWORK_TYPE_HSPA, + NETWORK_TYPE_IDEN, + NETWORK_TYPE_EVDO_B, + NETWORK_TYPE_LTE, + NETWORK_TYPE_EHRPD, + NETWORK_TYPE_HSPAP, + NETWORK_TYPE_GSM, + NETWORK_TYPE_TD_SCDMA, + NETWORK_TYPE_IWLAN, + NETWORK_TYPE_LTE_CA, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NetworkType{} + /** * @return the NETWORK_TYPE_xxxx for current data connection. */ - public int getNetworkType() { + public @NetworkType int getNetworkType() { try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -2136,24 +2167,24 @@ public class TelephonyManager { * @hide */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - @UnsupportedAppUsage - public int getNetworkType(int subId) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName()); - } else { - // This can happen when the ITelephony interface is not up yet. - return NETWORK_TYPE_UNKNOWN; - } - } catch(RemoteException ex) { - // This shouldn't happen in the normal case - return NETWORK_TYPE_UNKNOWN; - } catch (NullPointerException ex) { - // This could happen before phone restarts due to crashing - return NETWORK_TYPE_UNKNOWN; - } - } + @UnsupportedAppUsage + public int getNetworkType(int subId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getNetworkTypeForSubscriber(subId, getOpPackageName()); + } else { + // This can happen when the ITelephony interface is not up yet. + return NETWORK_TYPE_UNKNOWN; + } + } catch (RemoteException ex) { + // This shouldn't happen in the normal case + return NETWORK_TYPE_UNKNOWN; + } catch (NullPointerException ex) { + // This could happen before phone restarts due to crashing + return NETWORK_TYPE_UNKNOWN; + } + } /** * Returns a constant indicating the radio technology (network type) @@ -2186,7 +2217,7 @@ public class TelephonyManager { */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public int getDataNetworkType() { + public @NetworkType int getDataNetworkType() { return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId())); } @@ -2226,7 +2257,7 @@ public class TelephonyManager { */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public int getVoiceNetworkType() { + public @NetworkType int getVoiceNetworkType() { return getVoiceNetworkType(getSubId()); } @@ -4138,11 +4169,16 @@ public class TelephonyManager { } /** - * Returns the IMS home network domain name that was loaded from the ISIM. - * @return the IMS domain name, or null if not present or not loaded + * Returns the IMS home network domain name that was loaded from the ISIM {@see #APPTYPE_ISIM}. + * @return the IMS domain name. Returns {@code null} if ISIM hasn't been loaded or IMS domain + * hasn't been loaded or isn't present on the ISIM. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE} * @hide */ - @UnsupportedAppUsage + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain() { try { IPhoneSubInfo info = getSubscriberInfo(); @@ -4370,7 +4406,7 @@ public class TelephonyManager { * @hide */ private ITelecomService getTelecomService() { - return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE)); + return ITelecomService.Stub.asInterface(ServiceManager.getService(TELECOM_SERVICE)); } private ITelephonyRegistry getTelephonyRegistry() { @@ -5396,7 +5432,19 @@ public class TelephonyManager { } } - // ICC SIM Application Types + /** + * UICC SIM Application Types + * @hide + */ + @IntDef(prefix = { "APPTYPE_" }, value = { + APPTYPE_SIM, + APPTYPE_USIM, + APPTYPE_RUIM, + APPTYPE_CSIM, + APPTYPE_ISIM + }) + @Retention(RetentionPolicy.SOURCE) + public @interface UiccAppType{} /** UICC application type is SIM */ public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; /** UICC application type is USIM */ @@ -5407,6 +5455,7 @@ public class TelephonyManager { public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM; /** UICC application type is ISIM */ public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM; + // authContext (parameter P2) when doing UICC challenge, // per 3GPP TS 31.102 (Section 7.1.2) /** Authentication type for UICC challenge is EAP SIM. See RFC 4186 for details. */ @@ -5658,23 +5707,6 @@ public class TelephonyManager { } /** - * @return true if the IMS resolver is busy resolving a binding and should not be considered - * available, false if the IMS resolver is idle. - * @hide - */ - public boolean isResolvingImsBinding() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.isResolvingImsBinding(); - } - } catch (RemoteException e) { - Rlog.e(TAG, "isResolvingImsBinding, RemoteException: " + e.getMessage()); - } - return false; - } - - /** * Set IMS registration state * * @param Registration state @@ -5690,6 +5722,203 @@ public class TelephonyManager { } } + /** @hide */ + @IntDef(prefix = { "NETWORK_MODE_" }, value = { + NETWORK_MODE_WCDMA_PREF, + NETWORK_MODE_GSM_ONLY, + NETWORK_MODE_WCDMA_ONLY, + NETWORK_MODE_GSM_UMTS, + NETWORK_MODE_CDMA_EVDO, + NETWORK_MODE_CDMA_NO_EVDO, + NETWORK_MODE_EVDO_NO_CDMA, + NETWORK_MODE_GLOBAL, + NETWORK_MODE_LTE_CDMA_EVDO, + NETWORK_MODE_LTE_GSM_WCDMA, + NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_LTE_ONLY, + NETWORK_MODE_LTE_WCDMA, + NETWORK_MODE_TDSCDMA_ONLY, + NETWORK_MODE_TDSCDMA_WCDMA, + NETWORK_MODE_LTE_TDSCDMA, + NETWORK_MODE_TDSCDMA_GSM, + NETWORK_MODE_LTE_TDSCDMA_GSM, + NETWORK_MODE_TDSCDMA_GSM_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA, + NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA, + NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA + }) + @Retention(RetentionPolicy.SOURCE) + public @interface PrefNetworkMode{} + + /** + * network mode is GSM/WCDMA (WCDMA preferred). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_WCDMA_PREF = RILConstants.NETWORK_MODE_WCDMA_PREF; + + /** + * network mode is GSM only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GSM_ONLY = RILConstants.NETWORK_MODE_GSM_ONLY; + + /** + * network mode is WCDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_WCDMA_ONLY = RILConstants.NETWORK_MODE_WCDMA_ONLY; + + /** + * network mode is GSM/WCDMA (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GSM_UMTS = RILConstants.NETWORK_MODE_GSM_UMTS; + + /** + * network mode is CDMA and EvDo (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_CDMA_EVDO = RILConstants.NETWORK_MODE_CDMA; + + /** + * network mode is CDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_CDMA_NO_EVDO = RILConstants.NETWORK_MODE_CDMA_NO_EVDO; + + /** + * network mode is EvDo only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_EVDO_NO_CDMA = RILConstants.NETWORK_MODE_EVDO_NO_CDMA; + + /** + * network mode is GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL). + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_GLOBAL = RILConstants.NETWORK_MODE_GLOBAL; + + /** + * network mode is LTE, CDMA and EvDo. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_CDMA_EVDO = RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; + + /** + * preferred network mode is LTE, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_GSM_WCDMA = RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; + + /** + * network mode is LTE, CDMA, EvDo, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; + + /** + * network mode is LTE Only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_ONLY = RILConstants.NETWORK_MODE_LTE_ONLY; + + /** + * network mode is LTE/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_WCDMA = RILConstants.NETWORK_MODE_LTE_WCDMA; + + /** + * network mode is TD-SCDMA only. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_ONLY = RILConstants.NETWORK_MODE_TDSCDMA_ONLY; + + /** + * network mode is TD-SCDMA and WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_WCDMA = RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; + + /** + * network mode is TD-SCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA = RILConstants.NETWORK_MODE_LTE_TDSCDMA; + + /** + * network mode is TD-SCDMA and GSM. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_GSM = RILConstants.NETWORK_MODE_TDSCDMA_GSM; + + /** + * network mode is TD-SCDMA,GSM and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_GSM = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; + + /** + * network mode is TD-SCDMA, GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_GSM_WCDMA = + RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; + + /** + * network mode is TD-SCDMA, WCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; + + /** + * network mode is TD-SCDMA, GSM/WCDMA and LTE. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; + + /** + * network mode is TD-SCDMA,EvDo,CDMA,GSM/WCDMA. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + + /** + * network mode is TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo. + * @hide + */ + @SystemApi + public static final int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = + RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + /** * Get the preferred network type. * Used for device configuration by some CDMA operators. @@ -5698,11 +5927,12 @@ public class TelephonyManager { * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling * app has carrier privileges (see {@link #hasCarrierPrivileges}). * - * @return the preferred network type, defined in RILConstants.java. + * @return the preferred network type. * @hide */ - @UnsupportedAppUsage - public int getPreferredNetworkType(int subId) { + @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE)) + @SystemApi + public @PrefNetworkMode int getPreferredNetworkType(int subId) { try { ITelephony telephony = getITelephony(); if (telephony != null) @@ -5833,21 +6063,46 @@ public class TelephonyManager { * @param persistSelection whether the selection will persist until reboot. If true, only allows * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume * normal network selection next time. - * @return true on success; false on any failure. + * @return {@code true} on success; {@code false} on any failure. */ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(String operatorNumeric, boolean persistSelection) { + return setNetworkSelectionModeManual( + new OperatorInfo( + "" /* operatorAlphaLong */, "" /* operatorAlphaShort */, operatorNumeric), + persistSelection); + } + + /** + * Ask the radio to connect to the input network and change selection mode to manual. + * + * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the + * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()} + * + * <p>Requires Permission: + * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling + * app has carrier privileges (see {@link #hasCarrierPrivileges}). + * + * @param operatorInfo included the PLMN id, long name, short name of the operator to attach to. + * @param persistSelection whether the selection will persist until reboot. If true, only allows + * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume + * normal network selection next time. + * @return {@code true} on success; {@code true} on any failure. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public boolean setNetworkSelectionModeManual( + OperatorInfo operatorInfo, boolean persistSelection) { try { ITelephony telephony = getITelephony(); if (telephony != null) { return telephony.setNetworkSelectionModeManual( - getSubId(), operatorNumeric, persistSelection); + getSubId(), operatorInfo, persistSelection); } } catch (RemoteException ex) { Rlog.e(TAG, "setNetworkSelectionModeManual RemoteException", ex); - } catch (NullPointerException ex) { - Rlog.e(TAG, "setNetworkSelectionModeManual NPE", ex); } return false; } @@ -6259,57 +6514,42 @@ public class TelephonyManager { } /** - * @deprecated Use {@link android.telecom.TelecomManager#endCall()} instead. + * @removed Use {@link android.telecom.TelecomManager#endCall()} instead. * @hide + * @removed */ @Deprecated @SystemApi @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.endCall(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#endCall", e); - } return false; } /** - * @deprecated Use {@link android.telecom.TelecomManager#acceptRingingCall} instead + * @removed Use {@link android.telecom.TelecomManager#acceptRingingCall} instead * @hide + * @removed */ @Deprecated @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - telephony.answerRingingCall(); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#answerRingingCall", e); - } + // No-op } /** - * @deprecated Use {@link android.telecom.TelecomManager#silenceRinger} instead + * @removed Use {@link android.telecom.TelecomManager#silenceRinger} instead * @hide */ @Deprecated @SystemApi @SuppressLint("Doclava125") public void silenceRinger() { - try { - getTelecomService().silenceRinger(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelecomService#silenceRinger", e); - } + // No-op } /** - * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead + * @removed Use {@link android.telecom.TelecomManager#isInCall} instead * @hide */ @Deprecated @@ -6319,18 +6559,11 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isOffhook() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isOffhook(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isOffhook", e); - } return false; } /** - * @deprecated Use {@link android.telecom.TelecomManager#isRinging} instead + * @removed Use {@link android.telecom.TelecomManager#isRinging} instead * @hide */ @Deprecated @@ -6340,18 +6573,11 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isRinging() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isRinging(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isRinging", e); - } return false; } /** - * @deprecated Use {@link android.telecom.TelecomManager#isInCall} instead + * @removed Use {@link android.telecom.TelecomManager#isInCall} instead * @hide */ @Deprecated @@ -6361,13 +6587,6 @@ public class TelephonyManager { android.Manifest.permission.READ_PHONE_STATE }) public boolean isIdle() { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.isIdle(getOpPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#isIdle", e); - } return true; } @@ -7853,26 +8072,23 @@ public class TelephonyManager { } /** - * Return the application ID for the app type like {@link APPTYPE_CSIM}. - * - * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission + * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}. + * All uicc applications are uniquely identified by application ID. See ETSI 102.221 and 101.220 + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} * - * @param appType the uicc app type like {@link APPTYPE_CSIM} - * @return Application ID for specificied app type or null if no uicc or error. + * @param appType the uicc app type. + * @return Application ID for specified app type or {@code null} if no uicc or error. * @hide */ - public String getAidForAppType(int appType) { + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public String getAidForAppType(@UiccAppType int appType) { return getAidForAppType(getSubId(), appType); } /** - * Return the application ID for the app type like {@link APPTYPE_CSIM}. - * - * Requires that the calling app has READ_PRIVILEGED_PHONE_STATE permission - * - * @param subId the subscription ID that this request applies to. - * @param appType the uicc app type, like {@link APPTYPE_CSIM} - * @return Application ID for specificied app type or null if no uicc or error. + * same as {@link #getAidForAppType(int)} * @hide */ public String getAidForAppType(int subId, int appType) { diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index f0d3c8956962..5d6a8c158eed 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -118,7 +118,9 @@ public final class ImsCallProfile implements Parcelable { */ public static final String EXTRA_CONFERENCE = "conference"; /** - * @hide + * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an + * emergency call. The {@link ImsService} sets this on a call to indicate that the network has + * identified the call as an emergency call. */ public static final String EXTRA_E_CALL = "e_call"; /** @@ -245,7 +247,8 @@ public final class ImsCallProfile implements Parcelable { * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g. * "14" vs (int) 14). * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection# - * updateWifiStateFromExtras(Bundle)} to determine whether to set the + * updateImsCallRatFromExtras(Bundle)} to determine whether to set the + * {@link android.telecom.TelecomManager#EXTRA_CALL_NETWORK_TYPE} extra value and * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection. */ public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index 31381804d143..cecf2e26f139 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -21,12 +21,11 @@ import android.annotation.SystemApi; import android.net.Uri; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; -import android.telephony.ims.ImsReasonInfo; - import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; @@ -81,13 +80,14 @@ public class ImsRegistrationImplBase { * Callback class for receiving Registration callback events. * @hide */ - public static class Callback { + public static class Callback extends IImsRegistrationCallback.Stub { /** * Notifies the framework when the IMS Provider is connected to the IMS network. * * @param imsRadioTech the radio access technology. Valid values are defined in * {@link ImsRegistrationTech}. */ + @Override public void onRegistered(@ImsRegistrationTech int imsRadioTech) { } @@ -97,6 +97,7 @@ public class ImsRegistrationImplBase { * @param imsRadioTech the radio access technology. Valid values are defined in * {@link ImsRegistrationTech}. */ + @Override public void onRegistering(@ImsRegistrationTech int imsRadioTech) { } @@ -105,6 +106,7 @@ public class ImsRegistrationImplBase { * * @param info the {@link ImsReasonInfo} associated with why registration was disconnected. */ + @Override public void onDeregistered(ImsReasonInfo info) { } @@ -115,6 +117,7 @@ public class ImsRegistrationImplBase { * @param imsRadioTech The {@link ImsRegistrationTech} type that has failed * @param info A {@link ImsReasonInfo} that identifies the reason for failure. */ + @Override public void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech, ImsReasonInfo info) { } @@ -125,6 +128,7 @@ public class ImsRegistrationImplBase { * @param uris new array of subscriber {@link Uri}s that are associated with this IMS * subscription. */ + @Override public void onSubscriberAssociatedUriChanged(Uri[] uris) { } diff --git a/telephony/java/android/telephony/mbms/GroupCall.java b/telephony/java/android/telephony/mbms/GroupCall.java new file mode 100644 index 000000000000..9aca18e07812 --- /dev/null +++ b/telephony/java/android/telephony/mbms/GroupCall.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms; + +import android.annotation.IntDef; +import android.os.RemoteException; +import android.telephony.MbmsGroupCallSession; +import android.telephony.mbms.vendor.IMbmsGroupCallService; +import android.util.Log; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Class used to represent a single MBMS group call. After a call has been started with + * {@link MbmsGroupCallSession#startGroupCall}, + * this class is used to hold information about the call and control it. + */ +public class GroupCall implements AutoCloseable { + private static final String LOG_TAG = "MbmsGroupCall"; + + /** + * The state of a group call, reported via + * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED}) + public @interface GroupCallState {} + public static final int STATE_STOPPED = 1; + public static final int STATE_STARTED = 2; + public static final int STATE_STALLED = 3; + + /** + * The reason for a call state change, reported via + * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "REASON_" }, + value = {REASON_BY_USER_REQUEST, REASON_FREQUENCY_CONFLICT, + REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE, + REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE}) + public @interface GroupCallStateChangeReason {} + + /** + * Indicates that the middleware does not have a reason to provide for the state change. + */ + public static final int REASON_NONE = 0; + + /** + * State changed due to a call to {@link #close()} or + * {@link MbmsGroupCallSession#startGroupCall} + */ + public static final int REASON_BY_USER_REQUEST = 1; + + // 2 is unused to match up with streaming. + + /** + * State changed due to a frequency conflict with another requested call. + */ + public static final int REASON_FREQUENCY_CONFLICT = 3; + + /** + * State changed due to the middleware running out of memory + */ + public static final int REASON_OUT_OF_MEMORY = 4; + + /** + * State changed due to the device leaving the home carrier's LTE network. + */ + public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; + + /** + * State changed due to the device leaving the area where this call is being broadcast. + */ + public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; + + private final int mSubscriptionId; + private final long mTmgi; + private final MbmsGroupCallSession mParentSession; + private final InternalGroupCallCallback mCallback; + private IMbmsGroupCallService mService; + + /** + * @hide + */ + public GroupCall(int subscriptionId, + IMbmsGroupCallService service, + MbmsGroupCallSession session, + long tmgi, + InternalGroupCallCallback callback) { + mSubscriptionId = subscriptionId; + mParentSession = session; + mService = service; + mTmgi = tmgi; + mCallback = callback; + } + + /** + * Retrieve the TMGI (Temporary Mobile Group Identity) corresponding to this call. + */ + public long getTmgi() { + return mTmgi; + } + + /** + * Send an update to the middleware when the SAI (Service Area Identifier) list and frequency + * information of the group call has * changed. Callers must obtain this information from the + * wireless carrier independently. + * @param saiArray New array of SAIs that the call is available on. + * @param frequencyArray New array of frequencies that the call is available on. + */ + public void updateGroupCall(int[] saiArray, int[] frequencyArray) { + if (mService == null) { + throw new IllegalStateException("No group call service attached"); + } + + try { + mService.updateGroupCall(mSubscriptionId, mTmgi, saiArray, frequencyArray); + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService = null; + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + } finally { + mParentSession.onGroupCallStopped(this); + } + } + + /** + * Stop this group call. Further operations on this object will fail with an + * {@link IllegalStateException}. + * + * May throw an {@link IllegalStateException} + */ + @Override + public void close() { + if (mService == null) { + throw new IllegalStateException("No group call service attached"); + } + + try { + mService.stopGroupCall(mSubscriptionId, mTmgi); + } catch (RemoteException e) { + Log.w(LOG_TAG, "Remote process died"); + mService = null; + sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); + } finally { + mParentSession.onGroupCallStopped(this); + } + } + + /** @hide */ + public InternalGroupCallCallback getCallback() { + return mCallback; + } + + private void sendErrorToApp(int errorCode, String message) { + mCallback.onError(errorCode, message); + } +} + diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java new file mode 100644 index 000000000000..001bb02aad94 --- /dev/null +++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms; + +import android.annotation.IntDef; +import android.annotation.Nullable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A callback class for use when the application is in a group call. The middleware + * will provide updates on the status of the call via this callback. + */ +public class GroupCallCallback { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE, + MbmsErrors.ERROR_MIDDLEWARE_LOST, + MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY, + MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE, + MbmsErrors.GeneralErrors.ERROR_IN_E911, + MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE, + MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM, + MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" }) + private @interface GroupCallError{} + + /** + * Indicates broadcast signal strength is not available for this call. + * + * This may be due to the call no longer being available due to geography + * or timing (end of service) + */ + public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; + + /** + * Called by the middleware when it has detected an error condition in this group call. The + * possible error codes are listed in {@link MbmsErrors}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ + public void onError(@GroupCallError int errorCode, @Nullable String message) { + // default implementation empty + } + + /** + * Called to indicate this call has changed state. + * + * See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED} + * and {@link GroupCall#STATE_STALLED}. + */ + public void onGroupCallStateChanged(@GroupCall.GroupCallState int state, + @GroupCall.GroupCallStateChangeReason int reason) { + // default implementation empty + } + + /** + * Broadcast Signal Strength updated. + * + * This signal strength is the BROADCAST signal strength which, + * depending on technology in play and it's deployment, may be + * stronger or weaker than the traditional UNICAST signal + * strength. It a simple int from 0-4 for valid levels or + * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available + * for this call due to timing, geography or popularity. + */ + public void onBroadcastSignalStrengthUpdated(int signalStrength) { + // default implementation empty + } +} diff --git a/core/res/res/values-mcc262-mnc02/strings.xml b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl index 2b8940195ee3..844b6344a34c 100644..100755 --- a/core/res/res/values-mcc262-mnc02/strings.xml +++ b/telephony/java/android/telephony/mbms/IGroupCallCallback.aidl @@ -1,13 +1,11 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright (c) 2017, Google Inc. +/* + * 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 + * 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, @@ -15,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ ---> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> +package android.telephony.mbms; - <!-- Do not translate. Template for showing mobile network operator name while WFC is active --> - <string-array name="wfcSpnFormats"> - <item>%s</item> - <item>%s Wi-Fi Calling</item> - </string-array> -</resources> +/** + * @hide + */ +oneway interface IGroupCallCallback { + void onError(int errorCode, String message); + void onGroupCallStateChanged(int state, int reason); + void onBroadcastSignalStrengthUpdated(int signalStrength); +} diff --git a/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl new file mode 100755 index 000000000000..1a1c7f8af5df --- /dev/null +++ b/telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl @@ -0,0 +1,33 @@ +/* +** Copyright 2018, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony.mbms; + +import java.util.List; + +/** + * @hide + */ +oneway interface IMbmsGroupCallSessionCallback +{ + void onError(int errorCode, String message); + + void onAvailableSaisUpdated(in List currentSai, in List availableSais); + + void onServiceInterfaceAvailable(String interfaceName, int index); + + void onMiddlewareReady(); +} diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java new file mode 100644 index 000000000000..2910bb313d84 --- /dev/null +++ b/telephony/java/android/telephony/mbms/InternalGroupCallCallback.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms; + +import android.os.Binder; + +import java.util.concurrent.Executor; + +/** @hide */ +public class InternalGroupCallCallback extends IGroupCallCallback.Stub { + private final GroupCallCallback mAppCallback; + private final Executor mExecutor; + private volatile boolean mIsStopped = false; + + public InternalGroupCallCallback(GroupCallCallback appCallback, + Executor executor) { + mAppCallback = appCallback; + mExecutor = executor; + } + + @Override + public void onError(final int errorCode, final String message) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onError(errorCode, message); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onGroupCallStateChanged(final int state, final int reason) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onGroupCallStateChanged(state, reason); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onBroadcastSignalStrengthUpdated(final int signalStrength) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onBroadcastSignalStrengthUpdated(signalStrength); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + /** Prevents this callback from calling the app */ + public void stop() { + mIsStopped = true; + } +} diff --git a/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java new file mode 100644 index 000000000000..4c9cf4dd7c92 --- /dev/null +++ b/telephony/java/android/telephony/mbms/InternalGroupCallSessionCallback.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms; + +import android.os.Binder; + +import java.util.List; +import java.util.concurrent.Executor; + +/** @hide */ +public class InternalGroupCallSessionCallback extends IMbmsGroupCallSessionCallback.Stub { + private final Executor mExecutor; + private final MbmsGroupCallSessionCallback mAppCallback; + private volatile boolean mIsStopped = false; + + public InternalGroupCallSessionCallback(MbmsGroupCallSessionCallback appCallback, + Executor executor) { + mAppCallback = appCallback; + mExecutor = executor; + } + + @Override + public void onError(final int errorCode, final String message) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onError(errorCode, message); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onAvailableSaisUpdated(final List currentSais, final List availableSais) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onAvailableSaisUpdated(currentSais, availableSais); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onServiceInterfaceAvailable(final String interfaceName, final int index) { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onServiceInterfaceAvailable(interfaceName, index); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + @Override + public void onMiddlewareReady() { + if (mIsStopped) { + return; + } + + mExecutor.execute(new Runnable() { + @Override + public void run() { + long token = Binder.clearCallingIdentity(); + try { + mAppCallback.onMiddlewareReady(); + } finally { + Binder.restoreCallingIdentity(token); + } + } + }); + } + + /** Prevents this callback from calling the app */ + public void stop() { + mIsStopped = true; + } +} diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java new file mode 100644 index 000000000000..7da734ee5837 --- /dev/null +++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms; + +import android.annotation.IntDef; +import android.annotation.Nullable; +import android.content.Context; +import android.telephony.MbmsGroupCallSession; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * A callback class that is used to receive information from the middleware on MBMS group-call + * services. An instance of this object should be passed into + * {@link MbmsGroupCallSession#create(Context, Executor, int, MbmsGroupCallSessionCallback)}. + */ +public class MbmsGroupCallSessionCallback { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE, + MbmsErrors.ERROR_MIDDLEWARE_LOST, + MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND, + MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED, + MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, + MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY, + MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY, + MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE, + MbmsErrors.GeneralErrors.ERROR_IN_E911, + MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE, + MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM, + MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" }) + private @interface GroupCallError{} + + /** + * Called by the middleware when it has detected an error condition. The possible error codes + * are listed in {@link MbmsErrors}. + * @param errorCode The error code. + * @param message A human-readable message generated by the middleware for debugging purposes. + */ + public void onError(@GroupCallError int errorCode, @Nullable String message) { + } + + /** + * Indicates that the list of currently available SAIs has been updated. The app may use this + * information to filter the list of group calls when displaying available group calls to + * the user by matching the SAIs with a list of group calls separately negotiated with the + * carrier. The app may also report the aggregate list of SAIs to the group call application + * server so that a network entity can determine when, and where to activate the broadcast of + * particular group calls. + * @param currentSais The available SAIs on the current cell. + * @param availableSais A list of lists of available SAIS in neighboring cells, where each list + * contains the available SAIs in an individual cell. + */ + public void onAvailableSaisUpdated(List<Integer> currentSais, + List<List<Integer>> availableSais) { + } + + /** + * Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied + * via this callback may be used to establish a data-link interface with the modem before the + * middleware is ready. + * Note that this method may be called before {@link #onMiddlewareReady()}. + * + * @param interfaceName The interface name for the data link. + * @param index The index for the data link. + */ + public void onServiceInterfaceAvailable(String interfaceName, int index) { + } + + /** + * Called to indicate that the middleware has been initialized and is ready. + * + * Before this method is called, calling any method on an instance of + * {@link MbmsGroupCallSession} will result in an {@link IllegalStateException} or an error + * delivered via {@link #onError(int, String)} with error code + * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}. + */ + public void onMiddlewareReady() { + } +} diff --git a/telephony/java/android/telephony/mbms/MbmsUtils.java b/telephony/java/android/telephony/mbms/MbmsUtils.java index 06b2120b59c1..95b4d37e5840 100644 --- a/telephony/java/android/telephony/mbms/MbmsUtils.java +++ b/telephony/java/android/telephony/mbms/MbmsUtils.java @@ -23,6 +23,7 @@ import android.content.ServiceConnection; import android.content.pm.*; import android.content.pm.ServiceInfo; import android.telephony.MbmsDownloadSession; +import android.telephony.MbmsGroupCallSession; import android.telephony.MbmsStreamingSession; import android.util.Log; @@ -59,6 +60,9 @@ public class MbmsUtils { case MbmsStreamingSession.MBMS_STREAMING_SERVICE_ACTION: metaDataKey = MbmsStreamingSession.MBMS_STREAMING_SERVICE_OVERRIDE_METADATA; break; + case MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_ACTION: + metaDataKey = MbmsGroupCallSession.MBMS_GROUP_CALL_SERVICE_OVERRIDE_METADATA; + break; } if (metaDataKey == null) { return null; diff --git a/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl new file mode 100755 index 000000000000..721256a95396 --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/IMbmsGroupCallService.aidl @@ -0,0 +1,39 @@ +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.telephony.mbms.vendor; + +import android.net.Uri; +import android.telephony.mbms.IMbmsGroupCallSessionCallback; +import android.telephony.mbms.IGroupCallCallback; + +/** + * @hide + */ +interface IMbmsGroupCallService +{ + int initialize(IMbmsGroupCallSessionCallback callback, int subId); + + void stopGroupCall(int subId, long tmgi); + + void updateGroupCall(int subscriptionId, long tmgi, in int[] saiArray, + in int[] frequencyArray); + + int startGroupCall(int subscriptionId, long tmgi, in int[] saiArray, + in int[] frequencyArray, IGroupCallCallback callback); + + void dispose(int subId); +} diff --git a/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java new file mode 100644 index 000000000000..3734ca7d6fc9 --- /dev/null +++ b/telephony/java/android/telephony/mbms/vendor/MbmsGroupCallServiceBase.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony.mbms.vendor; + +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.app.Service; +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; +import android.telephony.mbms.GroupCallCallback; +import android.telephony.mbms.IGroupCallCallback; +import android.telephony.mbms.IMbmsGroupCallSessionCallback; +import android.telephony.mbms.MbmsErrors; +import android.telephony.mbms.MbmsGroupCallSessionCallback; +import android.telephony.mbms.vendor.IMbmsGroupCallService.Stub; + +import java.util.List; + +/** + * Base class for MBMS group-call services. The middleware should override this class to implement + * its {@link Service} for group calls + * Subclasses should call this class's {@link #onBind} method to obtain an {@link IBinder} if they + * override {@link #onBind}. + * @hide + */ +@SystemApi +@TestApi +public class MbmsGroupCallServiceBase extends Service { + private final IBinder mInterface = new Stub() { + @Override + public int initialize(final IMbmsGroupCallSessionCallback callback, + final int subscriptionId) throws RemoteException { + if (callback == null) { + throw new NullPointerException("Callback must not be null"); + } + + final int uid = Binder.getCallingUid(); + + int result = MbmsGroupCallServiceBase.this.initialize( + new MbmsGroupCallSessionCallback() { + @Override + public void onError(final int errorCode, final String message) { + try { + if (errorCode == MbmsErrors.UNKNOWN) { + throw new IllegalArgumentException( + "Middleware cannot send an unknown error."); + } + callback.onError(errorCode, message); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onAvailableSaisUpdated(final List currentSais, + final List availableSais) { + try { + callback.onAvailableSaisUpdated(currentSais, availableSais); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onServiceInterfaceAvailable(final String interfaceName, + final int index) { + try { + callback.onServiceInterfaceAvailable(interfaceName, index); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + @Override + public void onMiddlewareReady() { + try { + callback.onMiddlewareReady(); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + }, subscriptionId); + + if (result == MbmsErrors.SUCCESS) { + callback.asBinder().linkToDeath(new DeathRecipient() { + @Override + public void binderDied() { + onAppCallbackDied(uid, subscriptionId); + } + }, 0); + } + + return result; + } + + @Override + public void stopGroupCall(int subId, long tmgi) { + MbmsGroupCallServiceBase.this.stopGroupCall(subId, tmgi); + } + + @Override + public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray, + int[] frequencyArray) { + MbmsGroupCallServiceBase.this.updateGroupCall( + subscriptionId, tmgi, saiArray, frequencyArray); + } + + @Override + public int startGroupCall(final int subscriptionId, final long tmgi, final int[] saiArray, + final int[] frequencyArray, final IGroupCallCallback callback) + throws RemoteException { + if (callback == null) { + throw new NullPointerException("Callback must not be null"); + } + + final int uid = Binder.getCallingUid(); + + int result = MbmsGroupCallServiceBase.this.startGroupCall( + subscriptionId, tmgi, saiArray, frequencyArray, new GroupCallCallback() { + @Override + public void onError(final int errorCode, final String message) { + try { + if (errorCode == MbmsErrors.UNKNOWN) { + throw new IllegalArgumentException( + "Middleware cannot send an unknown error."); + } + callback.onError(errorCode, message); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + public void onGroupCallStateChanged(int state, int reason) { + try { + callback.onGroupCallStateChanged(state, reason); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + + public void onBroadcastSignalStrengthUpdated(int signalStrength) { + try { + callback.onBroadcastSignalStrengthUpdated(signalStrength); + } catch (RemoteException e) { + onAppCallbackDied(uid, subscriptionId); + } + } + }); + + if (result == MbmsErrors.SUCCESS) { + callback.asBinder().linkToDeath(new DeathRecipient() { + @Override + public void binderDied() { + onAppCallbackDied(uid, subscriptionId); + } + }, 0); + } + + return result; + } + + @Override + public void dispose(int subId) throws RemoteException { + MbmsGroupCallServiceBase.this.dispose(subId); + } + }; + + /** + * Initialize the group call service for this app and subscription ID, registering the callback. + * + * May throw an {@link IllegalArgumentException} or a {@link SecurityException}, which + * will be intercepted and passed to the app as + * {@link MbmsErrors.InitializationErrors#ERROR_UNABLE_TO_INITIALIZE} + * + * May return any value from {@link MbmsErrors.InitializationErrors} + * or {@link MbmsErrors#SUCCESS}. Non-successful error codes will be passed to the app via + * {@link IMbmsGroupCallSessionCallback#onError(int, String)}. + * + * @param callback The callback to use to communicate with the app. + * @param subscriptionId The subscription ID to use. + */ + public int initialize(MbmsGroupCallSessionCallback callback, int subscriptionId) + throws RemoteException { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Starts a particular group call. This method may perform asynchronous work. When + * the call is ready for consumption, the middleware should inform the app via + * {@link IGroupCallCallback#onGroupCallStateChanged(int, int)}. + * + * May throw an {@link IllegalArgumentException} or an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + * @param tmgi The TMGI, an identifier for the group call. + * @param saiArray An array of SAIs for the group call. + * @param frequencyArray An array of frequencies for the group call. + * @param callback The callback object on which the app wishes to receive updates. + * @return Any error in {@link MbmsErrors.GeneralErrors} + */ + public int startGroupCall(int subscriptionId, long tmgi, int[] saiArray, int[] frequencyArray, + GroupCallCallback callback) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Stop the group call identified by {@code tmgi}. + * + * The callback provided via {@link #startGroupCall} should no longer be + * used after this method has called by the app. + * + * May throw an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + * @param tmgi The TMGI for the call to stop. + */ + public void stopGroupCall(int subscriptionId, long tmgi) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Called when the app receives new SAI and frequency information for the group call identified + * by {@code tmgi}. + * @param saiArray New array of SAIs that the call is available on. + * @param frequencyArray New array of frequencies that the call is available on. + */ + public void updateGroupCall(int subscriptionId, long tmgi, int[] saiArray, + int[] frequencyArray) { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Signals that the app wishes to dispose of the session identified by the + * {@code subscriptionId} argument and the caller's uid. No notification back to the + * app is required for this operation, and the corresponding callback provided via + * {@link #initialize} should no longer be used + * after this method has been called by the app. + * + * May throw an {@link IllegalStateException} + * + * @param subscriptionId The subscription id to use. + */ + public void dispose(int subscriptionId) throws RemoteException { + throw new UnsupportedOperationException("Not implemented"); + } + + /** + * Indicates that the app identified by the given UID and subscription ID has died. + * @param uid the UID of the app, as returned by {@link Binder#getCallingUid()}. + * @param subscriptionId The subscription ID the app is using. + */ + public void onAppCallbackDied(int uid, int subscriptionId) { + } + + @Override + public IBinder onBind(Intent intent) { + return mInterface; + } +} diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 6521f0b41cb2..0ccd748c31df 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -232,5 +232,5 @@ interface ISub { */ int getSimStateForSlotIndex(int slotIndex); - boolean isActiveSubId(int subId); + boolean isActiveSubId(int subId, String callingPackage); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 066db1fca140..627dfaa5d36e 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -75,116 +75,6 @@ interface ITelephony { void call(String callingPackage, String number); /** - * End call if there is a call in progress, otherwise does nothing. - * - * @return whether it hung up - */ - boolean endCall(); - - /** - * End call on particular subId or go to the Home screen - * @param subId user preferred subId. - * @return whether it hung up - */ - boolean endCallForSubscriber(int subId); - - /** - * Answer the currently-ringing call. - * - * If there's already a current active call, that call will be - * automatically put on hold. If both lines are currently in use, the - * current active call will be ended. - * - * TODO: provide a flag to let the caller specify what policy to use - * if both lines are in use. (The current behavior is hardwired to - * "answer incoming, end ongoing", which is how the CALL button - * is specced to behave.) - * - * TODO: this should be a oneway call (especially since it's called - * directly from the key queue thread). - */ - void answerRingingCall(); - - /** - * Answer the currently-ringing call on particular subId . - * - * If there's already a current active call, that call will be - * automatically put on hold. If both lines are currently in use, the - * current active call will be ended. - * - * TODO: provide a flag to let the caller specify what policy to use - * if both lines are in use. (The current behavior is hardwired to - * "answer incoming, end ongoing", which is how the CALL button - * is specced to behave.) - * - * TODO: this should be a oneway call (especially since it's called - * directly from the key queue thread). - */ - void answerRingingCallForSubscriber(int subId); - - /** - * Silence the ringer if an incoming call is currently ringing. - * (If vibrating, stop the vibrator also.) - * - * It's safe to call this if the ringer has already been silenced, or - * even if there's no incoming call. (If so, this method will do nothing.) - * - * TODO: this should be a oneway call too (see above). - * (Actually *all* the methods here that return void can - * probably be oneway.) - */ - void silenceRinger(); - - /** - * Check if we are in either an active or holding call - * @param callingPackage the name of the package making the call. - * @return true if the phone state is OFFHOOK. - */ - boolean isOffhook(String callingPackage); - - /** - * Check if a particular subId has an active or holding call - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is OFFHOOK. - */ - boolean isOffhookForSubscriber(int subId, String callingPackage); - - /** - * Check if an incoming phone call is ringing or call waiting - * on a particular subId. - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is RINGING. - */ - boolean isRingingForSubscriber(int subId, String callingPackage); - - /** - * Check if an incoming phone call is ringing or call waiting. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is RINGING. - */ - boolean isRinging(String callingPackage); - - /** - * Check if the phone is idle. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is IDLE. - */ - boolean isIdle(String callingPackage); - - /** - * Check if the phone is idle on a particular subId. - * - * @param subId user preferred subId. - * @param callingPackage the name of the package making the call. - * @return true if the phone state is IDLE. - */ - boolean isIdleForSubscriber(int subId, String callingPackage); - - /** * Check to see if the radio is on or not. * @param callingPackage the name of the package making the call. * @return returns true if the radio is on. @@ -817,12 +707,6 @@ interface ITelephony { IImsConfig getImsConfig(int slotId, int feature); /** - * @return true if the IMS resolver is busy resolving a binding and should not be considered - * available, false if the IMS resolver is idle. - */ - boolean isResolvingImsBinding(); - - /** * @return true if the ImsService to bind to for the slot id specified was set, false otherwise. */ boolean setImsService(int slotId, boolean isCarrierImsService, String packageName); @@ -871,14 +755,15 @@ interface ITelephony { * Ask the radio to connect to the input network and change selection mode to manual. * * @param subId the id of the subscription. - * @param operatorNumeric the PLMN of the operator to attach to. - * @param persistSelection Whether the selection will persist until reboot. If true, only allows + * @param operatorInfo the operator inforamtion, included the PLMN, long name and short name of + * the operator to attach to. + * @param persistSelection whether the selection will persist until reboot. If true, only allows * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume * normal network selection next time. - * @return true if the request suceeded. + * @return {@code true} on success; {@code true} on any failure. */ - boolean setNetworkSelectionModeManual(int subId, in String operatorNumeric, - boolean persistSelection); + boolean setNetworkSelectionModeManual( + int subId, in OperatorInfo operatorInfo, boolean persisSelection); /** * Set the preferred network type. diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java index d0245a0a07b4..a47e2b026021 100644 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java @@ -21,7 +21,7 @@ import android.os.Parcel; import android.os.Parcelable; /** - * {@hide} + * @hide */ public class OperatorInfo implements Parcelable { public enum State { diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index f9de776f9a7b..21f3b92c6c4f 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -176,6 +176,10 @@ public class PhoneConstants { // FIXME: This is used to pass a subId via intents, we need to look at its usage, which is // FIXME: extensive, and see if this should be an array of all active subId's or ...? + /** + * @Deprecated use {@link android.telephony.SubscriptionManager#EXTRA_SUBSCRIPTION_INDEX} + * instead. + */ public static final String SUBSCRIPTION_KEY = "subscription"; public static final String SUB_SETTING = "subSettings"; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java index 6bf22a05beec..8015b07fa024 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java @@ -33,6 +33,7 @@ import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.SmsConstants; import java.io.UnsupportedEncodingException; +import java.util.Locale; /** * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is @@ -44,16 +45,34 @@ public class GsmSmsCbMessage { * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5. */ private static final String[] LANGUAGE_CODES_GROUP_0 = { - "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu", - "pl", null + Locale.GERMAN.getLanguage(), // German + Locale.ENGLISH.getLanguage(), // English + Locale.ITALIAN.getLanguage(), // Italian + Locale.FRENCH.getLanguage(), // French + new Locale("es").getLanguage(), // Spanish + new Locale("nl").getLanguage(), // Dutch + new Locale("sv").getLanguage(), // Swedish + new Locale("da").getLanguage(), // Danish + new Locale("pt").getLanguage(), // Portuguese + new Locale("fi").getLanguage(), // Finnish + new Locale("nb").getLanguage(), // Norwegian + new Locale("el").getLanguage(), // Greek + new Locale("tr").getLanguage(), // Turkish + new Locale("hu").getLanguage(), // Hungarian + new Locale("pl").getLanguage(), // Polish + null }; /** * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5. */ private static final String[] LANGUAGE_CODES_GROUP_2 = { - "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null, - null, null + new Locale("cs").getLanguage(), // Czech + new Locale("he").getLanguage(), // Hebrew + new Locale("ar").getLanguage(), // Arabic + new Locale("ru").getLanguage(), // Russian + new Locale("is").getLanguage(), // Icelandic + null, null, null, null, null, null, null, null, null, null, null }; private static final char CARRIAGE_RETURN = 0x0d; diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java index 0fabc2ff6b86..541ca8d1e5c0 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java @@ -118,71 +118,103 @@ public class SmsCbConstants { public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE = 0x111E; // 4382 - /** CMAS Message Identifier for Presidential Level alerts for additional languages - * for additional languages. */ + /** + * CMAS Message Identifier for Presidential Level alerts for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE = 0x111F; // 4383 - /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed - * for additional languages. */ + /** + * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE = 0x1120; // 4384 - /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely - * for additional languages. */ + /** + * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE = 0x1121; // 4385 - /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed - * for additional languages. */ + /** + * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE = 0x1122; // 4386 - /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely - * for additional languages. */ + /** + * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE = 0x1123; // 4387 - /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed - * for additional languages. */ + /** + * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE = 0x1124; // 4388 - /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely - * for additional languages.*/ + /** + * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE = 0x1125; // 4389 - /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed - * for additional languages. */ + /** + * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE = 0x1126; // 4390 - /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely - * for additional languages.*/ + /** + * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE = 0x1127; // 4391 - /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert) - * for additional languages. */ + /** + * CMAS Message Identifier for Child Abduction Emergency (Amber Alert) + * for additional languages. + */ public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE = 0x1128; // 4392 - /** CMAS Message Identifier for the Required Monthly Test - * for additional languages. */ + /** CMAS Message Identifier for the Required Monthly Test for additional languages. */ public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE = 0x1129; // 4393 - /** CMAS Message Identifier for CMAS Exercise - * for additional languages. */ + /** CMAS Message Identifier for CMAS Exercise for additional languages. */ public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE = 0x112A; // 4394 - /** CMAS Message Identifier for operator defined use - * for additional languages. */ + /** CMAS Message Identifier for operator defined use for additional languages. */ public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE = 0x112B; // 4395 + /** CMAS Message Identifier for CMAS Public Safety Alerts. */ + public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY + = 0x112C; // 4396 + + /** CMAS Message Identifier for CMAS Public Safety Alerts for additional languages. */ + public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY_LANGUAGE + = 0x112D; // 4397 + + /** CMAS Message Identifier for CMAS State/Local Test. */ + public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST + = 0x112E; // 4398 + + /** CMAS Message Identifier for CMAS State/Local Test for additional languages. */ + public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE + = 0x112F; // 4399 + /** End of CMAS Message Identifier range (including future extensions). */ public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = 0x112F; // 4399 diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java index 4790b75d9630..6b3df94063bf 100644 --- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java +++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java @@ -93,11 +93,23 @@ public class IccUtils { * converted. If the array size is more than needed, the rest of array remains unchanged. */ public static void bcdToBytes(String bcd, byte[] bytes) { + bcdToBytes(bcd, bytes, 0); + } + + /** + * Converts BCD string to bytes and put it into the given byte array. + * + * @param bcd This should have an even length. If not, an "0" will be appended to the string. + * @param bytes If the array size is less than needed, the rest of the BCD string isn't be + * converted. If the array size is more than needed, the rest of array remains unchanged. + * @param offset the offset into the bytes[] to fill the data + */ + public static void bcdToBytes(String bcd, byte[] bytes, int offset) { if (bcd.length() % 2 != 0) { bcd += "0"; } - int size = Math.min(bytes.length * 2, bcd.length()); - for (int i = 0, j = 0; i + 1 < size; i += 2, j++) { + int size = Math.min((bytes.length - offset) * 2, bcd.length()); + for (int i = 0, j = offset; i + 1 < size; i += 2, j++) { bytes[j] = (byte) (charToByte(bcd.charAt(i + 1)) << 4 | charToByte(bcd.charAt(i))); } } @@ -125,6 +137,20 @@ public class IccUtils { } /** + * Convert a 5 or 6 - digit PLMN string to a nibble-swizzled encoding as per 24.008 10.5.1.3 + * + * @param plmn the PLMN to convert + * @param data a byte array for the output + * @param offset the offset into data to start writing + */ + public static void stringToBcdPlmn(final String plmn, byte[] data, int offset) { + char digit6 = (plmn.length() > 5) ? plmn.charAt(5) : 'F'; + data[offset] = (byte) (charToByte(plmn.charAt(1)) << 4 | charToByte(plmn.charAt(0))); + data[offset + 1] = (byte) (charToByte(digit6) << 4 | charToByte(plmn.charAt(2))); + data[offset + 2] = (byte) (charToByte(plmn.charAt(4)) << 4 | charToByte(plmn.charAt(3))); + } + + /** * Some fields (like ICC ID) in GSM SIMs are stored as nibble-swizzled BCH */ public static String @@ -844,7 +870,7 @@ public class IccUtils { } /** - * Converts a character of [0-9a-aA-F] to its hex value in a byte. If the character is not a + * Converts a character of [0-9a-fA-F] to its hex value in a byte. If the character is not a * hex number, 0 will be returned. */ private static byte charToByte(char c) { diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index 6ce66f0f4546..639ed7d55384 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -245,8 +245,14 @@ public class AppLaunch extends InstrumentationTestCase { mIterationCycle = false; // In the "applaunch.txt" file, trail launches is referenced using // "TRIAL_LAUNCH" - String appPkgName = mNameToIntent.get(launch.getApp()) - .getComponent().getPackageName(); + Intent startIntent = mNameToIntent.get(launch.getApp()); + if (startIntent == null) { + Log.w(TAG, "App does not exist: " + launch.getApp()); + mResult.putString(mNameToResultKey.get(launch.getApp()), + "App does not exist"); + continue; + } + String appPkgName = startIntent.getComponent().getPackageName(); if (SPEED_PROFILE_FILTER.equals(launch.getCompilerFilter())) { assertTrue(String.format("Not able to compile the app : %s", appPkgName), compileApp(VERIFY_FILTER, appPkgName)); diff --git a/tests/DexLoggerIntegrationTests/AndroidManifest.xml b/tests/DexLoggerIntegrationTests/AndroidManifest.xml index a847e8f3b921..a9f01edbdc41 100644 --- a/tests/DexLoggerIntegrationTests/AndroidManifest.xml +++ b/tests/DexLoggerIntegrationTests/AndroidManifest.xml @@ -17,10 +17,10 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.frameworks.dexloggertest"> - <!-- Tests feature introduced in P (27) --> + <!-- Tests feature introduced in P (28) --> <uses-sdk - android:minSdkVersion="27" - android:targetSdkVersion="27" /> + android:minSdkVersion="28" + android:targetSdkVersion="28" /> <uses-permission android:name="android.permission.READ_LOGS" /> diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk index fe65eccedd24..c225e170c377 100644 --- a/tests/NetworkSecurityConfigTest/Android.mk +++ b/tests/NetworkSecurityConfigTest/Android.mk @@ -7,7 +7,6 @@ LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := \ android.test.runner \ - bouncycastle \ conscrypt \ android.test.base \ diff --git a/tests/net/Android.mk b/tests/net/Android.mk index e529b933bb80..750e2fb6f6b4 100644 --- a/tests/net/Android.mk +++ b/tests/net/Android.mk @@ -38,6 +38,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \ libbacktrace \ libbase \ libbinder \ + libbinderthreadstate \ libc++ \ libcrypto \ libcutils \ diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml index ba1a2ead8beb..6dae3f11b371 100644 --- a/tests/net/AndroidManifest.xml +++ b/tests/net/AndroidManifest.xml @@ -44,6 +44,7 @@ <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" /> <uses-permission android:name="android.permission.INSTALL_PACKAGES" /> + <uses-permission android:name="android.permission.NETWORK_STACK" /> <application> <uses-library android:name="android.test.runner" /> diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java index 312b3d1878d6..a592809618e6 100644 --- a/tests/net/java/android/net/dhcp/DhcpPacketTest.java +++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.annotation.Nullable; import android.net.DhcpResults; import android.net.LinkAddress; import android.net.NetworkUtils; @@ -37,6 +38,7 @@ import com.android.internal.util.HexDump; import java.io.ByteArrayOutputStream; import java.net.Inet4Address; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -56,6 +58,8 @@ public class DhcpPacketTest { private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH); private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress( SERVER_ADDR, PREFIX_LENGTH); + private static final String HOSTNAME = "testhostname"; + private static final short MTU = 1500; // Use our own empty address instead of Inet4Address.ANY or INADDR_ANY to ensure that the code // doesn't use == instead of equals when comparing addresses. private static final Inet4Address ANY = (Inet4Address) v4Address("0.0.0.0"); @@ -960,7 +964,8 @@ public class DhcpPacketTest { assertTrue(msg, Arrays.equals(expected, actual)); } - public void checkBuildOfferPacket(int leaseTimeSecs) throws Exception { + public void checkBuildOfferPacket(int leaseTimeSecs, @Nullable String hostname) + throws Exception { final int renewalTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) / 2); final int rebindingTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) * 875 / 1000); final int transactionId = 0xdeadbeef; @@ -971,7 +976,8 @@ public class DhcpPacketTest { CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */, BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */, Collections.singletonList(SERVER_ADDR) /* dnsServers */, - SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, false /* metered */); + SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname, + false /* metered */, MTU); ByteArrayOutputStream bos = new ByteArrayOutputStream(); // BOOTP headers @@ -1027,12 +1033,22 @@ public class DhcpPacketTest { // Nameserver bos.write(new byte[] { (byte) 0x06, (byte) 0x04 }); bos.write(SERVER_ADDR.getAddress()); + // Hostname + if (hostname != null) { + bos.write(new byte[]{(byte) 0x0c, (byte) hostname.length()}); + bos.write(hostname.getBytes(Charset.forName("US-ASCII"))); + } + // MTU + bos.write(new byte[] { (byte) 0x1a, (byte) 0x02 }); + bos.write(shortToByteArray(MTU)); // End options. bos.write(0xff); - final byte[] expected = bos.toByteArray(); - assertTrue((expected.length & 1) == 0); + if ((bos.size() & 1) != 0) { + bos.write(0x00); + } + final byte[] expected = bos.toByteArray(); final byte[] actual = new byte[packet.limit()]; packet.get(actual); final String msg = "Expected:\n " + HexDump.dumpHexString(expected) + @@ -1042,13 +1058,18 @@ public class DhcpPacketTest { @Test public void testOfferPacket() throws Exception { - checkBuildOfferPacket(3600); - checkBuildOfferPacket(Integer.MAX_VALUE); - checkBuildOfferPacket(0x80000000); - checkBuildOfferPacket(INFINITE_LEASE); + checkBuildOfferPacket(3600, HOSTNAME); + checkBuildOfferPacket(Integer.MAX_VALUE, HOSTNAME); + checkBuildOfferPacket(0x80000000, HOSTNAME); + checkBuildOfferPacket(INFINITE_LEASE, HOSTNAME); + checkBuildOfferPacket(3600, null); } private static byte[] intToByteArray(int val) { return ByteBuffer.allocate(4).putInt(val).array(); } + + private static byte[] shortToByteArray(short val) { + return ByteBuffer.allocate(2).putShort(val).array(); + } } diff --git a/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java index 45a50d9a8b5f..df34c7310b63 100644 --- a/tests/net/java/android/net/dhcp/DhcpServerTest.java +++ b/tests/net/java/android/net/dhcp/DhcpServerTest.java @@ -17,6 +17,7 @@ package android.net.dhcp; import static android.net.dhcp.DhcpPacket.DHCP_CLIENT; +import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME; import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP; import static android.net.dhcp.DhcpPacket.INADDR_ANY; import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST; @@ -87,6 +88,7 @@ public class DhcpServerTest { Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201"))); private static final long TEST_LEASE_TIME_SECS = 3600L; private static final int TEST_MTU = 1500; + private static final String TEST_HOSTNAME = "testhostname"; private static final int TEST_TRANSACTION_ID = 123; private static final byte[] TEST_CLIENT_MAC_BYTES = new byte [] { 1, 2, 3, 4, 5, 6 }; @@ -96,7 +98,10 @@ public class DhcpServerTest { private static final long TEST_CLOCK_TIME = 1234L; private static final int TEST_LEASE_EXPTIME_SECS = 3600; private static final DhcpLease TEST_LEASE = new DhcpLease(null, TEST_CLIENT_MAC, - TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS*1000L + TEST_CLOCK_TIME, null /* hostname */); + TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, + null /* hostname */); + private static final DhcpLease TEST_LEASE_WITH_HOSTNAME = new DhcpLease(null, TEST_CLIENT_MAC, + TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, TEST_HOSTNAME); @NonNull @Mock private Dependencies mDeps; @@ -217,15 +222,17 @@ public class DhcpServerTest { public void testRequest_Selecting_Ack() throws Exception { when(mRepository.requestLease(isNull() /* clientId */, eq(TEST_CLIENT_MAC), eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */, - eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, isNull() /* hostname */)) - .thenReturn(TEST_LEASE); + eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, eq(TEST_HOSTNAME))) + .thenReturn(TEST_LEASE_WITH_HOSTNAME); final DhcpRequestPacket request = makeRequestSelectingPacket(); + request.mHostName = TEST_HOSTNAME; + request.mRequestedParams = new byte[] { DHCP_HOST_NAME }; mServer.processPacket(request, DHCP_CLIENT); assertResponseSentTo(TEST_CLIENT_ADDR); final DhcpAckPacket packet = assertAck(getPacket()); - assertMatchesTestLease(packet); + assertMatchesTestLease(packet, TEST_HOSTNAME); } @Test @@ -270,14 +277,18 @@ public class DhcpServerTest { * - other request states (init-reboot/renewing/rebinding) */ - private void assertMatchesTestLease(@NonNull DhcpPacket packet) { + private void assertMatchesTestLease(@NonNull DhcpPacket packet, @Nullable String hostname) { assertMatchesClient(packet); assertFalse(packet.hasExplicitClientId()); assertEquals(TEST_SERVER_ADDR, packet.mServerIdentifier); assertEquals(TEST_CLIENT_ADDR, packet.mYourIp); assertNotNull(packet.mLeaseTime); assertEquals(TEST_LEASE_EXPTIME_SECS, (int) packet.mLeaseTime); - assertNull(packet.mHostName); + assertEquals(hostname, packet.mHostName); + } + + private void assertMatchesTestLease(@NonNull DhcpPacket packet) { + assertMatchesTestLease(packet, null); } private void assertMatchesClient(@NonNull DhcpPacket packet) { diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java new file mode 100644 index 000000000000..122edbaf078c --- /dev/null +++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java @@ -0,0 +1,327 @@ +/* + * 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.net.netlink; + +import static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; +import static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; +import static android.os.Process.INVALID_UID; +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; +import static android.system.OsConstants.IPPROTO_TCP; +import static android.system.OsConstants.IPPROTO_UDP; +import static android.system.OsConstants.SOCK_DGRAM; +import static android.system.OsConstants.SOCK_STREAM; +import static android.system.OsConstants.SOL_SOCKET; +import static android.system.OsConstants.SO_RCVTIMEO; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.netlink.StructNlMsgHdr; +import android.os.Process; +import android.support.test.runner.AndroidJUnit4; +import android.support.test.filters.SmallTest; +import android.support.test.InstrumentationRegistry; +import android.system.Os; +import android.system.StructTimeval; +import android.util.Log; +import java.io.FileDescriptor; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import libcore.util.HexEncoding; + +import org.junit.Before; +import org.junit.runner.RunWith; +import org.junit.Test; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class InetDiagSocketTest { + private final String TAG = "InetDiagSocketTest"; + private ConnectivityManager mCm; + private Context mContext; + private final static int SOCKET_TIMEOUT_MS = 100; + + @Before + public void setUp() throws Exception { + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + mContext = instrumentation.getTargetContext(); + mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + } + + private class Connection { + public int socketDomain; + public int socketType; + public InetAddress localAddress; + public InetAddress remoteAddress; + public InetAddress localhostAddress; + public InetSocketAddress local; + public InetSocketAddress remote; + public int protocol; + public FileDescriptor localFd; + public FileDescriptor remoteFd; + + public FileDescriptor createSocket() throws Exception { + return Os.socket(socketDomain, socketType, protocol); + } + + public Connection(String to, String from) throws Exception { + remoteAddress = InetAddress.getByName(to); + if (from != null) { + localAddress = InetAddress.getByName(from); + } else { + localAddress = (remoteAddress instanceof Inet4Address) ? + Inet4Address.getByName("localhost") : Inet6Address.getByName("::"); + } + if ((localAddress instanceof Inet4Address) && (remoteAddress instanceof Inet4Address)) { + socketDomain = AF_INET; + localhostAddress = Inet4Address.getByName("localhost"); + } else { + socketDomain = AF_INET6; + localhostAddress = Inet6Address.getByName("::"); + } + } + + public void close() throws Exception { + Os.close(localFd); + } + } + + private class TcpConnection extends Connection { + public TcpConnection(String to, String from) throws Exception { + super(to, from); + protocol = IPPROTO_TCP; + socketType = SOCK_STREAM; + + remoteFd = createSocket(); + Os.bind(remoteFd, remoteAddress, 0); + Os.listen(remoteFd, 10); + int remotePort = ((InetSocketAddress) Os.getsockname(remoteFd)).getPort(); + + localFd = createSocket(); + Os.bind(localFd, localAddress, 0); + Os.connect(localFd, remoteAddress, remotePort); + + local = (InetSocketAddress) Os.getsockname(localFd); + remote = (InetSocketAddress) Os.getpeername(localFd); + } + + public void close() throws Exception { + super.close(); + Os.close(remoteFd); + } + } + private class UdpConnection extends Connection { + public UdpConnection(String to, String from) throws Exception { + super(to, from); + protocol = IPPROTO_UDP; + socketType = SOCK_DGRAM; + + remoteFd = null; + localFd = createSocket(); + Os.bind(localFd, localAddress, 0); + + Os.connect(localFd, remoteAddress, 7); + local = (InetSocketAddress) Os.getsockname(localFd); + remote = new InetSocketAddress(remoteAddress, 7); + } + } + + private void checkConnectionOwnerUid(int protocol, InetSocketAddress local, + InetSocketAddress remote, boolean expectSuccess) { + final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID; + final int uid = mCm.getConnectionOwnerUid(protocol, local, remote); + assertEquals(expectedUid, uid); + } + + private int findLikelyFreeUdpPort(UdpConnection conn) throws Exception { + UdpConnection udp = new UdpConnection(conn.remoteAddress.getHostAddress(), + conn.localAddress.getHostAddress()); + final int localPort = udp.local.getPort(); + udp.close(); + return localPort; + } + + public void checkGetConnectionOwnerUid(String to, String from) throws Exception { + /** + * For TCP connections, create a test connection and verify that this + * {protocol, local, remote} socket result in receiving a valid UID. + */ + TcpConnection tcp = new TcpConnection(to, from); + checkConnectionOwnerUid(tcp.protocol, tcp.local, tcp.remote, true); + checkConnectionOwnerUid(IPPROTO_UDP, tcp.local, tcp.remote, false); + checkConnectionOwnerUid(tcp.protocol, new InetSocketAddress(0), tcp.remote, false); + checkConnectionOwnerUid(tcp.protocol, tcp.local, new InetSocketAddress(0), false); + tcp.close(); + + /** + * For UDP connections, either a complete match {protocol, local, remote} or a + * partial match {protocol, local} should return a valid UID. + */ + UdpConnection udp = new UdpConnection(to,from); + checkConnectionOwnerUid(udp.protocol, udp.local, udp.remote, true); + checkConnectionOwnerUid(udp.protocol, udp.local, new InetSocketAddress(0), true); + checkConnectionOwnerUid(IPPROTO_TCP, udp.local, udp.remote, false); + checkConnectionOwnerUid(udp.protocol, new InetSocketAddress(findLikelyFreeUdpPort(udp)), + udp.remote, false); + udp.close(); + } + + @Test + public void testGetConnectionOwnerUid() throws Exception { + checkGetConnectionOwnerUid("::", null); + checkGetConnectionOwnerUid("::", "::"); + checkGetConnectionOwnerUid("0.0.0.0", null); + checkGetConnectionOwnerUid("0.0.0.0", "0.0.0.0"); + checkGetConnectionOwnerUid("127.0.0.1", null); + checkGetConnectionOwnerUid("127.0.0.1", "127.0.0.2"); + checkGetConnectionOwnerUid("::1", null); + checkGetConnectionOwnerUid("::1", "::1"); + } + + // Hexadecimal representation of InetDiagReqV2 request. + private static final String INET_DIAG_REQ_V2_UDP_INET4_HEX = + // struct nlmsghdr + "48000000" + // length = 72 + "1400" + // type = SOCK_DIAG_BY_FAMILY + "0103" + // flags = NLM_F_REQUEST | NLM_F_DUMP + "00000000" + // seqno + "00000000" + // pid (0 == kernel) + // struct inet_diag_req_v2 + "02" + // family = AF_INET + "11" + // protcol = IPPROTO_UDP + "00" + // idiag_ext + "00" + // pad + "ffffffff" + // idiag_states + // inet_diag_sockid + "a5de" + // idiag_sport = 42462 + "b971" + // idiag_dport = 47473 + "0a006402000000000000000000000000" + // idiag_src = 10.0.100.2 + "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 + "00000000" + // idiag_if + "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE + private static final byte[] INET_DIAG_REQ_V2_UDP_INET4_BYTES = + HexEncoding.decode(INET_DIAG_REQ_V2_UDP_INET4_HEX.toCharArray(), false); + + @Test + public void testInetDiagReqV2UdpInet4() throws Exception { + InetSocketAddress local = new InetSocketAddress(InetAddress.getByName("10.0.100.2"), + 42462); + InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"), + 47473); + final byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_UDP, local, remote, AF_INET, + (short) (NLM_F_REQUEST | NLM_F_DUMP)); + assertArrayEquals(INET_DIAG_REQ_V2_UDP_INET4_BYTES, msg); + } + + // Hexadecimal representation of InetDiagReqV2 request. + private static final String INET_DIAG_REQ_V2_TCP_INET6_HEX = + // struct nlmsghdr + "48000000" + // length = 72 + "1400" + // type = SOCK_DIAG_BY_FAMILY + "0100" + // flags = NLM_F_REQUEST + "00000000" + // seqno + "00000000" + // pid (0 == kernel) + // struct inet_diag_req_v2 + "0a" + // family = AF_INET6 + "06" + // protcol = IPPROTO_TCP + "00" + // idiag_ext + "00" + // pad + "ffffffff" + // idiag_states + // inet_diag_sockid + "a5de" + // idiag_sport = 42462 + "b971" + // idiag_dport = 47473 + "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b + "08080808000000000000000000000000" + // idiag_dst = 8.8.8.8 + "00000000" + // idiag_if + "ffffffffffffffff"; // idiag_cookie = INET_DIAG_NOCOOKIE + private static final byte[] INET_DIAG_REQ_V2_TCP_INET6_BYTES = + HexEncoding.decode(INET_DIAG_REQ_V2_TCP_INET6_HEX.toCharArray(), false); + + @Test + public void testInetDiagReqV2TcpInet6() throws Exception { + InetSocketAddress local = new InetSocketAddress( + InetAddress.getByName("fe80::86c9:b2ff:fe6a:ed4b"), 42462); + InetSocketAddress remote = new InetSocketAddress(InetAddress.getByName("8.8.8.8"), + 47473); + byte[] msg = InetDiagMessage.InetDiagReqV2(IPPROTO_TCP, local, remote, AF_INET6, + NLM_F_REQUEST); + + assertArrayEquals(INET_DIAG_REQ_V2_TCP_INET6_BYTES, msg); + } + + // Hexadecimal representation of InetDiagReqV2 request. + private static final String INET_DIAG_MSG_HEX = + // struct nlmsghdr + "58000000" + // length = 88 + "1400" + // type = SOCK_DIAG_BY_FAMILY + "0200" + // flags = NLM_F_MULTI + "00000000" + // seqno + "f5220000" + // pid (0 == kernel) + // struct inet_diag_msg + "0a" + // family = AF_INET6 + "01" + // idiag_state + "00" + // idiag_timer + "00" + // idiag_retrans + // inet_diag_sockid + "a817" + // idiag_sport = 43031 + "960f" + // idiag_dport = 38415 + "fe8000000000000086c9b2fffe6aed4b" + // idiag_src = fe80::86c9:b2ff:fe6a:ed4b + "00000000000000000000ffff08080808" + // idiag_dst = 8.8.8.8 + "00000000" + // idiag_if + "ffffffffffffffff" + // idiag_cookie = INET_DIAG_NOCOOKIE + "00000000" + // idiag_expires + "00000000" + // idiag_rqueue + "00000000" + // idiag_wqueue + "a3270000" + // idiag_uid + "A57E1900"; // idiag_inode + private static final byte[] INET_DIAG_MSG_BYTES = + HexEncoding.decode(INET_DIAG_MSG_HEX.toCharArray(), false); + + @Test + public void testParseInetDiagResponse() throws Exception { + final ByteBuffer byteBuffer = ByteBuffer.wrap(INET_DIAG_MSG_BYTES); + byteBuffer.order(ByteOrder.LITTLE_ENDIAN); + final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer); + assertNotNull(msg); + + assertTrue(msg instanceof InetDiagMessage); + final InetDiagMessage inetDiagMsg = (InetDiagMessage) msg; + assertEquals(10147, inetDiagMsg.mStructInetDiagMsg.idiag_uid); + + final StructNlMsgHdr hdr = inetDiagMsg.getHeader(); + assertNotNull(hdr); + assertEquals(NetlinkConstants.SOCK_DIAG_BY_FAMILY, hdr.nlmsg_type); + assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags); + assertEquals(0, hdr.nlmsg_seq); + assertEquals(8949, hdr.nlmsg_pid); + } +} diff --git a/tests/net/java/android/net/util/SharedLogTest.java b/tests/net/java/android/net/util/SharedLogTest.java index d46facfaba06..86048604e95f 100644 --- a/tests/net/java/android/net/util/SharedLogTest.java +++ b/tests/net/java/android/net/util/SharedLogTest.java @@ -44,6 +44,8 @@ public class SharedLogTest { final SharedLog logLevel2a = logTop.forSubComponent("twoA"); final SharedLog logLevel2b = logTop.forSubComponent("twoB"); logLevel2b.e("2b or not 2b"); + logLevel2b.e("No exception", null); + logLevel2b.e("Wait, here's one", new Exception("Test")); logLevel2a.w("second post?"); final SharedLog logLevel3 = logLevel2a.forSubComponent("three"); @@ -54,6 +56,9 @@ public class SharedLogTest { final String[] expected = { " - MARK first post!", " - [twoB] ERROR 2b or not 2b", + " - [twoB] ERROR No exception", + // No stacktrace in shared log, only in logcat + " - [twoB] ERROR Wait, here's one: Test", " - [twoA] WARN second post?", " - still logging", " - [twoA.three] 3 >> 2", diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index e3db7e8a1354..1c77fcc568f6 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -79,6 +79,7 @@ import static org.mockito.Mockito.when; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -248,7 +249,7 @@ public class ConnectivityServiceTest { @Spy private Resources mResources; private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); - MockContext(Context base) { + MockContext(Context base, ContentProvider settingsProvider) { super(base); mResources = spy(base.getResources()); @@ -260,7 +261,7 @@ public class ConnectivityServiceTest { }); mContentResolver = new MockContentResolver(); - mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + mContentResolver.addProvider(Settings.AUTHORITY, settingsProvider); } @Override @@ -1048,7 +1049,9 @@ public class ConnectivityServiceTest { Looper.prepare(); } - mServiceContext = new MockContext(InstrumentationRegistry.getContext()); + FakeSettingsProvider.clearSettingsProvider(); + mServiceContext = new MockContext(InstrumentationRegistry.getContext(), + new FakeSettingsProvider()); LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class); LocalServices.addService( NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class)); @@ -1067,13 +1070,13 @@ public class ConnectivityServiceTest { // Ensure that the default setting for Captive Portals is used for most tests setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT); - setMobileDataAlwaysOn(false); + setAlwaysOnNetworks(false); setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com"); } @After public void tearDown() throws Exception { - setMobileDataAlwaysOn(false); + setAlwaysOnNetworks(false); if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); mCellNetworkAgent = null; @@ -1086,6 +1089,7 @@ public class ConnectivityServiceTest { mEthernetNetworkAgent.disconnect(); mEthernetNetworkAgent = null; } + FakeSettingsProvider.clearSettingsProvider(); } private static int transportToLegacyType(int transport) { @@ -2023,7 +2027,7 @@ public class ConnectivityServiceTest { @Test public void testNetworkGoesIntoBackgroundAfterLinger() { - setMobileDataAlwaysOn(true); + setAlwaysOnNetworks(true); NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities() .build(); @@ -2768,10 +2772,10 @@ public class ConnectivityServiceTest { Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode); } - private void setMobileDataAlwaysOn(boolean enable) { + private void setAlwaysOnNetworks(boolean enable) { ContentResolver cr = mServiceContext.getContentResolver(); Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0); - mService.updateMobileDataAlwaysOn(); + mService.updateAlwaysOnNetworks(); waitForIdle(); } @@ -2793,7 +2797,7 @@ public class ConnectivityServiceTest { public void testBackgroundNetworks() throws Exception { // Create a background request. We can't do this ourselves because ConnectivityService // doesn't have an API for it. So just turn on mobile data always on. - setMobileDataAlwaysOn(true); + setAlwaysOnNetworks(true); final NetworkRequest request = new NetworkRequest.Builder().build(); final NetworkRequest fgRequest = new NetworkRequest.Builder() .addCapability(NET_CAPABILITY_FOREGROUND).build(); @@ -2991,7 +2995,7 @@ public class ConnectivityServiceTest { // Turn on mobile data always on. The factory starts looking again. testFactory.expectAddRequests(1); - setMobileDataAlwaysOn(true); + setAlwaysOnNetworks(true); testFactory.waitForNetworkRequests(2); assertTrue(testFactory.getMyStartRequested()); @@ -3011,7 +3015,7 @@ public class ConnectivityServiceTest { // Turn off mobile data always on and expect the request to disappear... testFactory.expectRemoveRequests(1); - setMobileDataAlwaysOn(false); + setAlwaysOnNetworks(false); testFactory.waitForNetworkRequests(1); // ... and cell data to be torn down. @@ -4532,4 +4536,78 @@ public class ConnectivityServiceTest { mCellNetworkAgent.disconnect(); mCm.unregisterNetworkCallback(networkCallback); } + + @Test + public void testDataActivityTracking() throws RemoteException { + final TestNetworkCallback networkCallback = new TestNetworkCallback(); + final NetworkRequest networkRequest = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_INTERNET) + .build(); + mCm.registerNetworkCallback(networkRequest, networkCallback); + + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + final LinkProperties cellLp = new LinkProperties(); + cellLp.setInterfaceName(MOBILE_IFNAME); + mCellNetworkAgent.sendLinkProperties(cellLp); + reset(mNetworkManagementService); + mCellNetworkAgent.connect(true); + networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(), + eq(ConnectivityManager.TYPE_MOBILE)); + + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + final LinkProperties wifiLp = new LinkProperties(); + wifiLp.setInterfaceName(WIFI_IFNAME); + mWiFiNetworkAgent.sendLinkProperties(wifiLp); + + // Network switch + reset(mNetworkManagementService); + mWiFiNetworkAgent.connect(true); + networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); + networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); + verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(), + eq(ConnectivityManager.TYPE_WIFI)); + verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME)); + + // Disconnect wifi and switch back to cell + reset(mNetworkManagementService); + mWiFiNetworkAgent.disconnect(); + networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); + assertNoCallbacks(networkCallback); + verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME)); + verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(), + eq(ConnectivityManager.TYPE_MOBILE)); + + // reconnect wifi + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + wifiLp.setInterfaceName(WIFI_IFNAME); + mWiFiNetworkAgent.sendLinkProperties(wifiLp); + mWiFiNetworkAgent.connect(true); + networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); + networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); + + // Disconnect cell + reset(mNetworkManagementService); + mCellNetworkAgent.disconnect(); + networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent); + // LOST callback is triggered earlier than removing idle timer. Broadcast should also be + // sent as network being switched. Ensure rule removal for cell will not be triggered + // unexpectedly before network being removed. + waitForIdle(); + verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME)); + verify(mNetworkManagementService, times(1)).removeNetwork( + eq(mCellNetworkAgent.getNetwork().netId)); + + // Disconnect wifi + ConditionVariable cv = waitForConnectivityBroadcasts(1); + reset(mNetworkManagementService); + mWiFiNetworkAgent.disconnect(); + waitFor(cv); + verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME)); + + // Clean up + mCm.unregisterNetworkCallback(networkCallback); + } } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 40d5544dccd8..a6ed9f252008 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -33,6 +33,7 @@ import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE; import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; +import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -75,6 +76,8 @@ import android.net.NetworkRequest; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.RouteInfo; +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; @@ -85,6 +88,7 @@ import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.INetworkManagementService; +import android.os.Looper; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.test.TestLooper; @@ -146,6 +150,7 @@ public class TetheringTest { @Mock private UpstreamNetworkMonitor mUpstreamNetworkMonitor; @Mock private IPv6TetheringCoordinator mIPv6TetheringCoordinator; @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; + @Mock private DhcpServer mDhcpServer; @Mock private INetd mNetd; private final MockTetheringDependencies mTetheringDependencies = @@ -240,6 +245,12 @@ public class TetheringTest { public INetd getNetdService() { return mNetd; } + + @Override + public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, + DhcpServingParams params, SharedLog log) { + return mDhcpServer; + } }; } @@ -333,6 +344,7 @@ public class TetheringTest { mServiceContext = new MockContext(mContext); mContentResolver = new MockContentResolver(mServiceContext); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); + Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); mIntents = new Vector<>(); mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -343,12 +355,16 @@ public class TetheringTest { mServiceContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_TETHER_STATE_CHANGED)); mTetheringDependencies.reset(); - mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager, - mLooper.getLooper(), mSystemProperties, - mTetheringDependencies); + mTethering = makeTethering(); verify(mNMService).registerTetheringStatsProvider(any(), anyString()); } + private Tethering makeTethering() { + return new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager, + mLooper.getLooper(), mSystemProperties, + mTetheringDependencies); + } + @After public void tearDown() { mServiceContext.unregisterReceiver(mBroadcastReceiver); @@ -597,6 +613,18 @@ public class TetheringTest { sendIPv6TetherUpdates(upstreamState); verify(mRouterAdvertisementDaemon, never()).buildNewRa(any(), notNull()); + verify(mDhcpServer, times(1)).start(); + } + + @Test + public void workingMobileUsbTethering_IPv4LegacyDhcp() { + Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); + mTethering = makeTethering(); + final NetworkState upstreamState = buildMobileIPv4UpstreamState(); + runUsbTethering(upstreamState); + sendIPv6TetherUpdates(upstreamState); + + verify(mDhcpServer, never()).start(); } @Test @@ -620,6 +648,7 @@ public class TetheringTest { verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); verify(mRouterAdvertisementDaemon, times(1)).start(); + verify(mDhcpServer, times(1)).start(); sendIPv6TetherUpdates(upstreamState); verify(mRouterAdvertisementDaemon, times(1)).buildNewRa(any(), notNull()); @@ -633,6 +662,7 @@ public class TetheringTest { verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + verify(mDhcpServer, times(1)).start(); verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_XLAT_MOBILE_IFNAME); @@ -649,6 +679,7 @@ public class TetheringTest { runUsbTethering(upstreamState); verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + verify(mDhcpServer, times(1)).start(); verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); // Then 464xlat comes up @@ -671,6 +702,8 @@ public class TetheringTest { // Forwarding was not re-added for v6 (still times(1)) verify(mNMService, times(1)).enableNat(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); verify(mNMService, times(1)).startInterfaceForwarding(TEST_USB_IFNAME, TEST_MOBILE_IFNAME); + // DHCP not restarted on downstream (still times(1)) + verify(mDhcpServer, times(1)).start(); } @Test diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java index bb312309b34f..521778484d91 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java @@ -225,13 +225,4 @@ public class TetheringConfigurationTest { final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); assertFalse(cfg.enableLegacyDhcpServer); } - - @Test - public void testNewDhcpServerDefault() { - Settings.Global.putString(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, null); - - final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); - // TODO: change to false when new server is promoted to default - assertTrue(cfg.enableLegacyDhcpServer); - } } diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h index f71955247d78..b46a50398217 100644 --- a/tools/aapt2/ConfigDescription.h +++ b/tools/aapt2/ConfigDescription.h @@ -53,11 +53,11 @@ struct ConfigDescription : public android::ResTable_config { ConfigDescription(); ConfigDescription(const android::ResTable_config& o); // NOLINT(implicit) ConfigDescription(const ConfigDescription& o); - ConfigDescription(ConfigDescription&& o); + ConfigDescription(ConfigDescription&& o) noexcept; ConfigDescription& operator=(const android::ResTable_config& o); ConfigDescription& operator=(const ConfigDescription& o); - ConfigDescription& operator=(ConfigDescription&& o); + ConfigDescription& operator=(ConfigDescription&& o) noexcept; ConfigDescription CopyWithoutSdkVersion() const; @@ -124,7 +124,7 @@ inline ConfigDescription::ConfigDescription(const ConfigDescription& o) { *static_cast<android::ResTable_config*>(this) = o; } -inline ConfigDescription::ConfigDescription(ConfigDescription&& o) { +inline ConfigDescription::ConfigDescription(ConfigDescription&& o) noexcept { *this = o; } @@ -141,7 +141,7 @@ inline ConfigDescription& ConfigDescription::operator=( return *this; } -inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) { +inline ConfigDescription& ConfigDescription::operator=(ConfigDescription&& o) noexcept { *this = o; return *this; } diff --git a/tools/aapt2/io/FileStream_test.cpp b/tools/aapt2/io/FileStream_test.cpp index c0eaa8e08418..7872738320c3 100644 --- a/tools/aapt2/io/FileStream_test.cpp +++ b/tools/aapt2/io/FileStream_test.cpp @@ -41,46 +41,46 @@ TEST(FileInputStreamTest, NextAndBackup) { ASSERT_FALSE(in.HadError()); EXPECT_THAT(in.ByteCount(), Eq(0u)); - const char* buffer; + const void* buffer; size_t size; - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError(); + ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError(); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(in.ByteCount(), Eq(10u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("this is a ")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a ")); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin")); in.BackUp(5u); EXPECT_THAT(in.ByteCount(), Eq(15u)); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(5u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin")); // Backup 1 more than possible. Should clamp. in.BackUp(11u); EXPECT_THAT(in.ByteCount(), Eq(10u)); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(20u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin")); - ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + ASSERT_TRUE(in.Next(&buffer, &size)); ASSERT_THAT(size, Eq(1u)); ASSERT_THAT(buffer, NotNull()); ASSERT_THAT(in.ByteCount(), Eq(21u)); - EXPECT_THAT(StringPiece(buffer, size), Eq("g")); + EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g")); - EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size)); + EXPECT_FALSE(in.Next(&buffer, &size)); EXPECT_FALSE(in.HadError()); } @@ -93,25 +93,25 @@ TEST(FileOutputStreamTest, NextAndBackup) { ASSERT_FALSE(out.HadError()); EXPECT_THAT(out.ByteCount(), Eq(0u)); - char* buffer; + void* buffer; size_t size; - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(10u)); - memcpy(buffer, input.c_str(), size); + memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size); - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(20u)); - memcpy(buffer, input.c_str() + 10u, size); + memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size); - ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size)); + ASSERT_TRUE(out.Next(&buffer, &size)); ASSERT_THAT(size, Eq(10u)); ASSERT_THAT(buffer, NotNull()); EXPECT_THAT(out.ByteCount(), Eq(30u)); - buffer[0] = input[20u]; + reinterpret_cast<char*>(buffer)[0] = input[20u]; out.BackUp(size - 1); EXPECT_THAT(out.ByteCount(), Eq(21u)); diff --git a/tools/aapt2/java/ManifestClassGenerator.cpp b/tools/aapt2/java/ManifestClassGenerator.cpp index be67c9c8c03c..10e504ec0752 100644 --- a/tools/aapt2/java/ManifestClassGenerator.cpp +++ b/tools/aapt2/java/ManifestClassGenerator.cpp @@ -26,21 +26,20 @@ #include "util/Maybe.h" #include "xml/XmlDom.h" -using ::android::StringPiece; using ::aapt::text::IsJavaIdentifier; namespace aapt { -static Maybe<StringPiece> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source, +static Maybe<std::string> ExtractJavaIdentifier(IDiagnostics* diag, const Source& source, const std::string& value) { - StringPiece result = value; + std::string result = value; size_t pos = value.rfind('.'); if (pos != std::string::npos) { result = result.substr(pos + 1); } // Normalize only the java identifier, leave the original value unchanged. - if (result.contains("-")) { + if (result.find("-") != std::string::npos) { result = JavaClassGenerator::TransformToFieldName(result); } @@ -64,7 +63,7 @@ static bool WriteSymbol(const Source& source, IDiagnostics* diag, xml::Element* return false; } - Maybe<StringPiece> result = + Maybe<std::string> result = ExtractJavaIdentifier(diag, source.WithLine(el->line_number), attr->value); if (!result) { return false; diff --git a/tools/aapt2/util/BigBuffer.h b/tools/aapt2/util/BigBuffer.h index 30452552888e..d4b3abce68a7 100644 --- a/tools/aapt2/util/BigBuffer.h +++ b/tools/aapt2/util/BigBuffer.h @@ -68,7 +68,7 @@ class BigBuffer { */ explicit BigBuffer(size_t block_size); - BigBuffer(BigBuffer&& rhs); + BigBuffer(BigBuffer&& rhs) noexcept; /** * Number of occupied bytes in all the allocated blocks. @@ -136,7 +136,7 @@ class BigBuffer { inline BigBuffer::BigBuffer(size_t block_size) : block_size_(block_size), size_(0) {} -inline BigBuffer::BigBuffer(BigBuffer&& rhs) +inline BigBuffer::BigBuffer(BigBuffer&& rhs) noexcept : block_size_(rhs.block_size_), size_(rhs.size_), blocks_(std::move(rhs.blocks_)) {} diff --git a/tools/aapt2/util/ImmutableMap.h b/tools/aapt2/util/ImmutableMap.h index 59858e492c4c..1727b18e4106 100644 --- a/tools/aapt2/util/ImmutableMap.h +++ b/tools/aapt2/util/ImmutableMap.h @@ -32,8 +32,8 @@ class ImmutableMap { using const_iterator = typename std::vector<std::pair<TKey, TValue>>::const_iterator; - ImmutableMap(ImmutableMap&&) = default; - ImmutableMap& operator=(ImmutableMap&&) = default; + ImmutableMap(ImmutableMap&&) noexcept = default; + ImmutableMap& operator=(ImmutableMap&&) noexcept = default; static ImmutableMap<TKey, TValue> CreatePreSorted( std::initializer_list<std::pair<TKey, TValue>> list) { diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h index 9a82418e0a5a..031276c8b885 100644 --- a/tools/aapt2/util/Maybe.h +++ b/tools/aapt2/util/Maybe.h @@ -46,7 +46,7 @@ class Maybe { template <typename U> Maybe(const Maybe<U>& rhs); // NOLINT(implicit) - Maybe(Maybe&& rhs); + Maybe(Maybe&& rhs) noexcept; template <typename U> Maybe(Maybe<U>&& rhs); // NOLINT(implicit) @@ -56,7 +56,7 @@ class Maybe { template <typename U> Maybe& operator=(const Maybe<U>& rhs); - Maybe& operator=(Maybe&& rhs); + Maybe& operator=(Maybe&& rhs) noexcept; template <typename U> Maybe& operator=(Maybe<U>&& rhs); @@ -134,7 +134,7 @@ Maybe<T>::Maybe(const Maybe<U>& rhs) : nothing_(rhs.nothing_) { } template <typename T> -Maybe<T>::Maybe(Maybe&& rhs) : nothing_(rhs.nothing_) { +Maybe<T>::Maybe(Maybe&& rhs) noexcept : nothing_(rhs.nothing_) { if (!rhs.nothing_) { rhs.nothing_ = true; @@ -192,7 +192,7 @@ Maybe<T>& Maybe<T>::copy(const Maybe<U>& rhs) { } template <typename T> -inline Maybe<T>& Maybe<T>::operator=(Maybe&& rhs) { +inline Maybe<T>& Maybe<T>::operator=(Maybe&& rhs) noexcept { // Delegate to the actual assignment. return move(std::forward<Maybe<T>>(rhs)); } diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index 6c46e67be63d..fdc800bcc177 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -212,8 +212,8 @@ def main(argv): move_from_files(args.input_greylists, uncategorized, light_greylist) move_from_files(args.input_blacklists, uncategorized, blacklist) - # Iterate over all uncategorized members and move serialization API to light greylist. - move_serialization(uncategorized, light_greylist) + # Iterate over all uncategorized members and move serialization API to whitelist. + move_serialization(uncategorized, whitelist) # Extract package names of members from whitelist and light greylist, which # are assumed to have been finalized at this point. Assign all uncategorized diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py index 8f793189650c..4716241940b5 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists_test.py +++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py @@ -85,5 +85,23 @@ class TestHiddenapiListGeneration(unittest.TestCase): self.assertEqual( dst, set([ "Lfoo/bar/ClassA;->abc()J", "Lfoo/bar/ClassA;->def()J" ])) + def test_move_serialization(self): + # All the entries should be moved apart from the last one + src = set([ "Lfoo/bar/ClassA;->readObject(Ljava/io/ObjectInputStream;)V", + "Lfoo/bar/ClassA;->readObjectNoData()V", + "Lfoo/bar/ClassA;->readResolve()Ljava/lang/Object;", + "Lfoo/bar/ClassA;->serialVersionUID:J", + "Lfoo/bar/ClassA;->serialPersistentFields:[Ljava/io/ObjectStreamField;", + "Lfoo/bar/ClassA;->writeObject(Ljava/io/ObjectOutputStream;)V", + "Lfoo/bar/ClassA;->writeReplace()Ljava/lang/Object;", + # Should not be moved as signature does not match + "Lfoo/bar/ClassA;->readObject(Ljava/io/ObjectInputStream;)I"]) + expectedToMove = len(src) - 1 + dst = set() + packages = set([ "Lfoo/bar/" ]) + move_serialization(src, dst) + self.assertEqual(len(src), 1) + self.assertEqual(len(dst), expectedToMove) + if __name__ == '__main__': unittest.main() diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp index 3689a8f2981e..4b5677a75b70 100644 --- a/tools/incident_section_gen/main.cpp +++ b/tools/incident_section_gen/main.cpp @@ -140,7 +140,7 @@ static void splitAndPrint(const string& args) { size_t base = 0; size_t found; while (true) { - found = args.find_first_of(" ", base); + found = args.find_first_of(' ', base); if (found != base) { string arg = args.substr(base, found - base); printf(" \"%s\",", arg.c_str()); |