Merge "Revert "Refine documentation for Process.setThreadPriority""
diff --git a/ApiDocs.bp b/ApiDocs.bp
index ca921ff..d630209 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -65,7 +65,7 @@
"test-base/src/**/*.java",
":opt-telephony-srcs",
":opt-net-voip-srcs",
- ":art-module-public-api-stubs-source",
+ ":art.module.public.api{.public.stubs.source}",
":conscrypt.module.public.api{.public.stubs.source}",
":android_icu4j_public_api_files",
"test-mock/src/**/*.java",
@@ -131,7 +131,7 @@
],
knowntags: [
"docs/knowntags.txt",
- ":known-oj-tags",
+ ":art.module.public.api{.doctags}",
],
custom_template: "droiddoc-templates-sdk",
resourcesdir: "docs/html/reference/images/",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 4b0df44..9e087f0 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -47,7 +47,7 @@
"core/java/**/*.logtags",
":opt-telephony-srcs",
":opt-net-voip-srcs",
- ":art-module-public-api-stubs-source",
+ ":art.module.public.api{.public.stubs.source}",
":android_icu4j_public_api_files",
"**/package.html",
],
diff --git a/apex/media/OWNERS b/apex/media/OWNERS
index 9b853c5..ced2fb5 100644
--- a/apex/media/OWNERS
+++ b/apex/media/OWNERS
@@ -1,4 +1,10 @@
andrewlewis@google.com
aquilescanta@google.com
+chz@google.com
+hdmoon@google.com
+hkuang@google.com
+jinpark@google.com
+klhyun@google.com
+lnilsson@google.com
marcone@google.com
sungsoo@google.com
diff --git a/api/current.txt b/api/current.txt
index 167c2b4..e16876e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8771,6 +8771,7 @@
method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
+ method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
}
@@ -36463,7 +36464,7 @@
method public int dataCapacity();
method public int dataPosition();
method public int dataSize();
- method public void enforceInterface(String);
+ method public void enforceInterface(@NonNull String);
method public boolean hasFileDescriptors();
method public byte[] marshall();
method @NonNull public static android.os.Parcel obtain();
@@ -36534,7 +36535,7 @@
method public void writeFloatArray(@Nullable float[]);
method public void writeInt(int);
method public void writeIntArray(@Nullable int[]);
- method public void writeInterfaceToken(String);
+ method public void writeInterfaceToken(@NonNull String);
method public void writeList(@Nullable java.util.List);
method public void writeLong(long);
method public void writeLongArray(@Nullable long[]);
@@ -46944,7 +46945,7 @@
method public long getNci();
method @IntRange(from=0, to=3279165) public int getNrarfcn();
method @IntRange(from=0, to=1007) public int getPci();
- method @IntRange(from=0, to=65535) public int getTac();
+ method @IntRange(from=0, to=16777215) public int getTac();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
}
@@ -47038,9 +47039,9 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR;
}
- public abstract class CellLocation {
- ctor public CellLocation();
- method public static android.telephony.CellLocation getEmpty();
+ @Deprecated public abstract class CellLocation {
+ ctor @Deprecated public CellLocation();
+ method @Deprecated public static android.telephony.CellLocation getEmpty();
method @Deprecated public static void requestLocationUpdate();
}
@@ -48548,19 +48549,19 @@
package android.telephony.cdma {
- public class CdmaCellLocation extends android.telephony.CellLocation {
- ctor public CdmaCellLocation();
- ctor public CdmaCellLocation(android.os.Bundle);
- method public static double convertQuartSecToDecDegrees(int);
- method public void fillInNotifierBundle(android.os.Bundle);
- method public int getBaseStationId();
- method public int getBaseStationLatitude();
- method public int getBaseStationLongitude();
- method public int getNetworkId();
- method public int getSystemId();
- method public void setCellLocationData(int, int, int);
- method public void setCellLocationData(int, int, int, int, int);
- method public void setStateInvalid();
+ @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation {
+ ctor @Deprecated public CdmaCellLocation();
+ ctor @Deprecated public CdmaCellLocation(android.os.Bundle);
+ method @Deprecated public static double convertQuartSecToDecDegrees(int);
+ method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+ method @Deprecated public int getBaseStationId();
+ method @Deprecated public int getBaseStationLatitude();
+ method @Deprecated public int getBaseStationLongitude();
+ method @Deprecated public int getNetworkId();
+ method @Deprecated public int getSystemId();
+ method @Deprecated public void setCellLocationData(int, int, int);
+ method @Deprecated public void setCellLocationData(int, int, int, int, int);
+ method @Deprecated public void setStateInvalid();
}
}
@@ -48760,15 +48761,15 @@
package android.telephony.gsm {
- public class GsmCellLocation extends android.telephony.CellLocation {
- ctor public GsmCellLocation();
- ctor public GsmCellLocation(android.os.Bundle);
- method public void fillInNotifierBundle(android.os.Bundle);
- method public int getCid();
- method public int getLac();
- method public int getPsc();
- method public void setLacAndCid(int, int);
- method public void setStateInvalid();
+ @Deprecated public class GsmCellLocation extends android.telephony.CellLocation {
+ ctor @Deprecated public GsmCellLocation();
+ ctor @Deprecated public GsmCellLocation(android.os.Bundle);
+ method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+ method @Deprecated public int getCid();
+ method @Deprecated public int getLac();
+ method @Deprecated public int getPsc();
+ method @Deprecated public void setLacAndCid(int, int);
+ method @Deprecated public void setStateInvalid();
}
@Deprecated public final class SmsManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index 6d13582..ddf9c4d9 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -11188,6 +11188,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 9f6b828..1c40cff 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.annotation.NonNull;
+
/**
* This abstract class is used to implement {@link BluetoothGatt} callbacks.
*/
@@ -203,8 +205,7 @@
* called to re-discover the services.
*
* @param gatt GATT client involved
- * @hide
*/
- public void onServiceChanged(BluetoothGatt gatt) {
+ public void onServiceChanged(@NonNull BluetoothGatt gatt) {
}
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index f257326..2138f53 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -785,4 +785,6 @@
List<String> getMimeGroup(String packageName, String group);
boolean isAutoRevokeWhitelisted(String packageName);
+
+ void grantImplicitAccess(int queryingUid, String visibleAuthority);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 46af630..0789cfb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8018,6 +8018,20 @@
"getMimeGroup not implemented in subclass");
}
+ /**
+ * Grants implicit visibility of the package that provides an authority to a querying UID.
+ *
+ * @throws SecurityException when called by a package other than the contacts provider
+ * @hide
+ */
+ public void grantImplicitAccess(int queryingUid, String visibleAuthority) {
+ try {
+ ActivityThread.getPackageManager().grantImplicitAccess(queryingUid, visibleAuthority);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
// Some of the flags don't affect the query result, but let's be conservative and cache
// each combination of flags separately.
diff --git a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
index 27f8a61..7b6a457 100644
--- a/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
+++ b/core/java/android/hardware/camera2/impl/FrameNumberTracker.java
@@ -37,12 +37,16 @@
/** the completed frame number for each type of capture results */
private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
- /** the skipped frame numbers that don't belong to each type of capture results */
- private final LinkedList<Long>[] mSkippedOtherFrameNumbers =
+ /** the frame numbers that don't belong to each type of capture results and are yet to be seen
+ * through an updateTracker() call. Each list holds a list of frame numbers that should appear
+ * with request types other than that, to which the list corresponds.
+ */
+ private final LinkedList<Long>[] mPendingFrameNumbersWithOtherType =
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
- /** the skipped frame numbers that belong to each type of capture results */
- private final LinkedList<Long>[] mSkippedFrameNumbers =
+ /** the frame numbers that belong to each type of capture results which should appear, but
+ * haven't yet.*/
+ private final LinkedList<Long>[] mPendingFrameNumbers =
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
/** frame number -> request type */
@@ -53,8 +57,8 @@
public FrameNumberTracker() {
for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
- mSkippedOtherFrameNumbers[i] = new LinkedList<Long>();
- mSkippedFrameNumbers[i] = new LinkedList<Long>();
+ mPendingFrameNumbersWithOtherType[i] = new LinkedList<Long>();
+ mPendingFrameNumbers[i] = new LinkedList<Long>();
}
}
@@ -66,29 +70,29 @@
int requestType = (int) pair.getValue();
Boolean removeError = false;
if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
removeError = true;
+ }
+ // The error frame number could have also either been in the pending list or one of the
+ // 'other' pending lists.
+ if (!mPendingFrameNumbers[requestType].isEmpty()) {
+ if (errorFrameNumber == mPendingFrameNumbers[requestType].element()) {
+ mPendingFrameNumbers[requestType].remove();
+ removeError = true;
+ }
} else {
- if (!mSkippedFrameNumbers[requestType].isEmpty()) {
- if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
- mSkippedFrameNumbers[requestType].remove();
+ for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
+ int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
+ if (!mPendingFrameNumbersWithOtherType[otherType].isEmpty() && errorFrameNumber
+ == mPendingFrameNumbersWithOtherType[otherType].element()) {
+ mPendingFrameNumbersWithOtherType[otherType].remove();
removeError = true;
- }
- } else {
- for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
- int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
- if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber
- == mSkippedOtherFrameNumbers[otherType].element()) {
- mCompletedFrameNumber[requestType] = errorFrameNumber;
- mSkippedOtherFrameNumbers[otherType].remove();
- removeError = true;
- break;
- }
+ break;
}
}
}
if (removeError) {
+ mCompletedFrameNumber[requestType] = errorFrameNumber;
+ mPartialResults.remove(errorFrameNumber);
iter.remove();
}
}
@@ -182,7 +186,7 @@
* It validates that all previous frames of the same category have arrived.
*
* If there is a gap since previous frame number of the same category, assume the frames in
- * the gap are other categories and store them in the skipped frame number queue to check
+ * the gap are other categories and store them in the pending frame number queue to check
* against when frames of those categories arrive.
*/
private void updateCompletedFrameNumber(long frameNumber,
@@ -199,25 +203,29 @@
if (frameNumber < maxOtherFrameNumberSeen) {
// if frame number is smaller than completed frame numbers of other categories,
// it must be:
- // - the head of mSkippedFrameNumbers for this category, or
- // - in one of other mSkippedOtherFrameNumbers
- if (!mSkippedFrameNumbers[requestType].isEmpty()) {
- // frame number must be head of current type of mSkippedFrameNumbers if
- // mSkippedFrameNumbers isn't empty.
- if (frameNumber < mSkippedFrameNumbers[requestType].element()) {
+ // - the head of mPendingFrameNumbers for this category, or
+ // - in one of other mPendingFrameNumbersWithOtherType
+ if (!mPendingFrameNumbers[requestType].isEmpty()) {
+ // frame number must be head of current type of mPendingFrameNumbers if
+ // mPendingFrameNumbers isn't empty.
+ Long pendingFrameNumberSameType = mPendingFrameNumbers[requestType].element();
+ if (frameNumber == pendingFrameNumberSameType) {
+ // frame number matches the head of the pending frame number queue.
+ // Do this before the inequality checks since this is likely to be the common
+ // case.
+ mPendingFrameNumbers[requestType].remove();
+ } else if (frameNumber < pendingFrameNumberSameType) {
throw new IllegalArgumentException("frame number " + frameNumber
+ " is a repeat");
- } else if (frameNumber > mSkippedFrameNumbers[requestType].element()) {
+ } else {
throw new IllegalArgumentException("frame number " + frameNumber
+ " comes out of order. Expecting "
- + mSkippedFrameNumbers[requestType].element());
+ + pendingFrameNumberSameType);
}
- // frame number matches the head of the skipped frame number queue.
- mSkippedFrameNumbers[requestType].remove();
} else {
- // frame number must be in one of the other mSkippedOtherFrameNumbers.
- int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber);
- int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber);
+ // frame number must be in one of the other mPendingFrameNumbersWithOtherType.
+ int index1 = mPendingFrameNumbersWithOtherType[otherType1].indexOf(frameNumber);
+ int index2 = mPendingFrameNumbersWithOtherType[otherType2].indexOf(frameNumber);
boolean inSkippedOther1 = index1 != -1;
boolean inSkippedOther2 = index2 != -1;
if (!(inSkippedOther1 ^ inSkippedOther2)) {
@@ -225,33 +233,39 @@
+ " is a repeat or invalid");
}
- // We know the category of frame numbers in skippedOtherFrameNumbers leading up
- // to the current frame number. Move them into the correct skippedFrameNumbers.
+ // We know the category of frame numbers in pendingFrameNumbersWithOtherType leading
+ // up to the current frame number. The destination is the type which isn't the
+ // requestType* and isn't the src. Move them into the correct pendingFrameNumbers.
+ // * : This is since frameNumber is the first frame of requestType that we've
+ // received in the 'others' list, since for each request type frames come in order.
+ // All the frames before frameNumber are of the same type. They're not of
+ // 'requestType', neither of the type of the 'others' list they were found in. The
+ // remaining option is the 3rd type.
LinkedList<Long> srcList, dstList;
int index;
if (inSkippedOther1) {
- srcList = mSkippedOtherFrameNumbers[otherType1];
- dstList = mSkippedFrameNumbers[otherType2];
+ srcList = mPendingFrameNumbersWithOtherType[otherType1];
+ dstList = mPendingFrameNumbers[otherType2];
index = index1;
} else {
- srcList = mSkippedOtherFrameNumbers[otherType2];
- dstList = mSkippedFrameNumbers[otherType1];
+ srcList = mPendingFrameNumbersWithOtherType[otherType2];
+ dstList = mPendingFrameNumbers[otherType1];
index = index2;
}
for (int i = 0; i < index; i++) {
dstList.add(srcList.removeFirst());
}
- // Remove current frame number from skippedOtherFrameNumbers
+ // Remove current frame number from pendingFrameNumbersWithOtherType
srcList.remove();
}
} else {
// there is a gap of unseen frame numbers which should belong to the other
- // 2 categories. Put all the skipped frame numbers in the queue.
+ // 2 categories. Put all the pending frame numbers in the queue.
for (long i =
Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
i < frameNumber; i++) {
- mSkippedOtherFrameNumbers[requestType].add(i);
+ mPendingFrameNumbersWithOtherType[requestType].add(i);
}
}
diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java
index 21fd819..ab5637c 100644
--- a/core/java/android/os/FileBridge.java
+++ b/core/java/android/os/FileBridge.java
@@ -16,7 +16,6 @@
package android.os;
-import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SOCK_STREAM;
import android.system.ErrnoException;
@@ -58,17 +57,19 @@
/** CMD_CLOSE */
private static final int CMD_CLOSE = 3;
- private FileDescriptor mTarget;
+ private ParcelFileDescriptor mTarget;
- private final FileDescriptor mServer = new FileDescriptor();
- private final FileDescriptor mClient = new FileDescriptor();
+ private ParcelFileDescriptor mServer;
+ private ParcelFileDescriptor mClient;
private volatile boolean mClosed;
public FileBridge() {
try {
- Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mServer, mClient);
- } catch (ErrnoException e) {
+ ParcelFileDescriptor[] fds = ParcelFileDescriptor.createSocketPair(SOCK_STREAM);
+ mServer = fds[0];
+ mClient = fds[1];
+ } catch (IOException e) {
throw new RuntimeException("Failed to create bridge");
}
}
@@ -80,15 +81,14 @@
public void forceClose() {
IoUtils.closeQuietly(mTarget);
IoUtils.closeQuietly(mServer);
- IoUtils.closeQuietly(mClient);
mClosed = true;
}
- public void setTargetFile(FileDescriptor target) {
+ public void setTargetFile(ParcelFileDescriptor target) {
mTarget = target;
}
- public FileDescriptor getClientSocket() {
+ public ParcelFileDescriptor getClientSocket() {
return mClient;
}
@@ -96,32 +96,33 @@
public void run() {
final byte[] temp = new byte[8192];
try {
- while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) {
+ while (IoBridge.read(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH) == MSG_LENGTH) {
final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN);
if (cmd == CMD_WRITE) {
// Shuttle data into local file
int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN);
while (len > 0) {
- int n = IoBridge.read(mServer, temp, 0, Math.min(temp.length, len));
+ int n = IoBridge.read(mServer.getFileDescriptor(), temp, 0,
+ Math.min(temp.length, len));
if (n == -1) {
throw new IOException(
"Unexpected EOF; still expected " + len + " bytes");
}
- IoBridge.write(mTarget, temp, 0, n);
+ IoBridge.write(mTarget.getFileDescriptor(), temp, 0, n);
len -= n;
}
} else if (cmd == CMD_FSYNC) {
// Sync and echo back to confirm
- Os.fsync(mTarget);
- IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+ Os.fsync(mTarget.getFileDescriptor());
+ IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH);
} else if (cmd == CMD_CLOSE) {
// Close and echo back to confirm
- Os.fsync(mTarget);
- Os.close(mTarget);
+ Os.fsync(mTarget.getFileDescriptor());
+ mTarget.close();
mClosed = true;
- IoBridge.write(mServer, temp, 0, MSG_LENGTH);
+ IoBridge.write(mServer.getFileDescriptor(), temp, 0, MSG_LENGTH);
break;
}
}
@@ -143,17 +144,11 @@
mClient = clientPfd.getFileDescriptor();
}
- public FileBridgeOutputStream(FileDescriptor client) {
- mClientPfd = null;
- mClient = client;
- }
-
@Override
public void close() throws IOException {
try {
writeCommandAndBlock(CMD_CLOSE, "close()");
} finally {
- IoBridge.closeAndSignalBlockedThreads(mClient);
IoUtils.closeQuietly(mClientPfd);
}
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 7b82b1a..fe70a88 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -642,11 +642,11 @@
* {@link #dataPosition}. This is used to validate that the marshalled
* transaction is intended for the target interface.
*/
- public final void writeInterfaceToken(String interfaceName) {
+ public final void writeInterfaceToken(@NonNull String interfaceName) {
nativeWriteInterfaceToken(mNativePtr, interfaceName);
}
- public final void enforceInterface(String interfaceName) {
+ public final void enforceInterface(@NonNull String interfaceName) {
nativeEnforceInterface(mNativePtr, interfaceName);
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 095882e..60f1b44 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -36,7 +36,6 @@
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.RuntimeHooks;
-import dalvik.system.ThreadPrioritySetter;
import dalvik.system.VMRuntime;
import libcore.content.type.MimeMap;
@@ -208,7 +207,6 @@
*/
public static void preForkInit() {
if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
- RuntimeHooks.setThreadPrioritySetter(new RuntimeThreadPrioritySetter());
RuntimeInit.enableDdms();
// TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
// MimeMap.setDefault(DefaultMimeMapFactory.create());
@@ -221,35 +219,6 @@
MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
}
- private static class RuntimeThreadPrioritySetter implements ThreadPrioritySetter {
- // Should remain consistent with kNiceValues[] in system/libartpalette/palette_android.cc
- private static final int[] NICE_VALUES = {
- Process.THREAD_PRIORITY_LOWEST, // 1 (MIN_PRIORITY)
- Process.THREAD_PRIORITY_BACKGROUND + 6,
- Process.THREAD_PRIORITY_BACKGROUND + 3,
- Process.THREAD_PRIORITY_BACKGROUND,
- Process.THREAD_PRIORITY_DEFAULT, // 5 (NORM_PRIORITY)
- Process.THREAD_PRIORITY_DEFAULT - 2,
- Process.THREAD_PRIORITY_DEFAULT - 4,
- Process.THREAD_PRIORITY_URGENT_DISPLAY + 3,
- Process.THREAD_PRIORITY_URGENT_DISPLAY + 2,
- Process.THREAD_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY)
- };
-
- @Override
- public void setPriority(int nativeTid, int priority) {
- // Check NICE_VALUES[] length first.
- if (NICE_VALUES.length != (1 + Thread.MAX_PRIORITY - Thread.MIN_PRIORITY)) {
- throw new AssertionError("Unexpected NICE_VALUES.length=" + NICE_VALUES.length);
- }
- // Priority should be in the range of MIN_PRIORITY (1) to MAX_PRIORITY (10).
- if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
- throw new IllegalArgumentException("Priority out of range: " + priority);
- }
- Process.setThreadPriority(nativeTid, NICE_VALUES[priority - Thread.MIN_PRIORITY]);
- }
- }
-
@UnsupportedAppUsage
protected static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index f0f1b74..1968146 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -315,4 +315,9 @@
cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
},
},
+
+ // Workaround Clang LTO crash.
+ lto: {
+ never: true,
+ },
}
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h
index eeda275..ad8aeb2 100644
--- a/core/jni/core_jni_helpers.h
+++ b/core/jni/core_jni_helpers.h
@@ -90,6 +90,12 @@
return res;
}
+static inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
+ jclass cls = FindClassOrDie(env, "java/lang/ref/Reference");
+ jmethodID get = GetMethodIDOrDie(env, cls, "get", "()Ljava/lang/Object;");
+ return env->CallObjectMethod(ref, get);
+}
+
/**
* Read the specified field from jobject, and convert to std::string.
* If the field cannot be obtained, return defaultValue.
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 11f6a91..542d26f 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -17,6 +17,9 @@
roosa@google.com
per-file usagestatsservice.proto, usagestatsservice_v2.proto = mwachens@google.com
+# Biometrics
+kchyn@google.com
+
# Launcher
hyunyoungs@google.com
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8656820..80f73f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2682,6 +2682,14 @@
<permission android:name="android.permission.SUGGEST_MANUAL_TIME_AND_ZONE"
android:protectionLevel="signature" />
+ <!-- Allows applications like settings to manage configuration associated with automatic time
+ and time zone detection.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION"
+ android:protectionLevel="signature|privileged" />
+
<!-- ==================================================== -->
<!-- Permissions related to changing status bar -->
<!-- ==================================================== -->
diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java
index d4f6b1f..708bfa6 100644
--- a/core/tests/coretests/src/android/os/FileBridgeTest.java
+++ b/core/tests/coretests/src/android/os/FileBridgeTest.java
@@ -16,6 +16,9 @@
package android.os;
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+
import android.os.FileBridge.FileBridgeOutputStream;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
@@ -25,7 +28,6 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Random;
@@ -33,7 +35,7 @@
public class FileBridgeTest extends AndroidTestCase {
private File file;
- private FileOutputStream fileOs;
+ private ParcelFileDescriptor outputFile;
private FileBridge bridge;
private FileBridgeOutputStream client;
@@ -44,17 +46,17 @@
file = getContext().getFileStreamPath("meow.dat");
file.delete();
- fileOs = new FileOutputStream(file);
+ outputFile = ParcelFileDescriptor.open(file, MODE_CREATE | MODE_READ_WRITE);
bridge = new FileBridge();
- bridge.setTargetFile(fileOs.getFD());
+ bridge.setTargetFile(outputFile);
bridge.start();
client = new FileBridgeOutputStream(bridge.getClientSocket());
}
@Override
protected void tearDown() throws Exception {
- fileOs.close();
+ outputFile.close();
file.delete();
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 672b428..0a9e50e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -427,6 +427,8 @@
<permission name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<!-- Permissions required for CTS test - AdbManagerTest -->
<permission name="android.permission.MANAGE_DEBUGGING" />
+ <!-- Permissions required for CTS test - TimeManagerTest -->
+ <permission name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index a362bd2..667a751 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -139,7 +139,7 @@
mAnimationContext->destroy();
}
-static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
+static void setBufferCount(ANativeWindow* window) {
int query_value;
int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
if (err != 0 || query_value < 0) {
@@ -148,7 +148,9 @@
}
auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
- int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
+ // We only need to set min_undequeued + 2 because the renderahead amount was already factored into the
+ // query for min_undequeued
+ int bufferCount = min_undequeued_buffers + 2;
native_window_set_buffer_count(window, bufferCount);
}
@@ -179,7 +181,8 @@
mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);
if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) {
- setBufferCount(mNativeSurface->getNativeWindow(), mRenderAheadCapacity);
+ setBufferCount(mNativeSurface->getNativeWindow());
+
}
mFrameNumber = -1;
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index d35bc41..d02b496 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -372,7 +372,7 @@
AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
startLocalPlayer();
}
- } else if (mAllowRemote && (mRemotePlayer != null)) {
+ } else if (mAllowRemote && (mRemotePlayer != null) && (mUri != null)) {
final Uri canonicalUri = mUri.getCanonicalUri();
final boolean looping;
final float volume;
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8deb0c4..9deeb8f 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -34,6 +34,7 @@
import android.content.pm.UserInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
+import android.database.StaleDataException;
import android.net.Uri;
import android.os.Environment;
import android.os.FileUtils;
@@ -492,7 +493,12 @@
public Uri getRingtoneUri(int position) {
// use cursor directly instead of requerying it, which could easily
// cause position to shuffle.
- if (mCursor == null || !mCursor.moveToPosition(position)) {
+ try {
+ if (mCursor == null || !mCursor.moveToPosition(position)) {
+ return null;
+ }
+ } catch (StaleDataException | IllegalStateException e) {
+ Log.e(TAG, "Unexpected Exception has been catched.", e);
return null;
}
@@ -1130,11 +1136,13 @@
// Try finding the scanned ringtone
final String filename = getDefaultRingtoneFilename(type);
+ final String whichAudio = getQueryStringForType(type);
+ final String where = MediaColumns.DISPLAY_NAME + "=? AND " + whichAudio + "=?";
final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
try (Cursor cursor = context.getContentResolver().query(baseUri,
new String[] { MediaColumns._ID },
- MediaColumns.DISPLAY_NAME + "=?",
- new String[] { filename }, null)) {
+ where,
+ new String[] { filename, "1" }, null)) {
if (cursor.moveToFirst()) {
final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse(
ContentUris.withAppendedId(baseUri, cursor.getLong(0)));
@@ -1162,4 +1170,13 @@
default: throw new IllegalArgumentException();
}
}
+
+ private static String getQueryStringForType(int type) {
+ switch (type) {
+ case TYPE_RINGTONE: return MediaStore.Audio.AudioColumns.IS_RINGTONE;
+ case TYPE_NOTIFICATION: return MediaStore.Audio.AudioColumns.IS_NOTIFICATION;
+ case TYPE_ALARM: return MediaStore.Audio.AudioColumns.IS_ALARM;
+ default: throw new IllegalArgumentException();
+ }
+ }
}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index d2294b3..d346670 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -96,6 +96,11 @@
"-Wunused",
"-Wunreachable-code",
],
+
+ // Workaround Clang LTO crash.
+ lto: {
+ never: true,
+ },
}
cc_library_shared {
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
index 5ba5c01..40e4c54 100644
--- a/media/jni/audioeffect/Android.bp
+++ b/media/jni/audioeffect/Android.bp
@@ -28,4 +28,9 @@
"-Wunused",
"-Wunreachable-code",
],
+
+ // Workaround Clang LTO crash.
+ lto: {
+ never: true,
+ },
}
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index d6c74b1e..8a36837 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -8771,6 +8771,7 @@
method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
+ method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
}
@@ -35030,7 +35031,7 @@
method public int dataCapacity();
method public int dataPosition();
method public int dataSize();
- method public void enforceInterface(String);
+ method public void enforceInterface(@NonNull String);
method public boolean hasFileDescriptors();
method public byte[] marshall();
method @NonNull public static android.os.Parcel obtain();
@@ -35101,7 +35102,7 @@
method public void writeFloatArray(@Nullable float[]);
method public void writeInt(int);
method public void writeIntArray(@Nullable int[]);
- method public void writeInterfaceToken(String);
+ method public void writeInterfaceToken(@NonNull String);
method public void writeList(@Nullable java.util.List);
method public void writeLong(long);
method public void writeLongArray(@Nullable long[]);
@@ -45112,7 +45113,7 @@
method public long getNci();
method @IntRange(from=0, to=3279165) public int getNrarfcn();
method @IntRange(from=0, to=1007) public int getPci();
- method @IntRange(from=0, to=65535) public int getTac();
+ method @IntRange(from=0, to=16777215) public int getTac();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
}
@@ -45206,9 +45207,9 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellInfoWcdma> CREATOR;
}
- public abstract class CellLocation {
- ctor public CellLocation();
- method public static android.telephony.CellLocation getEmpty();
+ @Deprecated public abstract class CellLocation {
+ ctor @Deprecated public CellLocation();
+ method @Deprecated public static android.telephony.CellLocation getEmpty();
method @Deprecated public static void requestLocationUpdate();
}
@@ -46716,19 +46717,19 @@
package android.telephony.cdma {
- public class CdmaCellLocation extends android.telephony.CellLocation {
- ctor public CdmaCellLocation();
- ctor public CdmaCellLocation(android.os.Bundle);
- method public static double convertQuartSecToDecDegrees(int);
- method public void fillInNotifierBundle(android.os.Bundle);
- method public int getBaseStationId();
- method public int getBaseStationLatitude();
- method public int getBaseStationLongitude();
- method public int getNetworkId();
- method public int getSystemId();
- method public void setCellLocationData(int, int, int);
- method public void setCellLocationData(int, int, int, int, int);
- method public void setStateInvalid();
+ @Deprecated public class CdmaCellLocation extends android.telephony.CellLocation {
+ ctor @Deprecated public CdmaCellLocation();
+ ctor @Deprecated public CdmaCellLocation(android.os.Bundle);
+ method @Deprecated public static double convertQuartSecToDecDegrees(int);
+ method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+ method @Deprecated public int getBaseStationId();
+ method @Deprecated public int getBaseStationLatitude();
+ method @Deprecated public int getBaseStationLongitude();
+ method @Deprecated public int getNetworkId();
+ method @Deprecated public int getSystemId();
+ method @Deprecated public void setCellLocationData(int, int, int);
+ method @Deprecated public void setCellLocationData(int, int, int, int, int);
+ method @Deprecated public void setStateInvalid();
}
}
@@ -46928,15 +46929,15 @@
package android.telephony.gsm {
- public class GsmCellLocation extends android.telephony.CellLocation {
- ctor public GsmCellLocation();
- ctor public GsmCellLocation(android.os.Bundle);
- method public void fillInNotifierBundle(android.os.Bundle);
- method public int getCid();
- method public int getLac();
- method public int getPsc();
- method public void setLacAndCid(int, int);
- method public void setStateInvalid();
+ @Deprecated public class GsmCellLocation extends android.telephony.CellLocation {
+ ctor @Deprecated public GsmCellLocation();
+ ctor @Deprecated public GsmCellLocation(android.os.Bundle);
+ method @Deprecated public void fillInNotifierBundle(android.os.Bundle);
+ method @Deprecated public int getCid();
+ method @Deprecated public int getLac();
+ method @Deprecated public int getPsc();
+ method @Deprecated public void setLacAndCid(int, int);
+ method @Deprecated public void setStateInvalid();
}
@Deprecated public final class SmsManager {
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index 419d401..b67c22c 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -10070,6 +10070,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index f5f58ef..a927997 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -326,6 +326,9 @@
<!-- Permission needed for CTS test - DisplayTest -->
<uses-permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS" />
+ <!-- Permission needed for CTS test - TimeManagerTest -->
+ <uses-permission android:name="android.permission.MANAGE_TIME_AND_ZONE_DETECTION" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index f6c2ee2..02815a57 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -503,14 +503,14 @@
}
if (msg.what != MSG_SERVICE_COMMAND) {
- // Sanity check.
+ // Confidence check.
Log.e(TAG, "Invalid message type: " + msg.what);
return;
}
// At this point it's handling onStartCommand(), with the intent passed as an Extra.
if (!(msg.obj instanceof Intent)) {
- // Sanity check.
+ // Confidence check.
Log.wtf(TAG, "handleMessage(): invalid msg.obj type: " + msg.obj);
return;
}
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index b95092a..b8cfa1e 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -561,7 +561,7 @@
// Clear properties
mContext.getSharedPreferences(PREFS_BUGREPORT, Context.MODE_PRIVATE)
.edit().clear().commit();
- // Sanity check...
+ // Confidence check...
assertEquals("Did not reset properties", STATE_UNKNOWN,
getWarningState(mContext, STATE_UNKNOWN));
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 18a7add..cf83603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -284,6 +284,9 @@
mNetworkToIconLookup.put(toDisplayIconKey(
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE),
TelephonyIcons.NR_5G_PLUS);
+ mNetworkToIconLookup.put(toIconKey(
+ TelephonyManager.NETWORK_TYPE_NR),
+ TelephonyIcons.NR_5G);
}
private String getIconKey() {
@@ -306,9 +309,9 @@
case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
return toIconKey(TelephonyManager.NETWORK_TYPE_LTE) + "_CA_Plus";
case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
- return "5G";
+ return toIconKey(TelephonyManager.NETWORK_TYPE_NR);
case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE:
- return "5G_Plus";
+ return toIconKey(TelephonyManager.NETWORK_TYPE_NR) + "_Plus";
default:
return "unsupported";
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 33b9d00..da5f25b 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -28,6 +28,7 @@
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
import android.net.netlink.NetlinkSocket;
+import android.net.netlink.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
import android.net.util.SocketUtils;
@@ -41,11 +42,12 @@
import com.android.internal.annotations.VisibleForTesting;
import java.io.FileDescriptor;
-import java.io.InterruptedIOException;
import java.io.IOException;
+import java.io.InterruptedIOException;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.NoSuchElementException;
@@ -66,11 +68,12 @@
private static final String NO_IPV4_ADDRESS = "";
private static final String NO_IPV4_GATEWAY = "";
// Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h
- private static final int NF_NETLINK_CONNTRACK_NEW = 1;
- private static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
- private static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
+ public static final int NF_NETLINK_CONNTRACK_NEW = 1;
+ public static final int NF_NETLINK_CONNTRACK_UPDATE = 2;
+ public static final int NF_NETLINK_CONNTRACK_DESTROY = 4;
// Reference libnetfilter_conntrack/linux_nfnetlink_conntrack.h
public static final short NFNL_SUBSYS_CTNETLINK = 1;
+ public static final short IPCTNL_MSG_CT_NEW = 0;
public static final short IPCTNL_MSG_CT_GET = 1;
private final long NETLINK_MESSAGE_TIMEOUT_MS = 500;
@@ -237,7 +240,7 @@
NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
if (h1 == null) return false;
- sendNetlinkMessage(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
+ sendIpv4NfGenMsg(h1, (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
(short) (NLM_F_REQUEST | NLM_F_DUMP));
final NativeHandle h2 = mDeps.createConntrackSocket(
@@ -267,16 +270,23 @@
}
@VisibleForTesting
- public void sendNetlinkMessage(@NonNull NativeHandle handle, short type, short flags) {
- final int length = StructNlMsgHdr.STRUCT_SIZE;
+ public void sendIpv4NfGenMsg(@NonNull NativeHandle handle, short type, short flags) {
+ final int length = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
final byte[] msg = new byte[length];
- final StructNlMsgHdr nlh = new StructNlMsgHdr();
final ByteBuffer byteBuffer = ByteBuffer.wrap(msg);
+ byteBuffer.order(ByteOrder.nativeOrder());
+
+ final StructNlMsgHdr nlh = new StructNlMsgHdr();
nlh.nlmsg_len = length;
nlh.nlmsg_type = type;
nlh.nlmsg_flags = flags;
- nlh.nlmsg_seq = 1;
+ nlh.nlmsg_seq = 0;
nlh.pack(byteBuffer);
+
+ // Header needs to be added to buffer since a generic netlink request is being sent.
+ final StructNfGenMsg nfh = new StructNfGenMsg((byte) OsConstants.AF_INET);
+ nfh.pack(byteBuffer);
+
try {
NetlinkSocket.sendMessage(handle.getFileDescriptor(), msg, 0 /* offset */, length,
NETLINK_MESSAGE_TIMEOUT_MS);
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 7dd5290..64d5025 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -2104,7 +2104,7 @@
}
private boolean hasCallingPermission(@NonNull String permission) {
- return mContext.checkCallingPermission(permission) == PERMISSION_GRANTED;
+ return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
}
/** Unregister tethering event callback */
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 64be2d9..d206ea0 100644
--- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -553,7 +553,6 @@
TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
TestNetworkInterface iface = tnm.createTapInterface();
Log.d(TAG, "Created test interface " + iface.getInterfaceName());
- assertNotNull(NetworkInterface.getByName(iface.getInterfaceName()));
return iface;
}
diff --git a/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
new file mode 100644
index 0000000..57c28fc
--- /dev/null
+++ b/packages/Tethering/tests/privileged/src/com/android/networkstack/tethering/ConntrackSocketTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.networkstack.tethering;
+
+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 com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_GET;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.IPCTNL_MSG_CT_NEW;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NFNL_SUBSYS_CTNETLINK;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_DESTROY;
+import static com.android.networkstack.tethering.OffloadHardwareInterface.NF_NETLINK_CONNTRACK_NEW;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.netlink.StructNlMsgHdr;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.NativeHandle;
+import android.system.Os;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConntrackSocketTest {
+ private static final long TIMEOUT = 500;
+
+ private HandlerThread mHandlerThread;
+ private Handler mHandler;
+ private final SharedLog mLog = new SharedLog("privileged-test");
+
+ private OffloadHardwareInterface mOffloadHw;
+ private OffloadHardwareInterface.Dependencies mDeps;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mHandlerThread = new HandlerThread(getClass().getSimpleName());
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+
+ // Looper must be prepared here since AndroidJUnitRunner runs tests on separate threads.
+ if (Looper.myLooper() == null) Looper.prepare();
+
+ mDeps = new OffloadHardwareInterface.Dependencies(mLog);
+ mOffloadHw = new OffloadHardwareInterface(mHandler, mLog, mDeps);
+ }
+
+ @Test
+ public void testIpv4ConntrackSocket() throws Exception {
+ // Set up server and connect.
+ final InetSocketAddress anyAddress = new InetSocketAddress(
+ InetAddress.getByName("127.0.0.1"), 0);
+ final ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(anyAddress);
+ final SocketAddress theAddress = serverSocket.getLocalSocketAddress();
+
+ // Make a connection to the server.
+ final Socket socket = new Socket();
+ socket.connect(theAddress);
+ final Socket acceptedSocket = serverSocket.accept();
+
+ final NativeHandle handle = mDeps.createConntrackSocket(
+ NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
+ mOffloadHw.sendIpv4NfGenMsg(handle,
+ (short) ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET),
+ (short) (NLM_F_REQUEST | NLM_F_DUMP));
+
+ boolean foundConntrackEntry = false;
+ ByteBuffer buffer = ByteBuffer.allocate(DEFAULT_RECV_BUFSIZE);
+ buffer.order(ByteOrder.nativeOrder());
+
+ try {
+ while (Os.read(handle.getFileDescriptor(), buffer) > 0) {
+ buffer.flip();
+
+ // TODO: ConntrackMessage should get a parse API like StructNlMsgHdr
+ // so we can confirm that the conntrack added is for the TCP connection above.
+ final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(buffer);
+ assertNotNull(nlmsghdr);
+
+ // As long as 1 conntrack entry is found test case will pass, even if it's not
+ // the from the TCP connection above.
+ if (nlmsghdr.nlmsg_type == ((NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW)) {
+ foundConntrackEntry = true;
+ break;
+ }
+ }
+ } finally {
+ socket.close();
+ serverSocket.close();
+ }
+ assertTrue("Did not receive any NFNL_SUBSYS_CTNETLINK/IPCTNL_MSG_CT_NEW message",
+ foundConntrackEntry);
+ }
+}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
index c543fad..38b19dd 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -17,8 +17,9 @@
package com.android.networkstack.tethering;
import static android.net.util.TetheringUtils.uint16;
-import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.SOCK_STREAM;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -35,14 +36,15 @@
import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.net.netlink.StructNfGenMsg;
import android.net.netlink.StructNlMsgHdr;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.NativeHandle;
import android.os.test.TestLooper;
import android.system.ErrnoException;
-import android.system.OsConstants;
import android.system.Os;
+import android.system.OsConstants;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -55,8 +57,8 @@
import org.mockito.MockitoAnnotations;
import java.io.FileDescriptor;
-import java.io.OutputStream;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
@RunWith(AndroidJUnit4.class)
@@ -218,7 +220,7 @@
}
@Test
- public void testNetlinkMessage() throws Exception {
+ public void testSendIpv4NfGenMsg() throws Exception {
FileDescriptor writeSocket = new FileDescriptor();
FileDescriptor readSocket = new FileDescriptor();
try {
@@ -229,17 +231,25 @@
}
when(mNativeHandle.getFileDescriptor()).thenReturn(writeSocket);
- mOffloadHw.sendNetlinkMessage(mNativeHandle, TEST_TYPE, TEST_FLAGS);
+ mOffloadHw.sendIpv4NfGenMsg(mNativeHandle, TEST_TYPE, TEST_FLAGS);
- ByteBuffer buffer = ByteBuffer.allocate(StructNlMsgHdr.STRUCT_SIZE);
+ ByteBuffer buffer = ByteBuffer.allocate(9823); // Arbitrary value > expectedLen.
+ buffer.order(ByteOrder.nativeOrder());
+
int read = Os.read(readSocket, buffer);
+ final int expectedLen = StructNlMsgHdr.STRUCT_SIZE + StructNfGenMsg.STRUCT_SIZE;
+ assertEquals(expectedLen, read);
buffer.flip();
- assertEquals(StructNlMsgHdr.STRUCT_SIZE, buffer.getInt());
+ assertEquals(expectedLen, buffer.getInt());
assertEquals(TEST_TYPE, buffer.getShort());
assertEquals(TEST_FLAGS, buffer.getShort());
- assertEquals(1 /* seq */, buffer.getInt());
+ assertEquals(0 /* seq */, buffer.getInt());
assertEquals(0 /* pid */, buffer.getInt());
+ assertEquals(AF_INET, buffer.get()); // nfgen_family
+ assertEquals(0 /* error */, buffer.get()); // version
+ assertEquals(0 /* error */, buffer.getShort()); // res_id
+ assertEquals(expectedLen, buffer.position());
}
private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index ff8c628..7cdd3b3 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -284,10 +284,12 @@
@Override
public int handleFailedAttempt() {
final int lockoutMode = getLockoutMode();
- if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
- mPerformanceStats.permanentLockout++;
- } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
- mPerformanceStats.lockout++;
+ if (mPerformanceStats != null) {
+ if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
+ mPerformanceStats.permanentLockout++;
+ } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
+ mPerformanceStats.lockout++;
+ }
}
// Failing multiple times will continue to push out the lockout time
@@ -730,10 +732,12 @@
if (client != null && client.onAuthenticated(identifier, authenticated, token)) {
removeClient(client);
}
- if (authenticated) {
- mPerformanceStats.accept++;
- } else {
- mPerformanceStats.reject++;
+ if (mPerformanceStats != null) {
+ if (authenticated) {
+ mPerformanceStats.accept++;
+ } else {
+ mPerformanceStats.reject++;
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index e12cb8f..f116a24 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -352,6 +352,11 @@
public abstract boolean destroyCeSnapshotsNotSpecified(int userId, int[] retainRollbackIds);
/**
+ * Inform apexd that the boot has completed.
+ */
+ public abstract void markBootCompleted();
+
+ /**
* Dumps various state information to the provided {@link PrintWriter} object.
*
* @param pw the {@link PrintWriter} object to send information to.
@@ -883,6 +888,15 @@
}
}
+ @Override
+ public void markBootCompleted() {
+ try {
+ waitForApexService().markBootCompleted();
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Unable to contact apexservice", re);
+ }
+ }
+
/**
* Dump information about the packages contained in a particular cache
* @param packagesCache the cache to print information about.
@@ -1130,6 +1144,11 @@
}
@Override
+ public void markBootCompleted() {
+ // No-op
+ }
+
+ @Override
void dump(PrintWriter pw, String packageName) {
// No-op
}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index c3c2e5e..069a00f 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -547,9 +547,9 @@
final boolean newIsForceQueryable =
mForceQueryable.contains(newPkgSetting.appId)
/* shared user that is already force queryable */
- || newPkg.isForceQueryable()
- || newPkgSetting.forceQueryableOverride
+ || newPkgSetting.forceQueryableOverride /* adb override */
|| (newPkgSetting.isSystem() && (mSystemAppsQueryable
+ || newPkg.isForceQueryable()
|| ArrayUtils.contains(mForceQueryableByDevicePackageNames,
newPkg.getPackageName())));
if (newIsForceQueryable
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 994cec2..90d9834 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -943,6 +943,23 @@
}
}
+ private ParcelFileDescriptor openTargetInternal(String path, int flags, int mode)
+ throws IOException, ErrnoException {
+ // TODO: this should delegate to DCS so the system process avoids
+ // holding open FDs into containers.
+ final FileDescriptor fd = Os.open(path, flags, mode);
+ return new ParcelFileDescriptor(fd);
+ }
+
+ private ParcelFileDescriptor createRevocableFdInternal(RevocableFileDescriptor fd,
+ ParcelFileDescriptor pfd) throws IOException {
+ int releasedFdInt = pfd.detachFd();
+ FileDescriptor releasedFd = new FileDescriptor();
+ releasedFd.setInt$(releasedFdInt);
+ fd.init(mContext, releasedFd);
+ return fd.getRevocableFileDescriptor();
+ }
+
private ParcelFileDescriptor doWriteInternal(String name, long offsetBytes, long lengthBytes,
ParcelFileDescriptor incomingFd) throws IOException {
// Quick sanity check of state, and allocate a pipe for ourselves. We
@@ -975,21 +992,20 @@
Binder.restoreCallingIdentity(identity);
}
- // TODO: this should delegate to DCS so the system process avoids
- // holding open FDs into containers.
- final FileDescriptor targetFd = Os.open(target.getAbsolutePath(),
+ ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(),
O_CREAT | O_WRONLY, 0644);
Os.chmod(target.getAbsolutePath(), 0644);
// If caller specified a total length, allocate it for them. Free up
// cache space to grow, if needed.
if (stageDir != null && lengthBytes > 0) {
- mContext.getSystemService(StorageManager.class).allocateBytes(targetFd, lengthBytes,
+ mContext.getSystemService(StorageManager.class).allocateBytes(
+ targetPfd.getFileDescriptor(), lengthBytes,
PackageHelper.translateAllocateFlags(params.installFlags));
}
if (offsetBytes > 0) {
- Os.lseek(targetFd, offsetBytes, OsConstants.SEEK_SET);
+ Os.lseek(targetPfd.getFileDescriptor(), offsetBytes, OsConstants.SEEK_SET);
}
if (incomingFd != null) {
@@ -999,8 +1015,9 @@
// inserted above to hold the session active.
try {
final Int64Ref last = new Int64Ref(0);
- FileUtils.copy(incomingFd.getFileDescriptor(), targetFd, lengthBytes, null,
- Runnable::run, (long progress) -> {
+ FileUtils.copy(incomingFd.getFileDescriptor(), targetPfd.getFileDescriptor(),
+ lengthBytes, null, Runnable::run,
+ (long progress) -> {
if (params.sizeBytes > 0) {
final long delta = progress - last.value;
last.value = progress;
@@ -1011,7 +1028,7 @@
}
});
} finally {
- IoUtils.closeQuietly(targetFd);
+ IoUtils.closeQuietly(targetPfd);
IoUtils.closeQuietly(incomingFd);
// We're done here, so remove the "bridge" that was holding
@@ -1027,12 +1044,11 @@
}
return null;
} else if (PackageInstaller.ENABLE_REVOCABLE_FD) {
- fd.init(mContext, targetFd);
- return fd.getRevocableFileDescriptor();
+ return createRevocableFdInternal(fd, targetPfd);
} else {
- bridge.setTargetFile(targetFd);
+ bridge.setTargetFile(targetPfd);
bridge.start();
- return new ParcelFileDescriptor(bridge.getClientSocket());
+ return bridge.getClientSocket();
}
} catch (ErrnoException e) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 81748b2..4f0c707 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -280,6 +280,7 @@
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.permission.IPermissionManager;
+import android.provider.ContactsContract;
import android.provider.DeviceConfig;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
@@ -25400,6 +25401,32 @@
}
}
+ @Override
+ public void grantImplicitAccess(int recipientUid, String visibleAuthority) {
+ // This API is exposed temporarily to only the contacts provider. (b/158688602)
+ final int callingUid = Binder.getCallingUid();
+ ProviderInfo contactsProvider = resolveContentProviderInternal(
+ ContactsContract.AUTHORITY, 0, UserHandle.getUserId(callingUid));
+ if (contactsProvider == null || contactsProvider.applicationInfo == null
+ || !UserHandle.isSameApp(contactsProvider.applicationInfo.uid, callingUid)) {
+ throw new SecurityException(callingUid + " is not allow to call grantImplicitAccess");
+ }
+ final int userId = UserHandle.getUserId(recipientUid);
+ final long token = Binder.clearCallingIdentity();
+ final ProviderInfo providerInfo;
+ try {
+ providerInfo = resolveContentProvider(visibleAuthority, 0 /*flags*/, userId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ if (providerInfo == null) {
+ return;
+ }
+ int visibleUid = providerInfo.applicationInfo.uid;
+ mPmInternal.grantImplicitAccess(userId, null /*Intent*/, UserHandle.getAppId(recipientUid),
+ visibleUid, false);
+ }
+
boolean canHaveOatDir(String packageName) {
synchronized (mLock) {
AndroidPackage p = mPackages.get(packageName);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 09682c6..39b3203 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1377,7 +1377,7 @@
long timeoutMs = -1;
while ((opt = getNextOption()) != null) {
switch (opt) {
- case "--wait":
+ case "--wait-for-staged-ready":
waitForStagedSessionReady = true;
// If there is only one remaining argument, then it represents the sessionId, we
// shouldn't try to parse it as timeoutMs.
@@ -2865,7 +2865,7 @@
}
sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
break;
- case "--wait":
+ case "--wait-for-staged-ready":
params.mWaitForStagedSessionReady = true;
try {
params.timeoutMs = Long.parseLong(peekNextArg());
@@ -3597,7 +3597,7 @@
pw.println(" [--preload] [--instant] [--full] [--dont-kill]");
pw.println(" [--enable-rollback]");
pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
- pw.println(" [--apex] [--wait TIMEOUT]");
+ pw.println(" [--apex] [--wait-for-staged-ready TIMEOUT]");
pw.println(" [PATH [SPLIT...]|-]");
pw.println(" Install an application. Must provide the apk data to install, either as");
pw.println(" file path(s) or '-' to read from stdin. Options are:");
@@ -3625,8 +3625,8 @@
pw.println(" 3=device setup, 4=user request");
pw.println(" --force-uuid: force install on to disk volume with given UUID");
pw.println(" --apex: install an .apex file, not an .apk");
- pw.println(" --wait: when performing staged install, wait TIMEOUT milliseconds");
- pw.println(" for pre-reboot verification to complete. If TIMEOUT is not");
+ pw.println(" --wait-for-staged-ready: when performing staged install, wait TIMEOUT");
+ pw.println(" ms for pre-reboot verification to complete. If TIMEOUT is not");
pw.println(" specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
pw.println("");
pw.println(" install-existing [--user USER_ID|all|current]");
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index e2bd1f1..0c96f59 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -164,6 +164,7 @@
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_BOOT_COMPLETED && sStagingManager != null) {
sStagingManager.markStagedSessionsAsSuccessful();
+ sStagingManager.markBootCompleted();
}
}
}
@@ -179,6 +180,10 @@
}
}
+ private void markBootCompleted() {
+ mApexManager.markBootCompleted();
+ }
+
/**
* Validates the signature used to sign the container of the new apex package
*
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 2623094..37aedac 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -365,7 +365,25 @@
}
@Test
- public void testForceQueryable_DoesntFilter() throws Exception {
+ public void testForceQueryable_SystemDoesntFilter() throws Exception {
+ final AppsFilter appsFilter =
+ new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
+ simulateAddBasicAndroid(appsFilter);
+ appsFilter.onSystemReady();
+
+ PackageSetting target = simulateAddPackage(appsFilter,
+ pkg("com.some.package").setForceQueryable(true), DUMMY_TARGET_APPID,
+ setting -> setting.setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
+ PackageSetting calling = simulateAddPackage(appsFilter,
+ pkg("com.some.other.package"), DUMMY_CALLING_APPID);
+
+ assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ SYSTEM_USER));
+ }
+
+
+ @Test
+ public void testForceQueryable_NonSystemFilters() throws Exception {
final AppsFilter appsFilter =
new AppsFilter(mStateProvider, mFeatureConfigMock, new String[]{}, false, null);
simulateAddBasicAndroid(appsFilter);
@@ -376,7 +394,7 @@
PackageSetting calling = simulateAddPackage(appsFilter,
pkg("com.some.other.package"), DUMMY_CALLING_APPID);
- assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
+ assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
SYSTEM_USER));
}
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index ac88560..ddc6084 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -660,6 +660,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index 05cef9b..3923c756 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -37,7 +37,7 @@
private static final String TAG = "CellIdentityNr";
private static final int MAX_PCI = 1007;
- private static final int MAX_TAC = 65535;
+ private static final int MAX_TAC = 16777215; // 0xffffff
private static final int MAX_NRARFCN = 3279165;
private static final long MAX_NCI = 68719476735L;
@@ -65,7 +65,7 @@
/**
*
* @param pci Physical Cell Id in range [0, 1007].
- * @param tac 16-bit Tracking Area Code.
+ * @param tac 24-bit Tracking Area Code.
* @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165].
* @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2.
* @param mccStr 3-digit Mobile Country Code in string format.
@@ -215,9 +215,9 @@
/**
* Get the tracking area code.
- * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
+ * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
*/
- @IntRange(from = 0, to = 65535)
+ @IntRange(from = 0, to = 16777215)
public int getTac() {
return mTac;
}
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index cdf7351..8f5ec36 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -29,7 +29,10 @@
/**
* Abstract class that represents the location of the device. {@more}
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
*/
+@Deprecated
public abstract class CellLocation {
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 85dca2b..66eadb5 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -13388,4 +13388,38 @@
return true;
}
}
+
+ /**
+ * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app.
+ *
+ * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+ *
+ * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or
+ * does not exist on the SIM card.
+ *
+ * @throws IllegalStateException if the Telephony process is not currently available.
+ * @throws SecurityException if the caller doesn't have the permission.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ public @NonNull List<String> getEquivalentHomePlmns() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.getEquivalentHomePlmns(getSubId(), mContext.getOpPackageName(),
+ getAttributionTag());
+ } else {
+ throw new IllegalStateException("telephony service is null.");
+ }
+ } catch (RemoteException ex) {
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
+
+ return Collections.emptyList();
+ }
}
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 9bc39a0..d808cab 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -23,7 +23,10 @@
/**
* Represents the cell location on a CDMA phone.
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
*/
+@Deprecated
public class CdmaCellLocation extends CellLocation {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private int mBaseStationId = -1;
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index bc8ee1d..2eee4ce 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -23,7 +23,10 @@
/**
* Represents the cell location on a GSM phone.
+ *
+ * @deprecated use {@link android.telephony.CellIdentity CellIdentity}.
*/
+@Deprecated
public class GsmCellLocation extends CellLocation {
private int mLac;
private int mCid;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ae1b5c1..659d9cd3 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2297,4 +2297,12 @@
* Whether device can connect to 5G network when two SIMs are active.
*/
boolean canConnectTo5GInDsdsMode();
+
+ /**
+ * Returns a list of the equivalent home PLMNs (EF_EHPLMN) from the USIM app.
+ *
+ * @return A list of equivalent home PLMNs. Returns an empty list if EF_EHPLMN is empty or
+ * does not exist on the SIM card.
+ */
+ List<String> getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId);
}
diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
index 0f62c4f..e9227e94 100644
--- a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
+++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatCommandNotInstalledTest.kt
@@ -107,7 +107,10 @@
fun ParcelFileDescriptor.text() = FileReader(fileDescriptor).readText()
@After
- fun resetIdentity() = uiAutomation.dropShellPermissionIdentity()
+ fun resetChangeIdAndIdentity() {
+ command("am compat reset $TEST_CHANGE_ID $TEST_PKG")
+ uiAutomation.dropShellPermissionIdentity()
+ }
@Test
fun execute() {
diff --git a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
index 61d7c76..fb4a2b2 100644
--- a/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
+++ b/tests/RollbackTest/NetworkStagedRollbackTest/src/com/android/tests/rollback/host/NetworkStagedRollbackTest.java
@@ -26,6 +26,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -57,6 +58,9 @@
private WatchdogEventLogger mLogger = new WatchdogEventLogger();
+ @Rule
+ public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
+
@Before
public void setUp() throws Exception {
runPhase("cleanUp");
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index 9169ef5..be74e33 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -34,6 +34,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -87,6 +88,9 @@
private WatchdogEventLogger mLogger = new WatchdogEventLogger();
+ @Rule
+ public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
+
@Before
public void setUp() throws Exception {
deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
diff --git a/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java
new file mode 100644
index 0000000..b086213
--- /dev/null
+++ b/tests/RollbackTest/lib/src/com/android/tests/rollback/host/AbandonSessionsRule.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.tests.rollback.host;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.rules.ExternalResource;
+
+public class AbandonSessionsRule extends ExternalResource {
+ private final BaseHostJUnit4Test mHost;
+
+ public AbandonSessionsRule(BaseHostJUnit4Test host) {
+ mHost = host;
+ }
+
+ @Override
+ protected void before() throws Throwable {
+ abandonSessions(mHost.getDevice());
+ }
+
+ @Override
+ protected void after() {
+ try {
+ abandonSessions(mHost.getDevice());
+ } catch (Exception ignore) {
+ }
+ }
+
+ /**
+ * Abandons all sessions to prevent interference in our tests.
+ */
+ private static void abandonSessions(ITestDevice device) throws Exception {
+ // No point in abandoning applied or failed sessions. We care about ready sessions only.
+ String cmdListReadySessions =
+ "pm list staged-sessions --only-sessionid --only-parent --only-ready";
+ String output = device.executeShellCommand(cmdListReadySessions);
+ if (output.trim().isEmpty()) {
+ // No sessions to abandon
+ return;
+ }
+ // Ensure we have sufficient privilege to abandon sessions from other apps
+ device.enableAdbRoot();
+ device.executeShellCommand("for i in $(" + cmdListReadySessions
+ + "); do pm install-abandon $i; done");
+ device.disableAdbRoot();
+ }
+}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index c3fdd69..1e286bb 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -24,7 +24,15 @@
name: "StagedInstallInternalTest",
srcs: ["src/**/*.java"],
libs: ["tradefed"],
- static_libs: ["testng", "compatibility-tradefed"],
+ static_libs: [
+ "testng",
+ "compatibility-tradefed",
+ "module_test_util",
+ ],
+ data: [
+ ":com.android.apex.cts.shim.v2_prebuilt",
+ ":TestAppAv1",
+ ],
test_suites: ["general-tests"],
test_config: "StagedInstallInternalTest.xml",
}
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 9b432f7..86d5fd8 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -19,8 +19,10 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import com.android.ddmlib.Log;
+import com.android.tests.util.ModuleTestUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.ProcessInfo;
@@ -30,6 +32,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.File;
+
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedInstallInternalTest extends BaseHostJUnit4Test {
@@ -37,6 +41,11 @@
private static final long SYSTEM_SERVER_TIMEOUT_MS = 60 * 1000;
private boolean mWasRoot = false;
+ private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex";
+ private static final String APK_A = "TestAppAv1.apk";
+
+ private final ModuleTestUtils mTestUtils = new ModuleTestUtils(this);
+
/**
* Runs the given phase of a test by calling into the device.
* Throws an exception if the test phase fails.
@@ -87,6 +96,58 @@
runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
}
+ @Test
+ public void testAdbStagedInstallWaitForReadyFlagWorks() throws Exception {
+ assumeTrue("Device does not support updating APEX",
+ mTestUtils.isApexUpdateSupported());
+
+ File apexFile = mTestUtils.getTestFile(SHIM_V2);
+ String output = getDevice().executeAdbCommand("install", "--staged",
+ "--wait-for-staged-ready", "60000", apexFile.getAbsolutePath());
+ assertThat(output).contains("Reboot device to apply staged session");
+ String sessionId = getDevice().executeShellCommand(
+ "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+ assertThat(sessionId).isNotEmpty();
+ }
+
+ @Test
+ public void testAdbStagedInstallNoWaitFlagWorks() throws Exception {
+ assumeTrue("Device does not support updating APEX",
+ mTestUtils.isApexUpdateSupported());
+
+ File apexFile = mTestUtils.getTestFile(SHIM_V2);
+ String output = getDevice().executeAdbCommand("install", "--staged",
+ "--no-wait", apexFile.getAbsolutePath());
+ assertThat(output).doesNotContain("Reboot device to apply staged session");
+ assertThat(output).contains("Success");
+ String sessionId = getDevice().executeShellCommand(
+ "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+ assertThat(sessionId).isEmpty();
+ }
+
+ @Test
+ public void testAdbInstallMultiPackageCommandWorks() throws Exception {
+ assumeTrue("Device does not support updating APEX",
+ mTestUtils.isApexUpdateSupported());
+
+ File apexFile = mTestUtils.getTestFile(SHIM_V2);
+ File apkFile = mTestUtils.getTestFile(APK_A);
+ String output = getDevice().executeAdbCommand("install-multi-package",
+ apexFile.getAbsolutePath(), apkFile.getAbsolutePath());
+ assertThat(output).contains("Created parent session");
+ assertThat(output).contains("Created child session");
+ assertThat(output).contains("Success. Reboot device to apply staged session");
+
+ // Ensure there is only one parent session
+ String[] sessionIds = getDevice().executeShellCommand(
+ "pm get-stagedsessions --only-ready --only-parent --only-sessionid").split("\n");
+ assertThat(sessionIds.length).isEqualTo(1);
+ // Ensure there are two children session
+ sessionIds = getDevice().executeShellCommand(
+ "pm get-stagedsessions --only-ready --only-sessionid").split("\n");
+ assertThat(sessionIds.length).isEqualTo(3);
+ }
+
private void restartSystemServer() throws Exception {
// Restart the system server
long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();