Merge "Move ApplicationInfo to params in AppComponentFactory"
diff --git a/api/current.txt b/api/current.txt
index 7bb8e89..288a8a0 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -43071,7 +43071,7 @@
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getSubscriberId();
method public String getTypeAllocationCode();
method public String getTypeAllocationCode(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
+ method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @NonNull public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVisualVoicemailPackageName();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailAlphaTag();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber();
@@ -43240,8 +43240,8 @@
public final class UiccCardInfo implements android.os.Parcelable {
method public int describeContents();
method public int getCardId();
- method public String getEid();
- method public String getIccId();
+ method @Nullable public String getEid();
+ method @Nullable public String getIccId();
method public int getSlotIndex();
method public boolean isEuicc();
method public boolean isRemovable();
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 92b30a4..24a907b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -3668,7 +3668,8 @@
/**
* Registers to receive notifications about all networks which satisfy the given
* {@link NetworkRequest}. The callbacks will continue to be called until
- * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
+ * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is
+ * called.
*
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The {@link NetworkCallback} that the system will call as suitable
@@ -3684,7 +3685,8 @@
/**
* Registers to receive notifications about all networks which satisfy the given
* {@link NetworkRequest}. The callbacks will continue to be called until
- * either the application exits or link #unregisterNetworkCallback(NetworkCallback)} is called.
+ * either the application exits or {@link #unregisterNetworkCallback(NetworkCallback)} is
+ * called.
*
* @param request {@link NetworkRequest} describing this request.
* @param networkCallback The {@link NetworkCallback} that the system will call as suitable
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index 0894ee5..2a43238 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -17,7 +17,9 @@
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.captiveportallogin" >
+ package="com.android.captiveportallogin"
+ android:versionCode="10"
+ android:versionName="Q-initial">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 52c209e..90521de 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -18,7 +18,9 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack"
- android:sharedUserId="android.uid.networkstack">
+ android:sharedUserId="android.uid.networkstack"
+ android:versionCode="10"
+ android:versionName="Q-initial">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkStackPermissionStub/AndroidManifest.xml
index a8742d7..ba8a178 100644
--- a/packages/NetworkStackPermissionStub/AndroidManifest.xml
+++ b/packages/NetworkStackPermissionStub/AndroidManifest.xml
@@ -18,7 +18,9 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack.permissionstub"
- android:sharedUserId="android.uid.networkstack">
+ android:sharedUserId="android.uid.networkstack"
+ android:versionCode="10"
+ android:versionName="Q-initial">
<!--
This package only exists to define the below permissions, and enforce that they are only
granted to apps sharing the same signature.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b8184d9..29a305e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3203,6 +3203,7 @@
* the caller does not have adequate permissions for that card.
*/
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @NonNull
public List<UiccCardInfo> getUiccCardsInfo() {
try {
ITelephony telephony = getITelephony();
diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java
index 0192ffb..d95a499 100644
--- a/telephony/java/android/telephony/UiccCardInfo.java
+++ b/telephony/java/android/telephony/UiccCardInfo.java
@@ -15,6 +15,8 @@
*/
package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -104,6 +106,7 @@
* Note that this field may be omitted if the caller does not have the correct permissions
* (see {@link TelephonyManager#getUiccCardsInfo()}).
*/
+ @Nullable
public String getEid() {
if (!mIsEuicc) {
return null;
@@ -117,6 +120,7 @@
* Note that this field may be omitted if the caller does not have the correct permissions
* (see {@link TelephonyManager#getUiccCardsInfo()}).
*/
+ @Nullable
public String getIccId() {
return mIccId;
}
@@ -129,11 +133,12 @@
}
/**
- * Returns a copy of the UiccCardinfo with the clears the EID and ICCID set to null. These
- * values are generally private and require carrier privileges to view.
+ * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
+ * generally private and require carrier privileges to view.
*
* @hide
*/
+ @NonNull
public UiccCardInfo getUnprivileged() {
return new UiccCardInfo(mIsEuicc, mCardId, null, null, mSlotIndex, mIsRemovable);
}
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index ef405e4..295e3de 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -79,6 +79,7 @@
self.value = raw[3].strip(';"')
else:
self.value = None
+ self.annotations = []
self.ident = "-".join((self.typ, self.name, self.value or ""))
@@ -88,6 +89,18 @@
def __repr__(self):
return self.raw
+
+class Argument(object):
+
+ __slots__ = ["type", "annotations", "name", "default"]
+
+ def __init__(self, type):
+ self.type = type
+ self.annotations = []
+ self.name = None
+ self.default = None
+
+
class Method():
def __init__(self, clazz, line, raw, blame, sig_format = 1):
self.clazz = clazz
@@ -118,21 +131,24 @@
self.name = raw[1]
# parse args
- self.args = []
+ self.detailed_args = []
for arg in re.split(",\s*", raw_args):
arg = re.split("\s", arg)
# ignore annotations for now
arg = [ a for a in arg if not a.startswith("@") ]
if len(arg[0]) > 0:
- self.args.append(arg[0])
+ self.detailed_args.append(Argument(arg[0]))
# parse throws
self.throws = []
for throw in re.split(",\s*", raw_throws):
self.throws.append(throw)
+
+ self.annotations = []
else:
raise ValueError("Unknown signature format: " + sig_format)
+ self.args = map(lambda a: a.type, self.detailed_args)
self.ident = "-".join((self.typ, self.name, "-".join(self.args)))
def sig_matches(self, typ, name, args):
@@ -312,10 +328,10 @@
method.split = []
kind = self.parse_one_of("ctor", "method")
method.split.append(kind)
- annotations = self.parse_annotations()
+ method.annotations = self.parse_annotations()
method.split.extend(self.parse_modifiers())
self.parse_matching_paren("<", ">")
- if "@Deprecated" in annotations:
+ if "@Deprecated" in method.annotations:
method.split.append("deprecated")
if kind == "ctor":
method.typ = "ctor"
@@ -325,7 +341,7 @@
method.name = self.parse_name()
method.split.append(method.name)
self.parse_token("(")
- method.args = self.parse_args()
+ method.detailed_args = self.parse_args()
self.parse_token(")")
method.throws = self.parse_throws()
if "@interface" in method.clazz.split:
@@ -360,8 +376,8 @@
def parse_into_field(self, field):
kind = self.parse_one_of(*V2LineParser.FIELD_KINDS)
field.split = [kind]
- annotations = self.parse_annotations()
- if "@Deprecated" in annotations:
+ field.annotations = self.parse_annotations()
+ if "@Deprecated" in field.annotations:
field.split.append("deprecated")
field.split.extend(self.parse_modifiers())
field.typ = self.parse_type()
@@ -488,15 +504,16 @@
def parse_arg(self):
self.parse_if("vararg") # kotlin vararg
- self.parse_annotations()
- type = self.parse_arg_type()
+ annotations = self.parse_annotations()
+ arg = Argument(self.parse_arg_type())
+ arg.annotations = annotations
l = self.lookahead()
if l != "," and l != ")":
if self.lookahead() != '=':
- self.parse_token() # kotlin argument name
+ arg.name = self.parse_token() # kotlin argument name
if self.parse_if('='): # kotlin default value
- self.parse_expression()
- return type
+ arg.default = self.parse_expression()
+ return arg
def parse_expression(self):
while not self.lookahead() in [')', ',', ';']:
@@ -593,7 +610,7 @@
blame = None
sig_format = 1
- re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
+ re_blame = re.compile(r"^(\^?[a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
field_prefixes = map(lambda kind: " %s" % (kind,), V2LineParser.FIELD_KINDS)
def startsWithFieldPrefix(raw):
@@ -608,11 +625,13 @@
match = re_blame.match(raw)
if match is not None:
blame = match.groups()[0:2]
+ if blame[0].startswith("^"): # Outside of blame range
+ blame = None
raw = match.groups()[2]
else:
blame = None
- if line == 1 and raw.startswith("// Signature format: "):
+ if line == 1 and V2Tokenizer.SIGNATURE_PREFIX in raw:
sig_format_string = raw[len(V2Tokenizer.SIGNATURE_PREFIX):]
if sig_format_string in ["2.0", "3.0"]:
sig_format = 2
@@ -1871,6 +1890,35 @@
if arg in discouraged:
warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
+PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}
+
+def verify_nullability(clazz):
+ """Catches missing nullability annotations"""
+
+ for f in clazz.fields:
+ if f.value is not None and 'static' in f.split and 'final' in f.split:
+ continue # Nullability of constants can be inferred.
+ if f.typ not in PRIMITIVES and not has_nullability(f.annotations):
+ error(clazz, f, "M12", "Field must be marked either @NonNull or @Nullable")
+
+ for c in clazz.ctors:
+ verify_nullability_args(clazz, c)
+
+ for m in clazz.methods:
+ if m.name == "writeToParcel" or m.name == "onReceive":
+ continue # Parcelable.writeToParcel() and BroadcastReceiver.onReceive() are not yet annotated
+
+ if m.typ not in PRIMITIVES and not has_nullability(m.annotations):
+ error(clazz, m, "M12", "Return value must be marked either @NonNull or @Nullable")
+ verify_nullability_args(clazz, m)
+
+def verify_nullability_args(clazz, m):
+ for i, arg in enumerate(m.detailed_args):
+ if arg.type not in PRIMITIVES and not has_nullability(arg.annotations):
+ error(clazz, m, "M12", "Argument %d must be marked either @NonNull or @Nullable" % (i+1,))
+
+def has_nullability(annotations):
+ return "@NonNull" in annotations or "@Nullable" in annotations
def verify_singleton(clazz):
"""Catch singleton objects with constructors."""
@@ -1959,6 +2007,7 @@
verify_pfd(clazz)
verify_numbers(clazz)
verify_singleton(clazz)
+ verify_nullability(clazz)
def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
index c10ef15..f34492d 100644
--- a/tools/apilint/apilint_test.py
+++ b/tools/apilint/apilint_test.py
@@ -88,20 +88,22 @@
faulty_current_txt = """
+// Signature format: 2.0
package android.app {
public final class Activity {
}
public final class WallpaperColors implements android.os.Parcelable {
- ctor public WallpaperColors(android.os.Parcel);
+ ctor public WallpaperColors(@NonNull android.os.Parcel);
method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
}
}
-""".split('\n')
+""".strip().split('\n')
ok_current_txt = """
+// Signature format: 2.0
package android.app {
public final class Activity {
}
@@ -109,19 +111,20 @@
public final class WallpaperColors implements android.os.Parcelable {
ctor public WallpaperColors();
method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
}
}
-""".split('\n')
+""".strip().split('\n')
system_current_txt = """
+// Signature format: 2.0
package android.app {
public final class WallpaperColors implements android.os.Parcelable {
method public int getSomething();
}
}
-""".split('\n')
+""".strip().split('\n')