Merge "cts case com.android.server.cts.GraphicsStatsValidationTest#testDaveyDrawFrame in modue CtsIncidentHostTestCases failed"
diff --git a/api/current.txt b/api/current.txt
index 07dc4d2..5974877 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -68706,7 +68706,7 @@
method public java.util.regex.Matcher reset();
method public java.util.regex.Matcher reset(java.lang.CharSequence);
method public int start();
- method public int start(int) throws java.lang.IllegalStateException;
+ method public int start(int);
method public int start(java.lang.String);
method public java.util.regex.MatchResult toMatchResult();
method public java.util.regex.Matcher useAnchoringBounds(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 184ed44..863bfdf 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4969,6 +4969,28 @@
field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
+ field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
+ field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
+ field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
+ field public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617; // 0x651
+ field public static final int CODE_REJECT_INTERNAL_ERROR = 1612; // 0x64c
+ field public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608; // 0x648
+ field public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607; // 0x647
+ field public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611; // 0x64b
+ field public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616; // 0x650
+ field public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601; // 0x641
+ field public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618; // 0x652
+ field public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; // 0x655
+ field public static final int CODE_REJECT_ONGOING_E911_CALL = 1606; // 0x646
+ field public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620; // 0x654
+ field public static final int CODE_REJECT_ONGOING_HANDOVER = 1614; // 0x64e
+ field public static final int CODE_REJECT_QOS_FAILURE = 1613; // 0x64d
+ field public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604; // 0x644
+ field public static final int CODE_REJECT_UNKNOWN = 1600; // 0x640
+ field public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610; // 0x64a
+ field public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609; // 0x649
+ field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
+ field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
@@ -5240,6 +5262,7 @@
method public android.telephony.ims.stub.ImsUtImplBase getUt();
method public final void notifyCapabilitiesStatusChanged(android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
method public final void notifyIncomingCall(android.telephony.ims.stub.ImsCallSessionImplBase, android.os.Bundle);
+ method public final void notifyRejectedCall(android.telephony.ims.ImsCallProfile, android.telephony.ims.ImsReasonInfo);
method public final void notifyVoiceMessageCountUpdate(int);
method public void onFeatureReady();
method public void onFeatureRemoved();
diff --git a/api/test-current.txt b/api/test-current.txt
index 709b37e..24d1275 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -426,6 +426,14 @@
}
+package android.telecom {
+
+ public final class CallAudioState implements android.os.Parcelable {
+ ctor public CallAudioState(boolean, int, int, android.bluetooth.BluetoothDevice, java.util.Collection<android.bluetooth.BluetoothDevice>);
+ }
+
+}
+
package android.telephony {
public class MbmsDownloadSession implements java.lang.AutoCloseable {
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6d55d0b..d56c726 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -368,12 +368,14 @@
[Network Capabilities] Optional. A comma seprated list of network capabilities.
Values must be from NetworkCapabilities#NET_CAPABILITIES_* constants.
[IP config] Optional. If empty or not specified - DHCP will be used, otherwise
- static IP address with the mask.
+ use the following format to specify static IP configuration:
+ ip=<ip-address/mask> gateway=<ip-address> dns=<comma-sep-ip-addresses>
+ domains=<comma-sep-domains>
-->
<string-array translatable="false" name="config_ethernet_interfaces">
<!--
- <item>eth1;12,13,14,15;192.168.0.10/24</item>
- <item>eth2;;192.168.0.11/24</item>
+ <item>eth1;12,13,14,15;ip=192.168.0.10/24 gateway=192.168.0.1 dns=4.4.4.4,8.8.8.8</item>
+ <item>eth2;;ip=192.168.0.11/24</item>
-->
</string-array>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 8947bf0..fb78b3b 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -61,7 +61,7 @@
<shortcode country="bh" pattern="\\d{1,5}" free="81181" />
<!-- Brazil: 1-5 digits (standard system default, not country specific) -->
- <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963" />
+ <shortcode country="br" pattern="\\d{1,5}" free="6000[012]\\d|876|5500|9963|4141|8000" />
<!-- Belarus: 4 digits -->
<shortcode country="by" pattern="\\d{4}" premium="3336|4161|444[4689]|501[34]|7781" />
@@ -73,7 +73,7 @@
<shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765" />
<!-- Chile: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="cl" pattern="\\d{4,5}" free="9963" />
+ <shortcode country="cl" pattern="\\d{4,5}" free="9963|9240" />
<!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
@@ -104,7 +104,7 @@
<shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}|22791|222145|22189" />
<!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
- <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}|14789" />
+ <shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}|14789|17110" />
<!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
@@ -136,7 +136,7 @@
<shortcode country="in" pattern="\\d{1,5}" free="59336|53969" />
<!-- Indonesia: 1-5 digits (standard system default, not country specific) -->
- <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645" />
+ <shortcode country="id" pattern="\\d{1,5}" free="99477|6006|46645|363" />
<!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
@@ -190,7 +190,7 @@
<shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223" />
<!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
+ <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
<!-- New Zealand: 3-4 digits, known premium codes listed -->
<shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="3067|3068|4053" />
@@ -240,7 +240,7 @@
<shortcode country="sk" premium="\\d{4}" free="116\\d{3}|8000" />
<!-- Thailand: 4186001 used by AIS_TH_DCB -->
- <shortcode country="th" pattern="\\d{1,5}" free="4186001" />
+ <shortcode country="th" pattern="\\d{1,5}" premium="4\\d{6}" free="4186001" />
<!-- Tajikistan: 4 digits, known premium codes listed -->
<shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 434dfdf..64085ea 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -167,8 +167,6 @@
file="/system/framework/android.test.mock.jar" />
<library name="android.test.runner"
file="/system/framework/android.test.runner.jar" />
- <library name="javax.obex"
- file="/system/framework/javax.obex.jar" />
<!-- These are the standard packages that are white-listed to always have internet
access while in power save mode, even if they aren't in the foreground. -->
diff --git a/media/lib/tvremote/Android.bp b/media/lib/tvremote/Android.bp
new file mode 100644
index 0000000..5f101a3
--- /dev/null
+++ b/media/lib/tvremote/Android.bp
@@ -0,0 +1,24 @@
+//
+// 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.
+//
+
+java_sdk_library {
+ name: "com.android.media.tv.remoteprovider",
+ srcs: ["java/**/*.java"],
+ api_packages: ["com.android.media.tv.remoteprovider"],
+ dex_preopt: {
+ enabled: false,
+ }
+}
diff --git a/media/lib/tvremote/Android.mk b/media/lib/tvremote/Android.mk
deleted file mode 100644
index 1ffdd62..0000000
--- a/media/lib/tvremote/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-
-# the tvremoteprovider library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.media.tv.remoteprovider
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ==== com.android.media.tvremote.xml lib def ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.media.tv.remoteprovider.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
diff --git a/media/lib/tvremote/api/current.txt b/media/lib/tvremote/api/current.txt
new file mode 100644
index 0000000..eea9e9c
--- /dev/null
+++ b/media/lib/tvremote/api/current.txt
@@ -0,0 +1,21 @@
+package com.android.media.tv.remoteprovider {
+
+ public abstract class TvRemoteProvider {
+ ctor public TvRemoteProvider(android.content.Context);
+ method public void clearInputBridge(android.os.IBinder) throws java.lang.RuntimeException;
+ method public void closeInputBridge(android.os.IBinder) throws java.lang.RuntimeException;
+ method public android.os.IBinder getBinder();
+ method public final android.content.Context getContext();
+ method public void onInputBridgeConnected(android.os.IBinder);
+ method public void openRemoteInputBridge(android.os.IBinder, java.lang.String, int, int, int) throws java.lang.RuntimeException;
+ method public void sendKeyDown(android.os.IBinder, int) throws java.lang.RuntimeException;
+ method public void sendKeyUp(android.os.IBinder, int) throws java.lang.RuntimeException;
+ method public void sendPointerDown(android.os.IBinder, int, int, int) throws java.lang.RuntimeException;
+ method public void sendPointerSync(android.os.IBinder) throws java.lang.RuntimeException;
+ method public void sendPointerUp(android.os.IBinder, int) throws java.lang.RuntimeException;
+ method public void sendTimestamp(android.os.IBinder, long) throws java.lang.RuntimeException;
+ field public static final java.lang.String SERVICE_INTERFACE = "com.android.media.tv.remoteprovider.TvRemoteProvider";
+ }
+
+}
+
diff --git a/media/lib/tvremote/api/removed.txt b/media/lib/tvremote/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/tvremote/api/removed.txt
diff --git a/media/lib/tvremote/api/system-current.txt b/media/lib/tvremote/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/tvremote/api/system-current.txt
diff --git a/media/lib/tvremote/api/system-removed.txt b/media/lib/tvremote/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/tvremote/api/system-removed.txt
diff --git a/media/lib/tvremote/api/test-current.txt b/media/lib/tvremote/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/tvremote/api/test-current.txt
diff --git a/media/lib/tvremote/api/test-removed.txt b/media/lib/tvremote/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/tvremote/api/test-removed.txt
diff --git a/media/lib/tvremote/com.android.media.tv.remoteprovider.xml b/media/lib/tvremote/com.android.media.tv.remoteprovider.xml
deleted file mode 100644
index dcf479a..0000000
--- a/media/lib/tvremote/com.android.media.tv.remoteprovider.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<permissions>
- <library name="com.android.media.tv.remoteprovider"
- file="/system/framework/com.android.media.tv.remoteprovider.jar" />
-</permissions>
\ No newline at end of file
diff --git a/obex/Android.bp b/obex/Android.bp
new file mode 100644
index 0000000..6558eb3
--- /dev/null
+++ b/obex/Android.bp
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+java_sdk_library {
+ name: "javax.obex",
+ srcs: ["javax/**/*.java"],
+ api_packages: ["javax.obex"],
+}
diff --git a/obex/Android.mk b/obex/Android.mk
deleted file mode 100644
index e7c1fd3..0000000
--- a/obex/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE:= javax.obex
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE:= javax.obexstatic
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/obex/CleanSpec.mk b/obex/CleanSpec.mk
new file mode 100644
index 0000000..c104234
--- /dev/null
+++ b/obex/CleanSpec.mk
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+# runtime lib is renamed from javax.obex.jar to javax.obex.impl.jar
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/javax.obex.jar)
diff --git a/obex/api/current.txt b/obex/api/current.txt
new file mode 100644
index 0000000..1cd562f
--- /dev/null
+++ b/obex/api/current.txt
@@ -0,0 +1,12 @@
+package javax.obex {
+
+ public class ObexPacket {
+ method public static javax.obex.ObexPacket read(java.io.InputStream) throws java.io.IOException;
+ method public static javax.obex.ObexPacket read(int, java.io.InputStream) throws java.io.IOException;
+ field public int mHeaderId;
+ field public int mLength;
+ field public byte[] mPayload;
+ }
+
+}
+
diff --git a/obex/api/removed.txt b/obex/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/removed.txt
diff --git a/obex/api/system-current.txt b/obex/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/system-current.txt
diff --git a/obex/api/system-removed.txt b/obex/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/system-removed.txt
diff --git a/obex/api/test-current.txt b/obex/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/test-current.txt
diff --git a/obex/api/test-removed.txt b/obex/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/test-removed.txt
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index 6186a78..e645adc 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -66,10 +66,11 @@
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# out/target/common/obj/APPS/CtsShimPriv_intermediates/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
@@ -111,10 +112,11 @@
LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# frameworks/base/packages/CtsShim/build/shim/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 5ed14a0..6371d77 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -185,7 +185,12 @@
private boolean startIPv4() { return configureIPv4(true); }
- private void stopIPv4() { configureIPv4(false); }
+ private void stopIPv4() {
+ configureIPv4(false);
+ // NOTE: All of configureIPv4() will be refactored out of existence
+ // into calls to InterfaceController, shared with startIPv4().
+ mInterfaceCtrl.clearIPv4Address();
+ }
// TODO: Refactor this in terms of calls to InterfaceController.
private boolean configureIPv4(boolean enabled) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index da40692..e5cf394 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -179,6 +179,8 @@
private final PowerManager.WakeLock mWakeLock;
+ private final boolean mUseBpfTrafficStats;
+
private IConnectivityManager mConnManager;
@VisibleForTesting
@@ -328,6 +330,7 @@
mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
mSystemDir = checkNotNull(systemDir, "missing systemDir");
mBaseDir = checkNotNull(baseDir, "missing baseDir");
+ mUseBpfTrafficStats = new File("/sys/fs/bpf/traffic_uid_stats_map").exists();
}
@VisibleForTesting
@@ -916,7 +919,7 @@
}
private boolean checkBpfStatsEnable() {
- return new File("/sys/fs/bpf/traffic_uid_stats_map").exists();
+ return mUseBpfTrafficStats;
}
/**
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index 63ae09a..7f821ff 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -231,10 +231,10 @@
// TODO: Find an lighter weight approach.
private class LoggingCallbackWrapper extends Callback {
private static final String PREFIX = "INVOKE ";
- private Callback mCallback;
+ private final Callback mCallback;
public LoggingCallbackWrapper(Callback callback) {
- mCallback = callback;
+ mCallback = (callback != null) ? callback : new Callback();
}
private void log(String msg) {
@@ -605,6 +605,13 @@
private static final int EVENT_DHCPACTION_TIMEOUT = 11;
private static final int EVENT_READ_PACKET_FILTER_COMPLETE = 12;
+ // Internal commands to use instead of trying to call transitionTo() inside
+ // a given State's enter() method. Calling transitionTo() from enter/exit
+ // encounters a Log.wtf() that can cause trouble on eng builds.
+ private static final int CMD_JUMP_STARTED_TO_RUNNING = 100;
+ private static final int CMD_JUMP_RUNNING_TO_STOPPING = 101;
+ private static final int CMD_JUMP_STOPPING_TO_STOPPED = 102;
+
private static final int MAX_LOG_RECORDS = 500;
private static final int MAX_PACKET_RECORDS = 100;
@@ -1418,6 +1425,9 @@
resetLinkProperties();
if (mStartTimeMillis > 0) {
+ // Completed a life-cycle; send a final empty LinkProperties
+ // (cleared in resetLinkProperties() above) and record an event.
+ mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
mStartTimeMillis = 0;
}
@@ -1476,13 +1486,17 @@
public void enter() {
if (mDhcpClient == null) {
// There's no DHCPv4 for which to wait; proceed to stopped.
- transitionTo(mStoppedState);
+ deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
}
}
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_STOPPING_TO_STOPPED:
+ transitionTo(mStoppedState);
+ break;
+
case CMD_STOP:
break;
@@ -1516,7 +1530,7 @@
}
if (readyToProceed()) {
- transitionTo(mRunningState);
+ deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
} else {
// Clear all IPv4 and IPv6 before proceeding to RunningState.
// Clean up any leftover state from an abnormal exit from
@@ -1533,6 +1547,10 @@
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_STARTED_TO_RUNNING:
+ transitionTo(mRunningState);
+ break;
+
case CMD_STOP:
transitionTo(mStoppingState);
break;
@@ -1561,7 +1579,7 @@
return HANDLED;
}
- boolean readyToProceed() {
+ private boolean readyToProceed() {
return (!mLinkProperties.hasIPv4Address() &&
!mLinkProperties.hasGlobalIPv6Address());
}
@@ -1593,13 +1611,13 @@
if (mConfiguration.mEnableIPv6 && !startIPv6()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
if (mConfiguration.mEnableIPv4 && !startIPv4()) {
doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
@@ -1607,7 +1625,7 @@
if ((config != null) && !applyInitialConfig(config)) {
// TODO introduce a new IpManagerEvent constant to distinguish this error case.
doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
@@ -1621,7 +1639,7 @@
if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
doImmediateProvisioningFailure(
IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
- transitionTo(mStoppingState);
+ enqueueJumpToStoppingState();
return;
}
}
@@ -1658,6 +1676,10 @@
resetLinkProperties();
}
+ private void enqueueJumpToStoppingState() {
+ deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
+ }
+
private ConnectivityPacketTracker createPacketTracker() {
try {
return new ConnectivityPacketTracker(
@@ -1688,6 +1710,7 @@
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
+ case CMD_JUMP_RUNNING_TO_STOPPING:
case CMD_STOP:
transitionTo(mStoppingState);
break;
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 4b827d2..e33ba7e 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;
@@ -100,6 +101,7 @@
}
/** @hide */
+ @TestApi
public CallAudioState(boolean isMuted, @CallAudioRoute int route,
@CallAudioRoute int supportedRouteMask,
@Nullable BluetoothDevice activeBluetoothDevice,
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index d9fdd97..af4d8d7 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -207,23 +207,25 @@
public static final int STATUS_UNKNOWN = 0;
/**
- * Indicates that the file is actively downloading.
+ * Indicates that the file is actively being downloaded.
*/
public static final int STATUS_ACTIVELY_DOWNLOADING = 1;
/**
- * TODO: I don't know...
+ * Indicates that the file is awaiting the next download or repair operations. When a more
+ * precise status is known, the status will change to either {@link #STATUS_PENDING_REPAIR} or
+ * {@link #STATUS_PENDING_DOWNLOAD_WINDOW}.
*/
public static final int STATUS_PENDING_DOWNLOAD = 2;
/**
- * Indicates that the file is being repaired after the download being interrupted.
+ * Indicates that the file is awaiting file repair after the download has ended.
*/
public static final int STATUS_PENDING_REPAIR = 3;
/**
* Indicates that the file is waiting to download because its download window has not yet
- * started.
+ * started and is scheduled for a future time.
*/
public static final int STATUS_PENDING_DOWNLOAD_WINDOW = 4;
@@ -609,6 +611,9 @@
* If the operation encountered an error, the error code will be delivered via
* {@link MbmsDownloadSessionCallback#onError}.
*
+ * Repeated calls to this method for the same {@link DownloadRequest} will replace the
+ * previously registered listener.
+ *
* @param request The {@link DownloadRequest} that you want updates on.
* @param executor The {@link Executor} on which calls to {@code listener } should be executed.
* @param listener The listener that should be called when the middleware has information to
@@ -659,6 +664,9 @@
* If the operation encountered an error, the error code will be delivered via
* {@link MbmsDownloadSessionCallback#onError}.
*
+ * Repeated calls to this method for the same {@link DownloadRequest} will replace the
+ * previously registered listener.
+ *
* @param request The {@link DownloadRequest} provided during registration
* @param listener The listener provided during registration.
*/
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 7d65430..e70e633 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -399,6 +399,160 @@
*/
public static final int CODE_UNOBTAINABLE_NUMBER = 1515;
+ /**
+ * The rejection cause is not known.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_UNKNOWN = 1600;
+
+ /**
+ * Ongoing call, and call waiting is disabled.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601;
+
+ /**
+ * A call is ongoing on another sub.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602;
+
+ /**
+ * CDMA call collision.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_1X_COLLISION = 1603;
+
+ /**
+ * IMS is not registered for service yet.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604;
+
+ /**
+ * The call type is not allowed on the current RAT.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605;
+
+ /**
+ * And emergency call is ongoing.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_E911_CALL = 1606;
+
+ /**
+ * Another call is in the process of being establilshed.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607;
+
+ /**
+ * Maximum number of allowed calls are already in progress.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608;
+
+ /**
+ * Invalid/unsupported SIP headers received.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609;
+
+ /**
+ * Invalid/unsupported SDP headers received.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610;
+
+ /**
+ * A call transfer is in progress.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611;
+
+ /**
+ * An internal error occured while processing the call.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_INTERNAL_ERROR = 1612;
+
+ /**
+ * Call failure due to lack of dedicated bearer.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_QOS_FAILURE = 1613;
+
+ /**
+ * A call handover is in progress.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_HANDOVER = 1614;
+
+ /**
+ * Video calling not supported with TTY.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615;
+
+ /**
+ * A call upgrade is in progress.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616;
+
+ /**
+ * Call from conference server, when TTY mode is ON.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617;
+
+ /**
+ * A conference call is ongoing.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618;
+
+ /**
+ * A video call with AVPF is not supported.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619;
+
+ /**
+ * And encrypted call is ongoing; other calls not supported.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620;
+
+ /**
+ * A CS call is ongoing.
+ * <p>
+ * Used with implicit call rejection.
+ */
+ public static final int CODE_REJECT_ONGOING_CS_CALL = 1621;
+
/* OEM specific error codes. To be used by OEMs when they don't want to
reveal error code which would be replaced by ERROR_UNSPECIFIED */
public static final int CODE_OEM_CAUSE_1 = 0xf001;
diff --git a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
index 904e7ca..7bbe30a 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl
@@ -18,6 +18,9 @@
import android.os.Bundle;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
+
import com.android.ims.internal.IImsCallSession;
/**
@@ -26,5 +29,6 @@
*/
oneway interface IImsMmTelListener {
void onIncomingCall(IImsCallSession c, in Bundle extras);
+ void onRejectedCall(in ImsCallProfile callProfile, in ImsReasonInfo reason);
void onVoiceMessageCountUpdate(int count);
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index aaf1a1cf8..f12540f 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -36,6 +36,7 @@
import android.util.Log;
import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsMultiEndpoint;
@@ -326,6 +327,16 @@
}
/**
+ * Called when the IMS provider implicitly rejects an incoming call during setup.
+ * @param callProfile An {@link ImsCallProfile} with the call details.
+ * @param reason The {@link ImsReasonInfo} reason for call rejection.
+ */
+ @Override
+ public void onRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
+
+ }
+
+ /**
* Updates the Listener when the voice message count for IMS has changed.
* @param count an integer representing the new message count.
*/
@@ -429,6 +440,26 @@
}
/**
+ * Notify the framework that a call has been implicitly rejected by this MmTelFeature
+ * during call setup.
+ * @param callProfile The {@link ImsCallProfile} IMS call profile with details.
+ * This can be null if no call information is available for the rejected call.
+ * @param reason The {@link ImsReasonInfo} call rejection reason.
+ */
+ public final void notifyRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
+ synchronized (mLock) {
+ if (mListener == null) {
+ throw new IllegalStateException("Session is not available.");
+ }
+ try {
+ mListener.onRejectedCall(callProfile, reason);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
*
* @hide
*/
diff --git a/tests/ActivityTests/Android.mk b/tests/ActivityTests/Android.mk
index 61dbcc3..4c68c8b 100644
--- a/tests/ActivityTests/Android.mk
+++ b/tests/ActivityTests/Android.mk
@@ -9,9 +9,10 @@
LOCAL_MODULE_TAGS := tests
LOCAL_CERTIFICATE := platform
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# frameworks/base/tests/ActivityTests/AndroidManifest.xml:42: error: unexpected element <preferred> found in <manifest><application><activity>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index e682f79..b3a82f5 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -32,6 +32,8 @@
# These are not normally accessible from apps so they must be explicitly included.
LOCAL_JNI_SHARED_LIBRARIES := \
android.hidl.token@1.0 \
+ $(UBSAN_RUNTIME_LIBRARY) \
+ libartbase \
libbacktrace \
libbase \
libbinder \
@@ -57,7 +59,9 @@
libvndksupport \
libtinyxml2 \
libunwindstack \
- libutilscallstack
+ libutilscallstack \
+ libziparchive \
+ libz
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/tests/net/java/android/net/ip/IpClientTest.java b/tests/net/java/android/net/ip/IpClientTest.java
index e9e880d..89453e0 100644
--- a/tests/net/java/android/net/ip/IpClientTest.java
+++ b/tests/net/java/android/net/ip/IpClientTest.java
@@ -133,9 +133,18 @@
verify(mNMService, times(1)).registerObserver(arg.capture());
mObserver = arg.getValue();
reset(mNMService);
+ // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
+ verify(mCb, never()).onLinkPropertiesChange(any());
+ reset(mCb);
return ipc;
}
+ private static LinkProperties makeEmptyLinkProperties(String iface) {
+ final LinkProperties empty = new LinkProperties();
+ empty.setInterfaceName(iface);
+ return empty;
+ }
+
@Test
public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
setTestInterfaceParams(null);
@@ -197,6 +206,8 @@
ipc.shutdown();
verify(mNMService, timeout(100).times(1)).disableIpv6(iface);
verify(mNMService, timeout(100).times(1)).clearInterfaceAddresses(iface);
+ verify(mCb, timeout(100).times(1))
+ .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface)));
}
@Test
@@ -246,6 +257,8 @@
ipc.shutdown();
verify(mNMService, timeout(100).times(1)).disableIpv6(iface);
verify(mNMService, timeout(100).times(1)).clearInterfaceAddresses(iface);
+ verify(mCb, timeout(100).times(1))
+ .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface)));
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index d241b32..9994cdd 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -779,11 +779,12 @@
sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED);
mLooper.dispatchAll();
- // We verify get/set called twice here: once for setup and once during
+ // We verify get/set called thrice here: once for setup and twice during
// teardown because all events happen over the course of the single
- // dispatchAll() above.
+ // dispatchAll() above. Note that once the TISM IPv4 address config
+ // code is refactored the two calls during shutdown will revert to one.
verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME);
- verify(mNMService, times(2))
+ verify(mNMService, times(3))
.setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class));
verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME);
verify(mWifiManager).updateInterfaceIpState(
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index 7c77cf5..19d3a2e 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -173,6 +173,7 @@
dispatchCommand(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
InOrder inOrder = inOrder(mNMService, mStatsService, mTetherHelper);
inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
+ inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any());
inOrder.verify(mTetherHelper).updateInterfaceState(
mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
inOrder.verify(mTetherHelper).updateLinkProperties(
@@ -270,6 +271,7 @@
inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE);
inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE);
inOrder.verify(mNMService).untetherInterface(IFACE_NAME);
+ inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any());
inOrder.verify(mTetherHelper).updateInterfaceState(
mTestedSm, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR);
inOrder.verify(mTetherHelper).updateLinkProperties(
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 036bf5d8..3a312b0 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1923,6 +1923,12 @@
.OptionalFlag("--version-name",
"Version name to inject into the AndroidManifest.xml if none is present.",
&options.manifest_fixer_options.version_name_default)
+ .OptionalSwitch("--replace-version",
+ "If --version-code and/or --version-name are specified, these\n"
+ "values will replace any value already in the manifest. By\n"
+ "default, nothing is changed if the manifest already defines\n"
+ "these attributes.",
+ &options.manifest_fixer_options.replace_version)
.OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",
&shared_lib)
.OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib)
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index e6271eb..ca7b653 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -237,6 +237,9 @@
manifest_action.Action(FixCoreAppAttribute);
manifest_action.Action([&](xml::Element* el) -> bool {
if (options_.version_name_default) {
+ if (options_.replace_version) {
+ el->RemoveAttribute(xml::kSchemaAndroid, "versionName");
+ }
if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
el->attributes.push_back(
xml::Attribute{xml::kSchemaAndroid, "versionName",
@@ -245,6 +248,9 @@
}
if (options_.version_code_default) {
+ if (options_.replace_version) {
+ el->RemoveAttribute(xml::kSchemaAndroid, "versionCode");
+ }
if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
el->attributes.push_back(
xml::Attribute{xml::kSchemaAndroid, "versionCode",
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index dbabab17..d7a5931 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -33,13 +33,22 @@
Maybe<std::string> target_sdk_version_default;
Maybe<std::string> rename_manifest_package;
Maybe<std::string> rename_instrumentation_target_package;
+
+ // The version name to set if 'android:versionName' is not defined in <manifest> or if
+ // replace_version is set.
Maybe<std::string> version_name_default;
+
+ // The version code to set if 'android:versionCode' is not defined in <manifest> or if
+ // replace_version is set.
Maybe<std::string> version_code_default;
// Wether validation errors should be treated only as warnings. If this is 'true', then an
// incorrect node will not result in an error, but only as a warning, and the parsing will
// continue.
bool warn_validation = false;
+
+ // Whether to replace the manifest version with the the command line version
+ bool replace_version = false;
};
/**
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 84e367d..e6410c9 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -21,6 +21,7 @@
using ::android::StringPiece;
using ::testing::IsNull;
using ::testing::NotNull;
+using ::testing::StrEq;
namespace aapt {
@@ -339,6 +340,136 @@
EXPECT_EQ(std::string("0x10000000"), attr->value);
}
+TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) {
+ManifestFixerOptions options;
+options.version_name_default = std::string("Beta");
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_name_default = std::string("Beta");
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Beta"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionName) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_name_default = std::string("Beta");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Beta"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
+TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
EXPECT_EQ(nullptr,
Verify("<manifest package=\"android\" coreApp=\"hello\" />"));
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 1d122db..22767781 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -394,6 +394,15 @@
return nullptr;
}
+void Element::RemoveAttribute(const StringPiece& ns, const StringPiece& name) {
+ auto new_attr_end = std::remove_if(attributes.begin(), attributes.end(),
+ [&](const Attribute& attr) -> bool {
+ return ns == attr.namespace_uri && name == attr.name;
+ });
+
+ attributes.erase(new_attr_end, attributes.end());
+}
+
Element* Element::FindChild(const StringPiece& ns, const StringPiece& name) {
return FindChildWithAttribute(ns, name, {}, {}, {});
}
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 1542243..995cdb24 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -98,6 +98,9 @@
Attribute* FindAttribute(const android::StringPiece& ns, const android::StringPiece& name);
const Attribute* FindAttribute(const android::StringPiece& ns,
const android::StringPiece& name) const;
+ void RemoveAttribute(const android::StringPiece& ns,
+ const android::StringPiece& name);
+
Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name);
Element* FindChildWithAttribute(const android::StringPiece& ns, const android::StringPiece& name,
const android::StringPiece& attr_ns,