Merge "Unhide FrontendSettings part 1 with super Builder class"
diff --git a/Android.bp b/Android.bp
index 6c640b3..5fcefa6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -306,7 +306,6 @@
"rs/java",
"sax/java",
"telecomm/java",
- "wifi/java",
],
},
@@ -1126,9 +1125,10 @@
}
// Avoid including Parcelable classes as we don't want to have two copies of
-// Parcelable cross the process.
+// Parcelable cross the libraries. This is used by telephony-common (frameworks/opt/telephony)
+// and TeleService app (packages/services/Telephony).
filegroup {
- name: "framework-telephony-stack-shared-srcs",
+ name: "framework-telephony-common-shared-srcs",
srcs: [
"core/java/android/os/BasicShellCommandHandler.java",
"core/java/android/os/RegistrantList.java",
@@ -1151,6 +1151,21 @@
}
// Avoid including Parcelable classes as we don't want to have two copies of
+// Parcelable cross the process. This is used by framework-telephony (frameworks/base/telephony).
+filegroup {
+ name: "framework-telephony-shared-srcs",
+ srcs: [
+ "core/java/android/util/RecurrenceRule.java",
+ "core/java/com/android/internal/os/SomeArgs.java",
+ "core/java/com/android/internal/util/BitwiseInputStream.java",
+ "core/java/com/android/internal/util/BitwiseOutputStream.java",
+ "core/java/com/android/internal/util/HexDump.java",
+ "core/java/com/android/internal/util/IndentingPrintWriter.java",
+ "core/java/com/android/internal/util/Preconditions.java",
+ ],
+}
+
+// Avoid including Parcelable classes as we don't want to have two copies of
// Parcelable cross the process.
filegroup {
name: "framework-cellbroadcast-shared-srcs",
@@ -1274,6 +1289,7 @@
name: "framework-telephony",
srcs: [
":framework-telephony-sources",
+ ":framework-telephony-shared-srcs",
],
// TODO: change to framework-system-stub to build against system APIs.
libs: [
@@ -1292,7 +1308,7 @@
"frameworks/native/aidl/gui",
]
},
- jarjar_rules: ":telephony-framework-jarjar-rules",
+ jarjar_rules: ":framework-telephony-jarjar-rules",
dxflags: [
"--core-library",
"--multi-dex",
@@ -1311,6 +1327,6 @@
}
filegroup {
- name: "telephony-framework-jarjar-rules",
+ name: "framework-telephony-jarjar-rules",
srcs: ["telephony/framework-telephony-jarjar-rules.txt"],
}
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
new file mode 100644
index 0000000..02d0740
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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 android.app.blob;
+
+/** {@hide} */
+parcelable BlobHandle;
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobHandle.java b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
new file mode 100644
index 0000000..6aca4a1
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/BlobHandle.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 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 android.app.blob;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * An identifier to represent a blob.
+ */
+// TODO: use datagen tool?
+public final class BlobHandle implements Parcelable {
+ private static final String ALGO_SHA_256 = "SHA-256";
+
+ private static final int LIMIT_BLOB_TAG_LENGTH = 128; // characters
+
+ /**
+ * Cyrptographically secure hash algorithm used to generate hash of the blob this handle is
+ * representing.
+ *
+ * @hide
+ */
+ @NonNull public final String algorithm;
+ /**
+ * Hash of the blob this handle is representing using {@link #algorithm}.
+ *
+ * @hide
+ */
+ @NonNull public final byte[] digest;
+ /**
+ * Label of the blob that can be surfaced to the user.
+ * @hide
+ */
+ @NonNull public final CharSequence label;
+ /**
+ * Time in milliseconds after which the blob should be invalidated and not
+ * allowed to be accessed by any other app, in {@link System#currentTimeMillis()} timebase.
+ *
+ * @hide
+ */
+ @CurrentTimeMillisLong public final long expiryTimeMillis;
+ /**
+ * An opaque {@link String} associated with the blob.
+ *
+ * @hide
+ */
+ @NonNull public final String tag;
+
+ private BlobHandle(String algorithm, byte[] digest, CharSequence label, long expiryTimeMillis,
+ String tag) {
+ this.algorithm = algorithm;
+ this.digest = digest;
+ this.label = label;
+ this.expiryTimeMillis = expiryTimeMillis;
+ this.tag = tag;
+ }
+
+ private BlobHandle(Parcel in) {
+ this.algorithm = in.readString();
+ this.digest = in.createByteArray();
+ this.label = in.readCharSequence();
+ this.expiryTimeMillis = in.readLong();
+ this.tag = in.readString();
+ }
+
+ /** @hide */
+ public static @NonNull BlobHandle create(@NonNull String algorithm, @NonNull byte[] digest,
+ @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+ @NonNull String tag) {
+ Preconditions.checkNotNull(algorithm, "algorithm must not be null");
+ Preconditions.checkNotNull(digest, "digest must not be null");
+ Preconditions.checkNotNull(label, "label must not be null");
+ Preconditions.checkArgumentNonnegative(expiryTimeMillis,
+ "expiryTimeMillis must not be negative");
+ Preconditions.checkNotNull(tag, "tag must not be null");
+ Preconditions.checkArgument(tag.length() <= LIMIT_BLOB_TAG_LENGTH, "tag too long");
+ return new BlobHandle(algorithm, digest, label, expiryTimeMillis, tag);
+ }
+
+ /**
+ * Create a new blob identifier.
+ *
+ * <p> For two objects of {@link BlobHandle} to be considered equal, the following arguments
+ * must be equal:
+ * <ul>
+ * <li> {@code digest}
+ * <li> {@code label}
+ * <li> {@code expiryTimeMillis}
+ * <li> {@code tag}
+ * </ul>
+ *
+ * @param digest the SHA-256 hash of the blob this is representing.
+ * @param label a label indicating what the blob is, that can be surfaced to the user.
+ * @param expiryTimeMillis the time in secs after which the blob should be invalidated and not
+ * allowed to be accessed by any other app,
+ * in {@link System#currentTimeMillis()} timebase.
+ * @param tag an opaque {@link String} associated with the blob. The length of the tag
+ * cannot be more than 128 characters.
+ *
+ * @return a new instance of {@link BlobHandle} object.
+ */
+ public static @NonNull BlobHandle createWithSha256(@NonNull byte[] digest,
+ @NonNull CharSequence label, @CurrentTimeMillisLong long expiryTimeMillis,
+ @NonNull String tag) {
+ return create(ALGO_SHA_256, digest, label, expiryTimeMillis, tag);
+ }
+
+ /**
+ * Returns the SHA-256 hash of the blob that this object is representing.
+ *
+ * @see #createWithSha256(byte[], CharSequence, long, String)
+ */
+ public @NonNull byte[] getSha256Digest() {
+ return digest;
+ }
+
+ /**
+ * Returns the label associated with the blob that this object is representing.
+ *
+ * @see #createWithSha256(byte[], CharSequence, long, String)
+ */
+ public @NonNull CharSequence getLabel() {
+ return label;
+ }
+
+ /**
+ * Returns the expiry time in milliseconds of the blob that this object is representing, in
+ * {@link System#currentTimeMillis()} timebase.
+ *
+ * @see #createWithSha256(byte[], CharSequence, long, String)
+ */
+ public @CurrentTimeMillisLong long getExpiryTimeMillis() {
+ return expiryTimeMillis;
+ }
+
+ /**
+ * Returns the opaque {@link String} associated with the blob this object is representing.
+ *
+ * @see #createWithSha256(byte[], CharSequence, long, String)
+ */
+ public @NonNull String getTag() {
+ return tag;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(algorithm);
+ dest.writeByteArray(digest);
+ dest.writeCharSequence(label);
+ dest.writeLong(expiryTimeMillis);
+ dest.writeString(tag);
+ }
+
+ public static final @NonNull Creator<BlobHandle> CREATOR = new Creator<BlobHandle>() {
+ @Override
+ public @NonNull BlobHandle createFromParcel(@NonNull Parcel source) {
+ return new BlobHandle(source);
+ }
+
+ @Override
+ public @NonNull BlobHandle[] newArray(int size) {
+ return new BlobHandle[size];
+ }
+ };
+}
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 1ed188e..4395e5a 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -15,18 +15,33 @@
*/
package android.app.blob;
+import android.annotation.BytesLong;
+import android.annotation.CallbackExecutor;
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.IdRes;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelableException;
+import android.os.RemoteException;
+
+import com.android.internal.util.function.pooled.PooledLambda;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
- * This class provides access to the blob store maintained by the system.
+ * This class provides access to the blob store managed by the system.
*
* Apps can publish data blobs which might be useful for other apps on the device to be
- * maintained by the system and apps that would like to access these data blobs can do so
+ * managed by the system and apps that would like to access these data blobs can do so
* by addressing them via their cryptographically secure hashes.
*
- * TODO: make this public once the APIs are added.
- * @hide
+ * TODO: More documentation.
*/
@SystemService(Context.BLOB_STORE_SERVICE)
public class BlobStoreManager {
@@ -34,8 +49,421 @@
private final IBlobStoreManager mService;
/** @hide */
- public BlobStoreManager(Context context, IBlobStoreManager service) {
+ public BlobStoreManager(@NonNull Context context, @NonNull IBlobStoreManager service) {
mContext = context;
mService = service;
}
+
+ /**
+ * Create a new session using the given {@link BlobHandle}, returning a unique id
+ * that represents the session. Once created, the session can be opened
+ * multiple times across multiple device boots.
+ *
+ * <p> The system may automatically destroy sessions that have not been
+ * finalized (either committed or abandoned) within a reasonable period of
+ * time, typically about a week.
+ *
+ * @param blobHandle the {@link BlobHandle} identifier for which a new session
+ * needs to be created.
+ * @return positive, non-zero unique id that represents the created session.
+ * This id remains consistent across device reboots until the
+ * session is finalized. IDs are not reused during a given boot.
+ *
+ * @throws IOException when there is an I/O error while creating the session.
+ * @throws SecurityException when the caller is not allowed to create a session, such
+ * as when called from an Instant app.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+ * @throws IllegalStateException when a new session could not be created, such as when the
+ * caller is trying to create too many sessions or when the
+ * device is running low on space.
+ */
+ public @IntRange(from = 1) long createSession(@NonNull BlobHandle blobHandle)
+ throws IOException {
+ try {
+ return mService.createSession(blobHandle, mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Open an existing session to actively perform work.
+ *
+ * @param sessionId a unique id obtained via {@link #createSession(BlobHandle)} that
+ * represents a particular session.
+ * @return the {@link Session} object corresponding to the {@code sessionId}.
+ *
+ * @throws IOException when there is an I/O error while opening the session.
+ * @throws SecurityException when the caller does not own the session, or
+ * the session does not exist or is invalid.
+ */
+ public @NonNull Session openSession(@IntRange(from = 1) long sessionId) throws IOException {
+ try {
+ return new Session(mService.openSession(sessionId));
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Opens an existing blob for reading from the blob store managed by the system.
+ *
+ * @param blobHandle the {@link BlobHandle} representing the blob that the caller
+ * wants to access.
+ * @return a {@link ParcelFileDescriptor} that can be used to read the blob content.
+ *
+ * @throws IOException when there is an I/O while opening the blob for read.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+ * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+ * exist or the caller does not have access to it.
+ */
+ public @NonNull ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle)
+ throws IOException {
+ try {
+ return mService.openBlob(blobHandle, mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+ * system that the caller wants the blob to be kept around.
+ *
+ * <p> Any active leases will be automatically released when the blob's expiry time
+ * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+ *
+ * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+ * acquire a lease for.
+ * @param descriptionResId the resource id for a short description string that can be surfaced
+ * to the user explaining what the blob is used for.
+ * @param leaseExpiryTimeMillis the time in milliseconds after which the lease can be
+ * automatically released, in {@link System#currentTimeMillis()}
+ * timebase. If its value is {@code 0}, then the behavior of this
+ * API is identical to {@link #acquireLease(BlobHandle, int)}
+ * where clients have to explicitly call
+ * {@link #releaseLease(BlobHandle)} when they don't
+ * need the blob anymore.
+ *
+ * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+ * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+ * exist or the caller does not have access to it.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid or
+ * if the {@code leaseExpiryTimeMillis} is greater than the
+ * {@link BlobHandle#getExpiryTimeMillis()}.
+ * @throws IllegalStateException when a lease could not be acquired, such as when the
+ * caller is trying to acquire too many leases.
+ *
+ * @see {@link #acquireLease(BlobHandle, int)}
+ */
+ public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+ @CurrentTimeMillisLong long leaseExpiryTimeMillis) throws IOException {
+ try {
+ mService.acquireLease(blobHandle, descriptionResId, leaseExpiryTimeMillis,
+ mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Acquire a lease to the blob represented by {@code blobHandle}. This lease indicates to the
+ * system that the caller wants the blob to be kept around.
+ *
+ * <p> This is similar to {@link #acquireLease(BlobHandle, int, long)} except clients don't
+ * have to specify the lease expiry time upfront using this API and need to explicitly
+ * release the lease using {@link #releaseLease(BlobHandle)} when they no longer like to keep
+ * a blob around.
+ *
+ * <p> Any active leases will be automatically released when the blob's expiry time
+ * ({@link BlobHandle#getExpiryTimeMillis()}) is elapsed.
+ *
+ * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+ * acquire a lease for.
+ * @param descriptionResId the resource id for a short description string that can be surfaced
+ * to the user explaining what the blob is used for.
+ *
+ * @throws IOException when there is an I/O error while acquiring a lease to the blob.
+ * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+ * exist or the caller does not have access to it.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+ * @throws IllegalStateException when a lease could not be acquired, such as when the
+ * caller is trying to acquire too many leases.
+ *
+ * @see {@link #acquireLease(BlobHandle, int, long)}
+ */
+ public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId)
+ throws IOException {
+ acquireLease(blobHandle, descriptionResId, 0);
+ }
+
+ /**
+ * Release all active leases to the blob represented by {@code blobHandle} which are
+ * currently held by the caller.
+ *
+ * @param blobHandle the {@link BlobHandle} representing the blob that the caller wants to
+ * release the leases for.
+ *
+ * @throws IOException when there is an I/O error while releasing the releases to the blob.
+ * @throws SecurityException when the blob represented by the {@code blobHandle} does not
+ * exist or the caller does not have access to it.
+ * @throws IllegalArgumentException when {@code blobHandle} is invalid.
+ */
+ public void releaseLease(@NonNull BlobHandle blobHandle) throws IOException {
+ try {
+ mService.releaseLease(blobHandle, mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Represents an ongoing session of a blob's contribution to the blob store managed by the
+ * system.
+ *
+ * <p> Clients that want to contribute a blob need to first create a {@link Session} using
+ * {@link #createSession(BlobHandle)} and once the session is created, clients can open and
+ * close this session multiple times using {@link #openSession(long)} and
+ * {@link Session#close()} before committing it using
+ * {@link Session#commit(Executor, Consumer)}, at which point system will take
+ * ownership of the blob and the client can no longer make any modifications to the blob's
+ * content.
+ */
+ public static class Session implements Closeable {
+ private final IBlobStoreSession mSession;
+
+ private Session(@NonNull IBlobStoreSession session) {
+ mSession = session;
+ }
+
+ /**
+ * Opens a file descriptor to write a blob into the session.
+ *
+ * <p> The returned file descriptor will start writing data at the requested offset
+ * in the underlying file, which can be used to resume a partially
+ * written file. If a valid file length is specified, the system will
+ * preallocate the underlying disk space to optimize placement on disk.
+ * It is strongly recommended to provide a valid file length when known.
+ *
+ * @param offsetBytes offset into the file to begin writing at, or 0 to
+ * start at the beginning of the file.
+ * @param lengthBytes total size of the file being written, used to
+ * preallocate the underlying disk space, or -1 if unknown.
+ * The system may clear various caches as needed to allocate
+ * this space.
+ *
+ * @return a {@link ParcelFileDescriptor} for writing to the blob file.
+ *
+ * @throws IOException when there is an I/O error while opening the file to write.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to write to the file after it is
+ * abandoned (using {@link #abandon()})
+ * or committed (using {@link #commit})
+ * or closed (using {@link #close()}).
+ */
+ public @NonNull ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+ @BytesLong long lengthBytes) throws IOException {
+ try {
+ return mSession.openWrite(offsetBytes, lengthBytes);
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Gets the size of the blob file that was written to the session so far.
+ *
+ * @return the size of the blob file so far.
+ *
+ * @throws IOException when there is an I/O error while opening the file to read.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to get the file size after it is
+ * abandoned (using {@link #abandon()})
+ * or closed (using {@link #close()}).
+ */
+ public @BytesLong long getSize() throws IOException {
+ try {
+ return mSession.getSize();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Close this session. It can be re-opened for writing/reading if it has not been
+ * abandoned (using {@link #abandon}) or closed (using {@link #commit}).
+ *
+ * @throws IOException when there is an I/O error while closing the session.
+ * @throws SecurityException when the caller is not the owner of the session.
+ */
+ public void close() throws IOException {
+ try {
+ mSession.close();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Abandon this session and delete any data that was written to this session so far.
+ *
+ * @throws IOException when there is an I/O error while abandoning the session.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to abandon a session which was
+ * already finalized.
+ */
+ public void abandon() throws IOException {
+ try {
+ mSession.abandon();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow {@code packageName} with a particular signing certificate to access this blob
+ * data once it is committed using a {@link BlobHandle} representing the blob.
+ *
+ * <p> This needs to be called before committing the blob using
+ * {@link #commit(Executor, Consumer)}.
+ *
+ * @param packageName the name of the package which should be allowed to access the blob.
+ * @param certificate the input bytes representing a certificate of type
+ * {@link android.content.pm.PackageManager#CERT_INPUT_SHA256}.
+ *
+ * @throws IOException when there is an I/O error while changing the access.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to change access for a blob which is
+ * already committed.
+ */
+ public void allowPackageAccess(@NonNull String packageName, @NonNull byte[] certificate)
+ throws IOException {
+ try {
+ mSession.allowPackageAccess(packageName, certificate);
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow packages which are signed with the same certificate as the caller to access this
+ * blob data once it is committed using a {@link BlobHandle} representing the blob.
+ *
+ * <p> This needs to be called before committing the blob using
+ * {@link #commit(Executor, Consumer)}.
+ *
+ * @throws IOException when there is an I/O error while changing the access.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to change access for a blob which is
+ * already committed.
+ */
+ public void allowSameSignatureAccess() throws IOException {
+ try {
+ mSession.allowSameSignatureAccess();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Allow any app on the device to access this blob data once it is committed using
+ * a {@link BlobHandle} representing the blob.
+ *
+ * <p><strong>Note:</strong> This is only meant to be used from libraries and SDKs where
+ * the apps which we want to allow access is not known ahead of time.
+ * If a blob is being committed to be shared with a particular set of apps, it is highly
+ * recommended to use {@link #allowPackageAccess(String, byte[])} instead.
+ *
+ * <p> This needs to be called before committing the blob using
+ * {@link #commit(Executor, Consumer)}.
+ *
+ * @throws IOException when there is an I/O error while changing the access.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalStateException when the caller tries to change access for a blob which is
+ * already committed.
+ */
+ public void allowPublicAccess() throws IOException {
+ try {
+ mSession.allowPublicAccess();
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Commit the file that was written so far to this session to the blob store maintained by
+ * the system.
+ *
+ * <p> Once this method is called, the session is finalized and no additional
+ * mutations can be performed on the session. If the device reboots
+ * before the session has been finalized, you may commit the session again.
+ *
+ * <p> Note that this commit operation will fail if the hash of the data written so far
+ * to this session does not match with the one used for
+ * {@link BlobHandle#createWithSha256(byte[], CharSequence, long, String)} BlobHandle}
+ * associated with this session.
+ *
+ * @param executor the executor on which result callback will be invoked.
+ * @param resultCallback a callback to receive the commit result. when the result is
+ * {@code 0}, it indicates success. Otherwise, failure.
+ *
+ * @throws IOException when there is an I/O error while committing the session.
+ * @throws SecurityException when the caller is not the owner of the session.
+ * @throws IllegalArgumentException when the passed parameters are not valid.
+ * @throws IllegalStateException when the caller tries to commit a session which was
+ * already finalized.
+ */
+ public void commit(@NonNull @CallbackExecutor Executor executor,
+ @NonNull Consumer<Integer> resultCallback) throws IOException {
+ try {
+ mSession.commit(new IBlobCommitCallback.Stub() {
+ public void onResult(int result) {
+ executor.execute(PooledLambda.obtainRunnable(
+ Consumer::accept, resultCallback, result));
+ }
+ });
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
}
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
new file mode 100644
index 0000000..a9b30e2
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobCommitCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright 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 android.app.blob;
+
+/** {@hide} */
+oneway interface IBlobCommitCallback {
+ void onResult(int result);
+}
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 00c1ed4..b7a2f1a 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -15,6 +15,16 @@
*/
package android.app.blob;
+import android.app.blob.BlobHandle;
+import android.app.blob.IBlobStoreSession;
+
/** {@hide} */
interface IBlobStoreManager {
+ long createSession(in BlobHandle handle, in String packageName);
+ IBlobStoreSession openSession(long sessionId);
+ ParcelFileDescriptor openBlob(in BlobHandle handle, in String packageName);
+
+ void acquireLease(in BlobHandle handle, int descriptionResId, long leaseTimeout,
+ in String packageName);
+ void releaseLease(in BlobHandle handle, in String packageName);
}
\ No newline at end of file
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
new file mode 100644
index 0000000..bb5ef3b
--- /dev/null
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreSession.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 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 android.app.blob;
+
+import android.app.blob.IBlobCommitCallback;
+import android.os.ParcelFileDescriptor;
+
+/** {@hide} */
+interface IBlobStoreSession {
+ ParcelFileDescriptor openWrite(long offsetBytes, long lengthBytes);
+
+ void allowPackageAccess(in String packageName, in byte[] certificate);
+ void allowSameSignatureAccess();
+ void allowPublicAccess();
+
+ long getSize();
+ void close();
+ void abandon();
+
+ void commit(in IBlobCommitCallback callback);
+}
\ No newline at end of file
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index d7cab59..b204fee 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -15,8 +15,14 @@
*/
package com.android.server.blob;
+import android.annotation.CurrentTimeSecondsLong;
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.app.blob.BlobHandle;
import android.app.blob.IBlobStoreManager;
+import android.app.blob.IBlobStoreSession;
import android.content.Context;
+import android.os.ParcelFileDescriptor;
import com.android.server.SystemService;
@@ -25,8 +31,11 @@
*/
public class BlobStoreManagerService extends SystemService {
+ private final Context mContext;
+
public BlobStoreManagerService(Context context) {
super(context);
+ mContext = context;
}
@Override
@@ -35,5 +44,29 @@
}
private class Stub extends IBlobStoreManager.Stub {
+ @Override
+ public long createSession(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+ return 0;
+ }
+
+ @Override
+ public IBlobStoreSession openSession(long sessionId) {
+ return null;
+ }
+
+ @Override
+ public ParcelFileDescriptor openBlob(@NonNull BlobHandle blobHandle,
+ @NonNull String packageName) {
+ return null;
+ }
+
+ @Override
+ public void acquireLease(@NonNull BlobHandle blobHandle, @IdRes int descriptionResId,
+ @CurrentTimeSecondsLong long leaseTimeout, @NonNull String packageName) {
+ }
+
+ @Override
+ public void releaseLease(@NonNull BlobHandle blobHandle, @NonNull String packageName) {
+ }
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
new file mode 100644
index 0000000..2c38e76
--- /dev/null
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 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.server.blob;
+
+import android.annotation.BytesLong;
+import android.annotation.NonNull;
+import android.app.blob.IBlobCommitCallback;
+import android.app.blob.IBlobStoreSession;
+import android.os.ParcelFileDescriptor;
+
+/** TODO: add doc */
+public class BlobStoreSession extends IBlobStoreSession.Stub {
+
+ @Override
+ @NonNull
+ public ParcelFileDescriptor openWrite(@BytesLong long offsetBytes,
+ @BytesLong long lengthBytes) {
+ return null;
+ }
+
+ @Override
+ @BytesLong
+ public long getSize() {
+ return 0;
+ }
+
+ @Override
+ public void allowPackageAccess(@NonNull String packageName,
+ @NonNull byte[] certificate) {
+ }
+
+ @Override
+ public void allowSameSignatureAccess() {
+ }
+
+ @Override
+ public void allowPublicAccess() {
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void abandon() {
+ }
+
+ @Override
+ public void commit(IBlobCommitCallback callback) {
+ }
+}
diff --git a/apex/statsd/aidl/Android.bp b/apex/statsd/aidl/Android.bp
index f8325d4..cc5172c6 100644
--- a/apex/statsd/aidl/Android.bp
+++ b/apex/statsd/aidl/Android.bp
@@ -23,7 +23,6 @@
"android/os/IPullAtomResultReceiver.aidl",
"android/os/IStatsCompanionService.aidl",
"android/os/IStatsd.aidl",
- "android/os/IStatsPullerCallback.aidl",
"android/util/StatsEventParcel.aidl",
],
}
diff --git a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl b/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
deleted file mode 100644
index c3e1e55..0000000
--- a/apex/statsd/aidl/android/os/IStatsPullerCallback.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.StatsLogEventWrapper;
-
-/**
- * DEPRECATED
- * Binder interface to pull atoms for the stats service.
- * {@hide}
- */
-interface IStatsPullerCallback {
- /**
- * Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
- * the data.
- *
- * Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
- * timestamps will be truncated to the nearest 5 minutes.
- */
- StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
-
-}
diff --git a/apex/statsd/aidl/android/os/IStatsd.aidl b/apex/statsd/aidl/android/os/IStatsd.aidl
index 0ecf2f0..a2564212 100644
--- a/apex/statsd/aidl/android/os/IStatsd.aidl
+++ b/apex/statsd/aidl/android/os/IStatsd.aidl
@@ -16,7 +16,6 @@
package android.os;
-import android.os.IStatsPullerCallback;
import android.os.IPendingIntentRef;
import android.os.IPullAtomCallback;
import android.os.ParcelFileDescriptor;
@@ -183,16 +182,6 @@
*/
void sendAppBreadcrumbAtom(int label, int state);
- /**
- * Registers a puller callback function that, when invoked, pulls the data
- * for the specified vendor atom tag.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
- * @deprecated please use registerPullAtomCallback.
- */
- oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
- String packageName);
-
/**
* Registers a puller callback function that, when invoked, pulls the data
* for the specified atom tag.
@@ -207,13 +196,6 @@
oneway void registerNativePullAtomCallback(int atomTag, long coolDownNs, long timeoutNs,
in int[] additiveFields, IPullAtomCallback pullerCallback);
- /**
- * Unregisters a puller callback function for the given vendor atom.
- *
- * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
- */
- oneway void unregisterPullerCallback(int atomTag, String packageName);
-
/**
* Unregisters any pullAtomCallback for the given uid/atom.
*/
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 17573bb..e5d1182 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -714,265 +714,6 @@
}
}
- private void pullSystemElapsedRealtime(
- int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeLong(SystemClock.elapsedRealtime());
- pulledData.add(e);
- }
-
- private void pullLooperStats(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- LooperStats looperStats = LocalServices.getService(LooperStats.class);
- if (looperStats == null) {
- throw new IllegalStateException("looperStats null");
- }
-
- List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
- looperStats.reset();
- for (LooperStats.ExportedEntry entry : entries) {
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(entry.workSourceUid);
- e.writeString(entry.handlerClassName);
- e.writeString(entry.threadName);
- e.writeString(entry.messageName);
- e.writeLong(entry.messageCount);
- e.writeLong(entry.exceptionCount);
- e.writeLong(entry.recordedMessageCount);
- e.writeLong(entry.totalLatencyMicros);
- e.writeLong(entry.cpuUsageMicros);
- e.writeBoolean(entry.isInteractive);
- e.writeLong(entry.maxCpuUsageMicros);
- e.writeLong(entry.maxLatencyMicros);
- e.writeLong(entry.recordedDelayMessageCount);
- e.writeLong(entry.delayMillis);
- e.writeLong(entry.maxDelayMillis);
- pulledData.add(e);
- }
- }
-
- private void pullDiskStats(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- // Run a quick-and-dirty performance test: write 512 bytes
- byte[] junk = new byte[512];
- for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
-
- File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
- FileOutputStream fos = null;
- IOException error = null;
-
- long before = SystemClock.elapsedRealtime();
- try {
- fos = new FileOutputStream(tmp);
- fos.write(junk);
- } catch (IOException e) {
- error = e;
- } finally {
- try {
- if (fos != null) fos.close();
- } catch (IOException e) {
- // Do nothing.
- }
- }
-
- long latency = SystemClock.elapsedRealtime() - before;
- if (tmp.exists()) tmp.delete();
-
- if (error != null) {
- Slog.e(TAG, "Error performing diskstats latency test");
- latency = -1;
- }
- // File based encryption.
- boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
-
- //Recent disk write speed. Binder call to storaged.
- int writeSpeed = -1;
- try {
- IBinder binder = ServiceManager.getService("storaged");
- if (binder == null) {
- Slog.e(TAG, "storaged not found");
- }
- IStoraged storaged = IStoraged.Stub.asInterface(binder);
- writeSpeed = storaged.getRecentPerf();
- } catch (RemoteException e) {
- Slog.e(TAG, "storaged not found");
- }
-
- // Add info pulledData.
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeLong(latency);
- e.writeBoolean(fileBased);
- e.writeInt(writeSpeed);
- pulledData.add(e);
- }
-
- private void pullDirectoryUsage(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
- StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
- StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA);
- e.writeLong(statFsData.getAvailableBytes());
- e.writeLong(statFsData.getTotalBytes());
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE);
- e.writeLong(statFsCache.getAvailableBytes());
- e.writeLong(statFsCache.getTotalBytes());
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM);
- e.writeLong(statFsSystem.getAvailableBytes());
- e.writeLong(statFsSystem.getTotalBytes());
- pulledData.add(e);
- }
-
- private void pullAppSize(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- try {
- String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
- JSONObject json = new JSONObject(jsonStr);
- long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
- JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
- JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
- JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
- JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
- // Sanity check: Ensure all 4 lists have the same length.
- int length = pkg_names.length();
- if (app_sizes.length() != length || app_data_sizes.length() != length
- || app_cache_sizes.length() != length) {
- Slog.e(TAG, "formatting error in diskstats cache file!");
- return;
- }
- for (int i = 0; i < length; i++) {
- StatsLogEventWrapper e =
- new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeString(pkg_names.getString(i));
- e.writeLong(app_sizes.optLong(i, -1L));
- e.writeLong(app_data_sizes.optLong(i, -1L));
- e.writeLong(app_cache_sizes.optLong(i, -1L));
- e.writeLong(cache_time);
- pulledData.add(e);
- }
- } catch (IOException | JSONException e) {
- Slog.e(TAG, "exception reading diskstats cache file", e);
- }
- }
-
- private void pullCategorySize(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- try {
- String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
- JSONObject json = new JSONObject(jsonStr);
- long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE);
- e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE);
- e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE);
- e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS);
- e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS);
- e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO);
- e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS);
- e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM);
- e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
-
- e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER);
- e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L));
- e.writeLong(cacheTime);
- pulledData.add(e);
- } catch (IOException | JSONException e) {
- Slog.e(TAG, "exception reading diskstats cache file", e);
- }
- }
-
- private void pullNumBiometricsEnrolled(int modality, int tagId, long elapsedNanos,
- long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
- final PackageManager pm = mContext.getPackageManager();
- FingerprintManager fingerprintManager = null;
- FaceManager faceManager = null;
-
- if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
- fingerprintManager = mContext.getSystemService(
- FingerprintManager.class);
- }
- if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
- faceManager = mContext.getSystemService(FaceManager.class);
- }
-
- if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
- return;
- }
- if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
- return;
- }
- UserManager userManager = mContext.getSystemService(UserManager.class);
- if (userManager == null) {
- return;
- }
-
- final long token = Binder.clearCallingIdentity();
- for (UserInfo user : userManager.getUsers()) {
- final int userId = user.getUserHandle().getIdentifier();
- int numEnrolled = 0;
- if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
- numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
- } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
- numEnrolled = faceManager.getEnrolledFaces(userId).size();
- } else {
- return;
- }
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(userId);
- e.writeInt(numEnrolled);
- pulledData.add(e);
- }
- Binder.restoreCallingIdentity(token);
- }
-
// read high watermark for section
private long readProcStatsHighWaterMark(int section) {
try {
@@ -1024,39 +765,6 @@
}
}
- private INotificationManager mNotificationManager =
- INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-
- private void pullNotificationStats(int reportId, int tagId, long elapsedNanos,
- long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- final long callingToken = Binder.clearCallingIdentity();
- try {
- // determine last pull tine. Copy file trick from pullProcessStats?
- long lastNotificationStatsNs = wallClockNanos -
- TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
-
- List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
- long notificationStatsNs = mNotificationManager.pullStats(
- lastNotificationStatsNs, reportId, true, statsFiles);
- if (statsFiles.size() != 1) {
- return;
- }
- unpackStreamedData(tagId, elapsedNanos, wallClockNanos, pulledData, statsFiles);
- } catch (IOException e) {
- Log.e(TAG, "Getting notistats failed: ", e);
-
- } catch (RemoteException e) {
- Log.e(TAG, "Getting notistats failed: ", e);
- } catch (SecurityException e) {
- Log.e(TAG, "Getting notistats failed: ", e);
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
-
- }
-
static void unpackStreamedData(int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData, List<ParcelFileDescriptor> statsFiles)
throws IOException {
@@ -1098,104 +806,6 @@
}
}
- private void pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
- fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
- fgFsync, bgFsync) -> {
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
- wallClockNanos);
- e.writeInt(uid);
- e.writeLong(fgCharsRead);
- e.writeLong(fgCharsWrite);
- e.writeLong(fgBytesRead);
- e.writeLong(fgBytesWrite);
- e.writeLong(bgCharsRead);
- e.writeLong(bgCharsWrite);
- e.writeLong(bgBytesRead);
- e.writeLong(bgBytesWrite);
- e.writeLong(fgFsync);
- e.writeLong(bgFsync);
- pulledData.add(e);
- });
- }
-
- private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- synchronized (this) {
- if (mProcessCpuTracker == null) {
- mProcessCpuTracker = new ProcessCpuTracker(false);
- mProcessCpuTracker.init();
- }
- mProcessCpuTracker.update();
- for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
- ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
- wallClockNanos);
- e.writeInt(st.uid);
- e.writeString(st.name);
- e.writeLong(st.base_utime);
- e.writeLong(st.base_stime);
- pulledData.add(e);
- }
- }
- }
-
- private void pullCpuTimePerThreadFreq(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- if (this.mKernelCpuThreadReader == null) {
- throw new IllegalStateException("mKernelCpuThreadReader is null");
- }
- ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
- this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
- if (processCpuUsages == null) {
- throw new IllegalStateException("processCpuUsages is null");
- }
- int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
- if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
- String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
- + " frequencies, but got " + cpuFrequencies.length;
- Slog.w(TAG, message);
- throw new IllegalStateException(message);
- }
- for (int i = 0; i < processCpuUsages.size(); i++) {
- KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
- ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
- processCpuUsage.threadCpuUsages;
- for (int j = 0; j < threadCpuUsages.size(); j++) {
- KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
- if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
- String message = "Unexpected number of usage times,"
- + " expected " + cpuFrequencies.length
- + " but got " + threadCpuUsage.usageTimesMillis.length;
- Slog.w(TAG, message);
- throw new IllegalStateException(message);
- }
-
- StatsLogEventWrapper e =
- new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(processCpuUsage.uid);
- e.writeInt(processCpuUsage.processId);
- e.writeInt(threadCpuUsage.threadId);
- e.writeString(processCpuUsage.processName);
- e.writeString(threadCpuUsage.threadName);
- for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
- if (k < cpuFrequencies.length) {
- e.writeInt(cpuFrequencies[k]);
- e.writeInt(threadCpuUsage.usageTimesMillis[k]);
- } else {
- // If we have no more frequencies to write, we still must write empty data.
- // We know that this data is empty (and not just zero) because all
- // frequencies are expected to be greater than zero
- e.writeInt(0);
- e.writeInt(0);
- }
- }
- pulledData.add(e);
- }
- }
- }
-
private void pullDebugElapsedClock(int tagId,
long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
final long elapsedMillis = SystemClock.elapsedRealtime();
@@ -1246,283 +856,6 @@
pulledData.add(e);
}
- private void pullDangerousPermissionState(int atomId, long elapsedNanos,
- final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
- long token = Binder.clearCallingIdentity();
- Set<Integer> reportedUids = new HashSet<>();
- try {
- PackageManager pm = mContext.getPackageManager();
-
- List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
- int numUsers = users.size();
- for (int userNum = 0; userNum < numUsers; userNum++) {
- UserHandle user = users.get(userNum).getUserHandle();
-
- List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
- PackageManager.GET_PERMISSIONS, user.getIdentifier());
-
- int numPkgs = pkgs.size();
- for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
- PackageInfo pkg = pkgs.get(pkgNum);
-
- if (pkg.requestedPermissions == null) {
- continue;
- }
-
- if (reportedUids.contains(pkg.applicationInfo.uid)) {
- // do not report same uid twice
- continue;
- }
- reportedUids.add(pkg.applicationInfo.uid);
-
- if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
- && ThreadLocalRandom.current().nextFloat() > 0.2f) {
- continue;
- }
-
- int numPerms = pkg.requestedPermissions.length;
- for (int permNum = 0; permNum < numPerms; permNum++) {
- String permName = pkg.requestedPermissions[permNum];
-
- PermissionInfo permissionInfo;
- int permissionFlags = 0;
- try {
- permissionInfo = pm.getPermissionInfo(permName, 0);
- permissionFlags =
- pm.getPermissionFlags(permName, pkg.packageName, user);
-
- } catch (PackageManager.NameNotFoundException ignored) {
- continue;
- }
-
- if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
- continue;
- }
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(
- atomId, elapsedNanos, wallClockNanos);
-
- e.writeString(permName);
- e.writeInt(pkg.applicationInfo.uid);
- if (atomId == StatsLog.DANGEROUS_PERMISSION_STATE) {
- e.writeString(null);
- }
- e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
- & REQUESTED_PERMISSION_GRANTED) != 0);
- e.writeInt(permissionFlags);
-
- pulledData.add(e);
- }
- }
- }
- } catch (Throwable t) {
- Log.e(TAG, "Could not read permissions", t);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private void pullAppOps(long elapsedNanos, final long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- long token = Binder.clearCallingIdentity();
- try {
- AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
-
- CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
- HistoricalOpsRequest histOpsRequest =
- new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
- appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
-
- HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
- TimeUnit.MILLISECONDS);
-
- for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
- final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
- final int uid = uidOps.getUid();
- for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
- final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
- for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
- final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
- StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS,
- elapsedNanos, wallClockNanos);
-
- e.writeInt(uid);
- e.writeString(packageOps.getPackageName());
- e.writeInt(op.getOpCode());
- e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
- e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
- e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
- e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
- e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
- e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
-
- String perm = AppOpsManager.opToPermission(op.getOpCode());
- if (perm == null) {
- e.writeBoolean(false);
- } else {
- PermissionInfo permInfo;
- try {
- permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
- e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
- } catch (PackageManager.NameNotFoundException exception) {
- e.writeBoolean(false);
- }
- }
-
- pulledData.add(e);
- }
- }
- }
- } catch (Throwable t) {
- Log.e(TAG, "Could not read appops", t);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
-
- /**
- * Add a RoleHolder atom for each package that holds a role.
- *
- * @param elapsedNanos the time since boot
- * @param wallClockNanos the time on the clock
- * @param pulledData the data sink to write to
- */
- private void pullRoleHolders(long elapsedNanos, final long wallClockNanos,
- @NonNull List<StatsLogEventWrapper> pulledData) {
- long callingToken = Binder.clearCallingIdentity();
- try {
- PackageManager pm = mContext.getPackageManager();
- RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
-
- List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
-
- int numUsers = users.size();
- for (int userNum = 0; userNum < numUsers; userNum++) {
- int userId = users.get(userNum).getUserHandle().getIdentifier();
-
- ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(
- userId);
-
- int numRoles = roles.size();
- for (int roleNum = 0; roleNum < numRoles; roleNum++) {
- String roleName = roles.keyAt(roleNum);
- ArraySet<String> holders = roles.valueAt(roleNum);
-
- int numHolders = holders.size();
- for (int holderNum = 0; holderNum < numHolders; holderNum++) {
- String holderName = holders.valueAt(holderNum);
-
- PackageInfo pkg;
- try {
- pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Role holder " + holderName + " not found");
- return;
- }
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER,
- elapsedNanos, wallClockNanos);
- e.writeInt(pkg.applicationInfo.uid);
- e.writeString(holderName);
- e.writeString(roleName);
- pulledData.add(e);
- }
- }
- }
- } finally {
- Binder.restoreCallingIdentity(callingToken);
- }
- }
-
- private void pullTimeZoneDataInfo(int tagId,
- long elapsedNanos, long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
- String tzDbVersion = "Unknown";
- try {
- tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
- } catch (Exception e) {
- Log.e(TAG, "Getting tzdb version failed: ", e);
- }
-
- StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeString(tzDbVersion);
- pulledData.add(e);
- }
-
- private void pullExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- StorageManager storageManager = mContext.getSystemService(StorageManager.class);
- if (storageManager != null) {
- List<VolumeInfo> volumes = storageManager.getVolumes();
- for (VolumeInfo vol : volumes) {
- final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
- final DiskInfo diskInfo = vol.getDisk();
- if (diskInfo != null) {
- if (envState.equals(Environment.MEDIA_MOUNTED)) {
- // Get the type of the volume, if it is adoptable or portable.
- int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
- if (vol.getType() == TYPE_PUBLIC) {
- volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
- } else if (vol.getType() == TYPE_PRIVATE) {
- volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
- }
- // Get the type of external storage inserted in the device (sd cards,
- // usb, etc)
- int externalStorageType;
- if (diskInfo.isSd()) {
- externalStorageType = StorageEnums.SD_CARD;
- } else if (diskInfo.isUsb()) {
- externalStorageType = StorageEnums.USB;
- } else {
- externalStorageType = StorageEnums.OTHER;
- }
- StatsLogEventWrapper e =
- new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(externalStorageType);
- e.writeInt(volumeType);
- e.writeLong(diskInfo.size);
- pulledData.add(e);
- }
- }
- }
- }
- }
-
- private void pullAppsOnExternalStorageInfo(int tagId, long elapsedNanos, long wallClockNanos,
- List<StatsLogEventWrapper> pulledData) {
- PackageManager pm = mContext.getPackageManager();
- StorageManager storage = mContext.getSystemService(StorageManager.class);
- List<ApplicationInfo> apps = pm.getInstalledApplications(/* flags = */ 0);
- for (ApplicationInfo appInfo : apps) {
- UUID storageUuid = appInfo.storageUuid;
- if (storageUuid != null) {
- VolumeInfo volumeInfo = storage.findVolumeByUuid(appInfo.storageUuid.toString());
- if (volumeInfo != null) {
- DiskInfo diskInfo = volumeInfo.getDisk();
- if (diskInfo != null) {
- int externalStorageType = -1;
- if (diskInfo.isSd()) {
- externalStorageType = StorageEnums.SD_CARD;
- } else if (diskInfo.isUsb()) {
- externalStorageType = StorageEnums.USB;
- } else if (appInfo.isExternal()) {
- externalStorageType = StorageEnums.OTHER;
- }
- // App is installed on external storage.
- if (externalStorageType != -1) {
- StatsLogEventWrapper e =
- new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(externalStorageType);
- e.writeString(appInfo.packageName);
- pulledData.add(e);
- }
- }
- }
- }
- }
- }
-
private void pullFaceSettings(int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long callingToken = Binder.clearCallingIdentity();
@@ -1574,48 +907,6 @@
long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
switch (tagId) {
- case StatsLog.SYSTEM_ELAPSED_REALTIME: {
- pullSystemElapsedRealtime(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.LOOPER_STATS: {
- pullLooperStats(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.DISK_STATS: {
- pullDiskStats(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.DIRECTORY_USAGE: {
- pullDirectoryUsage(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.APP_SIZE: {
- pullAppSize(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.CATEGORY_SIZE: {
- pullCategorySize(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.NUM_FINGERPRINTS_ENROLLED: {
- pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FINGERPRINT, tagId,
- elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.NUM_FACES_ENROLLED: {
- pullNumBiometricsEnrolled(BiometricsProtoEnums.MODALITY_FACE, tagId, elapsedNanos,
- wallClockNanos, ret);
- break;
- }
-
case StatsLog.PROC_STATS: {
pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
break;
@@ -1627,20 +918,6 @@
break;
}
- case StatsLog.DISK_IO: {
- pullDiskIo(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.PROCESS_CPU_TIME: {
- pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
- case StatsLog.CPU_TIME_PER_THREAD_FREQ: {
- pullCpuTimePerThreadFreq(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
case StatsLog.DEBUG_ELAPSED_CLOCK: {
pullDebugElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
break;
@@ -1651,54 +928,11 @@
break;
}
- case StatsLog.ROLE_HOLDER: {
- pullRoleHolders(elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.DANGEROUS_PERMISSION_STATE: {
- pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE, elapsedNanos,
- wallClockNanos, ret);
- break;
- }
-
- case StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED: {
- pullDangerousPermissionState(StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED,
- elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.TIME_ZONE_DATA_INFO: {
- pullTimeZoneDataInfo(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.EXTERNAL_STORAGE_INFO: {
- pullExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO: {
- pullAppsOnExternalStorageInfo(tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
case StatsLog.FACE_SETTINGS: {
pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
- case StatsLog.APP_OPS: {
- pullAppOps(elapsedNanos, wallClockNanos, ret);
- break;
- }
-
- case StatsLog.NOTIFICATION_REMOTE_VIEWS: {
- pullNotificationStats(NotificationManagerService.REPORT_REMOTE_VIEWS,
- tagId, elapsedNanos, wallClockNanos, ret);
- break;
- }
-
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;
diff --git a/api/current.txt b/api/current.txt
index 0812019..e662783 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7451,6 +7451,41 @@
}
+package android.app.blob {
+
+ public final class BlobHandle implements android.os.Parcelable {
+ method @NonNull public static android.app.blob.BlobHandle createWithSha256(@NonNull byte[], @NonNull CharSequence, long, @NonNull String);
+ method public int describeContents();
+ method public long getExpiryTimeMillis();
+ method @NonNull public CharSequence getLabel();
+ method @NonNull public byte[] getSha256Digest();
+ method @NonNull public String getTag();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.blob.BlobHandle> CREATOR;
+ }
+
+ public class BlobStoreManager {
+ method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int, long) throws java.io.IOException;
+ method public void acquireLease(@NonNull android.app.blob.BlobHandle, @IdRes int) throws java.io.IOException;
+ method @IntRange(from=1) public long createSession(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+ method @NonNull public android.os.ParcelFileDescriptor openBlob(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+ method @NonNull public android.app.blob.BlobStoreManager.Session openSession(@IntRange(from=1) long) throws java.io.IOException;
+ method public void releaseLease(@NonNull android.app.blob.BlobHandle) throws java.io.IOException;
+ }
+
+ public static class BlobStoreManager.Session implements java.io.Closeable {
+ method public void abandon() throws java.io.IOException;
+ method public void allowPackageAccess(@NonNull String, @NonNull byte[]) throws java.io.IOException;
+ method public void allowPublicAccess() throws java.io.IOException;
+ method public void allowSameSignatureAccess() throws java.io.IOException;
+ method public void close() throws java.io.IOException;
+ method public void commit(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws java.io.IOException;
+ method public long getSize() throws java.io.IOException;
+ method @NonNull public android.os.ParcelFileDescriptor openWrite(long, long) throws java.io.IOException;
+ }
+
+}
+
package android.app.job {
public class JobInfo implements android.os.Parcelable {
@@ -18266,6 +18301,7 @@
field public static final int RIGHT = 7; // 0x7
field public static final int TOP = 8; // 0x8
field public static final int TOP_AND_BOTTOM = 9; // 0x9
+ field public static final int TOP_AND_BOTTOM_AND_LEFT = 15; // 0xf
field public static final int TOP_AND_BOTTOM_AND_RIGHT = 10; // 0xa
field public static final int TOP_AND_LEFT = 11; // 0xb
field public static final int TOP_AND_LEFT_AND_RIGHT = 12; // 0xc
@@ -18588,6 +18624,7 @@
field public static final int CHEROKEE_SUPPLEMENT_ID = 255; // 0xff
field public static final android.icu.lang.UCharacter.UnicodeBlock CHESS_SYMBOLS;
field public static final int CHESS_SYMBOLS_ID = 281; // 0x119
+ field public static final int CHORASMIAN_ID = 301; // 0x12d
field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY;
field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_COMPATIBILITY_FORMS;
field public static final int CJK_COMPATIBILITY_FORMS_ID = 83; // 0x53
@@ -18615,6 +18652,7 @@
field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E_ID = 256; // 0x100
field public static final android.icu.lang.UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F;
field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_F_ID = 274; // 0x112
+ field public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_G_ID = 302; // 0x12e
field public static final int CJK_UNIFIED_IDEOGRAPHS_ID = 71; // 0x47
field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
field public static final android.icu.lang.UCharacter.UnicodeBlock COMBINING_DIACRITICAL_MARKS_EXTENDED;
@@ -18664,6 +18702,7 @@
field public static final int DEVANAGARI_ID = 15; // 0xf
field public static final android.icu.lang.UCharacter.UnicodeBlock DINGBATS;
field public static final int DINGBATS_ID = 56; // 0x38
+ field public static final int DIVES_AKURU_ID = 303; // 0x12f
field public static final android.icu.lang.UCharacter.UnicodeBlock DOGRA;
field public static final int DOGRA_ID = 282; // 0x11a
field public static final android.icu.lang.UCharacter.UnicodeBlock DOMINO_TILES;
@@ -18792,6 +18831,8 @@
field public static final int KAYAH_LI_ID = 162; // 0xa2
field public static final android.icu.lang.UCharacter.UnicodeBlock KHAROSHTHI;
field public static final int KHAROSHTHI_ID = 137; // 0x89
+ field public static final android.icu.lang.UCharacter.UnicodeBlock KHITAN_SMALL_SCRIPT;
+ field public static final int KHITAN_SMALL_SCRIPT_ID = 304; // 0x130
field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER;
field public static final int KHMER_ID = 36; // 0x24
field public static final android.icu.lang.UCharacter.UnicodeBlock KHMER_SYMBOLS;
@@ -18830,6 +18871,8 @@
field public static final int LINEAR_B_SYLLABARY_ID = 117; // 0x75
field public static final android.icu.lang.UCharacter.UnicodeBlock LISU;
field public static final int LISU_ID = 176; // 0xb0
+ field public static final android.icu.lang.UCharacter.UnicodeBlock LISU_SUPPLEMENT;
+ field public static final int LISU_SUPPLEMENT_ID = 305; // 0x131
field public static final android.icu.lang.UCharacter.UnicodeBlock LOW_SURROGATES;
field public static final int LOW_SURROGATES_ID = 77; // 0x4d
field public static final android.icu.lang.UCharacter.UnicodeBlock LYCIAN;
@@ -19041,6 +19084,8 @@
field public static final int SYLOTI_NAGRI_ID = 143; // 0x8f
field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A;
field public static final int SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A_ID = 298; // 0x12a
+ field public static final android.icu.lang.UCharacter.UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING;
+ field public static final int SYMBOLS_FOR_LEGACY_COMPUTING_ID = 306; // 0x132
field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC;
field public static final int SYRIAC_ID = 13; // 0xd
field public static final android.icu.lang.UCharacter.UnicodeBlock SYRIAC_SUPPLEMENT;
@@ -19069,6 +19114,8 @@
field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_COMPONENTS;
field public static final int TANGUT_COMPONENTS_ID = 273; // 0x111
field public static final int TANGUT_ID = 272; // 0x110
+ field public static final android.icu.lang.UCharacter.UnicodeBlock TANGUT_SUPPLEMENT;
+ field public static final int TANGUT_SUPPLEMENT_ID = 307; // 0x133
field public static final android.icu.lang.UCharacter.UnicodeBlock TELUGU;
field public static final int TELUGU_ID = 21; // 0x15
field public static final android.icu.lang.UCharacter.UnicodeBlock THAANA;
@@ -19103,6 +19150,8 @@
field public static final int WANCHO_ID = 300; // 0x12c
field public static final android.icu.lang.UCharacter.UnicodeBlock WARANG_CITI;
field public static final int WARANG_CITI_ID = 252; // 0xfc
+ field public static final android.icu.lang.UCharacter.UnicodeBlock YEZIDI;
+ field public static final int YEZIDI_ID = 308; // 0x134
field public static final android.icu.lang.UCharacter.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
field public static final int YIJING_HEXAGRAM_SYMBOLS_ID = 116; // 0x74
field public static final android.icu.lang.UCharacter.UnicodeBlock YI_RADICALS;
@@ -19399,6 +19448,7 @@
field public static final int CHAKMA = 118; // 0x76
field public static final int CHAM = 66; // 0x42
field public static final int CHEROKEE = 6; // 0x6
+ field public static final int CHORASMIAN = 189; // 0xbd
field public static final int CIRTH = 67; // 0x43
field public static final int COMMON = 0; // 0x0
field public static final int COPTIC = 7; // 0x7
@@ -19408,6 +19458,7 @@
field public static final int DEMOTIC_EGYPTIAN = 69; // 0x45
field public static final int DESERET = 9; // 0x9
field public static final int DEVANAGARI = 10; // 0xa
+ field public static final int DIVES_AKURU = 190; // 0xbe
field public static final int DOGRA = 178; // 0xb2
field public static final int DUPLOYAN = 135; // 0x87
field public static final int EASTERN_SYRIAC = 97; // 0x61
@@ -19449,6 +19500,7 @@
field public static final int KATAKANA_OR_HIRAGANA = 54; // 0x36
field public static final int KAYAH_LI = 79; // 0x4f
field public static final int KHAROSHTHI = 57; // 0x39
+ field public static final int KHITAN_SMALL_SCRIPT = 191; // 0xbf
field public static final int KHMER = 23; // 0x17
field public static final int KHOJKI = 157; // 0x9d
field public static final int KHUDAWADI = 145; // 0x91
@@ -19566,6 +19618,7 @@
field public static final int WARANG_CITI = 146; // 0x92
field public static final int WESTERN_SYRIAC = 96; // 0x60
field public static final int WOLEAI = 155; // 0x9b
+ field public static final int YEZIDI = 192; // 0xc0
field public static final int YI = 41; // 0x29
field public static final int ZANABAZAR_SQUARE = 177; // 0xb1
}
@@ -24346,28 +24399,39 @@
method public static boolean hasProfile(int, int);
field public static final int QUALITY_1080P = 6; // 0x6
field public static final int QUALITY_2160P = 8; // 0x8
+ field public static final int QUALITY_2K = 12; // 0xc
field public static final int QUALITY_480P = 4; // 0x4
+ field public static final int QUALITY_4KDCI = 10; // 0xa
field public static final int QUALITY_720P = 5; // 0x5
field public static final int QUALITY_CIF = 3; // 0x3
field public static final int QUALITY_HIGH = 1; // 0x1
field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4
field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5
field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2
+ field public static final int QUALITY_HIGH_SPEED_4KDCI = 2008; // 0x7d8
field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3
+ field public static final int QUALITY_HIGH_SPEED_CIF = 2006; // 0x7d6
field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1
field public static final int QUALITY_HIGH_SPEED_LOW = 2000; // 0x7d0
+ field public static final int QUALITY_HIGH_SPEED_VGA = 2007; // 0x7d7
field public static final int QUALITY_LOW = 0; // 0x0
field public static final int QUALITY_QCIF = 2; // 0x2
+ field public static final int QUALITY_QHD = 11; // 0xb
field public static final int QUALITY_QVGA = 7; // 0x7
field public static final int QUALITY_TIME_LAPSE_1080P = 1006; // 0x3ee
field public static final int QUALITY_TIME_LAPSE_2160P = 1008; // 0x3f0
+ field public static final int QUALITY_TIME_LAPSE_2K = 1012; // 0x3f4
field public static final int QUALITY_TIME_LAPSE_480P = 1004; // 0x3ec
+ field public static final int QUALITY_TIME_LAPSE_4KDCI = 1010; // 0x3f2
field public static final int QUALITY_TIME_LAPSE_720P = 1005; // 0x3ed
field public static final int QUALITY_TIME_LAPSE_CIF = 1003; // 0x3eb
field public static final int QUALITY_TIME_LAPSE_HIGH = 1001; // 0x3e9
field public static final int QUALITY_TIME_LAPSE_LOW = 1000; // 0x3e8
field public static final int QUALITY_TIME_LAPSE_QCIF = 1002; // 0x3ea
+ field public static final int QUALITY_TIME_LAPSE_QHD = 1011; // 0x3f3
field public static final int QUALITY_TIME_LAPSE_QVGA = 1007; // 0x3ef
+ field public static final int QUALITY_TIME_LAPSE_VGA = 1009; // 0x3f1
+ field public static final int QUALITY_VGA = 9; // 0x9
field public int audioBitRate;
field public int audioChannels;
field public int audioCodec;
@@ -30203,6 +30267,7 @@
method public void close();
method public void continueCall(int) throws android.net.sip.SipException;
method public void endCall() throws android.net.sip.SipException;
+ method @Nullable public android.net.rtp.AudioGroup getAudioGroup();
method public android.net.sip.SipProfile getLocalProfile();
method public android.net.sip.SipProfile getPeerProfile();
method public int getState();
@@ -30213,6 +30278,7 @@
method public void makeCall(android.net.sip.SipProfile, android.net.sip.SipSession, int) throws android.net.sip.SipException;
method public void sendDtmf(int);
method public void sendDtmf(int, android.os.Message);
+ method public void setAudioGroup(@NonNull android.net.rtp.AudioGroup);
method public void setListener(android.net.sip.SipAudioCall.Listener);
method public void setListener(android.net.sip.SipAudioCall.Listener, boolean);
method public void setSpeakerMode(boolean);
@@ -30261,6 +30327,7 @@
method public void close(String) throws android.net.sip.SipException;
method public android.net.sip.SipSession createSipSession(android.net.sip.SipProfile, android.net.sip.SipSession.Listener) throws android.net.sip.SipException;
method public static String getCallId(android.content.Intent);
+ method @NonNull public java.util.List<android.net.sip.SipProfile> getListOfProfiles() throws android.net.sip.SipException;
method public static String getOfferSessionDescription(android.content.Intent);
method public android.net.sip.SipSession getSessionFor(android.content.Intent) throws android.net.sip.SipException;
method public static boolean isApiSupported(android.content.Context);
@@ -30278,6 +30345,11 @@
method public void setRegistrationListener(String, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
method public android.net.sip.SipAudioCall takeAudioCall(android.content.Intent, android.net.sip.SipAudioCall.Listener) throws android.net.sip.SipException;
method public void unregister(android.net.sip.SipProfile, android.net.sip.SipRegistrationListener) throws android.net.sip.SipException;
+ field public static final String ACTION_SIP_CALL_OPTION_CHANGED = "android.net.sip.action.SIP_CALL_OPTION_CHANGED";
+ field public static final String ACTION_SIP_INCOMING_CALL = "android.net.sip.action.SIP_INCOMING_CALL";
+ field public static final String ACTION_SIP_REMOVE_PROFILE = "android.net.sip.action.SIP_REMOVE_PROFILE";
+ field public static final String ACTION_SIP_SERVICE_UP = "android.net.sip.action.SIP_SERVICE_UP";
+ field public static final String ACTION_START_SIP = "android.net.sip.action.START_SIP";
field public static final String EXTRA_CALL_ID = "android:sipCallID";
field public static final String EXTRA_OFFER_SD = "android:sipOfferSD";
field public static final int INCOMING_CALL_RESULT_CODE = 101; // 0x65
@@ -30287,6 +30359,7 @@
method public int describeContents();
method public String getAuthUserName();
method public boolean getAutoRegistration();
+ method public int getCallingUid();
method public String getDisplayName();
method public String getPassword();
method public int getPort();
@@ -30297,6 +30370,7 @@
method public String getSipDomain();
method public String getUriString();
method public String getUserName();
+ method public void setCallingUid(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.sip.SipProfile> CREATOR;
}
@@ -45043,6 +45117,8 @@
package android.telephony {
public final class AccessNetworkConstants {
+ field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+ field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
}
public static final class AccessNetworkConstants.AccessNetworkType {
@@ -45391,6 +45467,7 @@
field public static final String KEY_MMS_ALIAS_MIN_CHARS_INT = "aliasMinChars";
field public static final String KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL = "allowAttachAudio";
field public static final String KEY_MMS_APPEND_TRANSACTION_ID_BOOL = "enabledTransID";
+ field public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
field public static final String KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING = "emailGatewayNumber";
field public static final String KEY_MMS_GROUP_MMS_ENABLED_BOOL = "enableGroupMms";
field public static final String KEY_MMS_HTTP_PARAMS_STRING = "httpParams";
@@ -45588,7 +45665,8 @@
method public int getCellConnectionStatus();
method @NonNull public abstract android.telephony.CellIdentity getCellIdentity();
method @NonNull public abstract android.telephony.CellSignalStrength getCellSignalStrength();
- method public long getTimeStamp();
+ method @Deprecated public long getTimeStamp();
+ method public long getTimestampNanos();
method public boolean isRegistered();
field public static final int CONNECTION_NONE = 0; // 0x0
field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1
@@ -45828,6 +45906,35 @@
field @Deprecated public static final int UNKNOWN_RSSI = 99; // 0x63
}
+ public final class NetworkRegistrationInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAccessNetworkTechnology();
+ method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+ method @Nullable public android.telephony.CellIdentity getCellIdentity();
+ method public int getDomain();
+ method public int getNrState();
+ method public int getTransportType();
+ method public boolean isRegistered();
+ method public boolean isRoaming();
+ method public boolean isSearching();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+ field public static final int DOMAIN_CS = 1; // 0x1
+ field public static final int DOMAIN_CS_PS = 3; // 0x3
+ field public static final int DOMAIN_PS = 2; // 0x2
+ field public static final int DOMAIN_UNKNOWN = 0; // 0x0
+ field public static final int NR_STATE_CONNECTED = 3; // 0x3
+ field public static final int NR_STATE_NONE = 0; // 0x0
+ field public static final int NR_STATE_NOT_RESTRICTED = 2; // 0x2
+ field public static final int NR_STATE_RESTRICTED = 1; // 0x1
+ field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+ field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+ field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+ field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+ field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+ }
+
public class NetworkScan {
method public void stopScan();
field public static final int ERROR_INTERRUPTED = 10002; // 0x2712
@@ -46002,6 +46109,7 @@
method public int getChannelNumber();
method public int getDuplexMode();
method public boolean getIsManualSelection();
+ method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
method public String getOperatorAlphaLong();
method public String getOperatorAlphaShort();
method public String getOperatorNumeric();
@@ -46038,6 +46146,7 @@
method @Deprecated public int getGsmBitErrorRate();
method @Deprecated public int getGsmSignalStrength();
method public int getLevel();
+ method public long getTimestampNanos();
method @Deprecated public boolean isGsm();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SignalStrength> CREATOR;
@@ -46060,7 +46169,9 @@
method public void sendDataMessage(String, String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
method @Deprecated public void sendMultimediaMessage(android.content.Context, android.net.Uri, String, android.os.Bundle, android.app.PendingIntent);
method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
+ method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, long);
method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
+ method public void sendTextMessage(@NonNull String, @Nullable String, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent, long);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSmscAddress(@NonNull String);
field public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
@@ -46432,6 +46543,7 @@
method @Deprecated public String iccTransmitApduBasicChannel(int, int, int, int, int, String);
method @Deprecated public String iccTransmitApduLogicalChannel(int, int, int, int, int, int, String);
method public boolean isConcurrentVoiceAndDataSupported();
+ method public boolean isDataCapable();
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean isDataEnabled();
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
method public boolean isEmergencyNumber(@NonNull String);
@@ -71910,6 +72022,18 @@
method public int lastIndexOf(@Nullable Object);
method @NonNull public java.util.ListIterator<E> listIterator();
method @NonNull public java.util.ListIterator<E> listIterator(int);
+ method @NonNull public static <E> java.util.List<E> of();
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull @java.lang.SafeVarargs public static <E> java.util.List<E> of(@NonNull E...);
method public E remove(int);
method public default void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
method public E set(int, E);
@@ -72064,6 +72188,7 @@
method @Nullable public default V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
method public boolean containsKey(@Nullable Object);
method public boolean containsValue(@Nullable Object);
+ method @NonNull public static <K, V> java.util.Map.Entry<K,V> entry(@NonNull K, @NonNull V);
method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
method public boolean equals(@Nullable Object);
method public default void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
@@ -72073,6 +72198,18 @@
method public boolean isEmpty();
method @NonNull public java.util.Set<K> keySet();
method @Nullable public default V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+ method @NonNull public static <K, V> java.util.Map<K,V> of();
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+ method @NonNull @java.lang.SafeVarargs public static <K, V> java.util.Map<K,V> ofEntries(@NonNull java.util.Map.Entry<? extends K,? extends V>...);
method @Nullable public V put(K, V);
method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
method @Nullable public default V putIfAbsent(K, V);
@@ -72154,6 +72291,9 @@
}
public final class Objects {
+ method public static int checkFromIndexSize(int, int, int);
+ method public static int checkFromToIndex(int, int, int);
+ method public static int checkIndex(int, int);
method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
method public static boolean deepEquals(@Nullable Object, @Nullable Object);
method public static boolean equals(@Nullable Object, @Nullable Object);
@@ -72164,6 +72304,8 @@
method @NonNull public static <T> T requireNonNull(@Nullable T);
method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull String);
method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull java.util.function.Supplier<java.lang.String>);
+ method @NonNull public static <T> T requireNonNullElse(@Nullable T, @NonNull T);
+ method @NonNull public static <T> T requireNonNullElseGet(@Nullable T, @NonNull java.util.function.Supplier<? extends T>);
method @NonNull public static String toString(@Nullable Object);
method @NonNull public static String toString(@Nullable Object, @NonNull String);
}
@@ -72468,6 +72610,18 @@
}
public interface Set<E> extends java.util.Collection<E> {
+ method @NonNull public static <E> java.util.Set<E> of();
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+ method @NonNull @java.lang.SafeVarargs public static <E> java.util.Set<E> of(@NonNull E...);
}
public class SimpleTimeZone extends java.util.TimeZone {
@@ -73406,6 +73560,29 @@
method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
}
+ public final class Flow {
+ method public static int defaultBufferSize();
+ }
+
+ public static interface Flow.Processor<T, R> extends java.util.concurrent.Flow.Subscriber<T> java.util.concurrent.Flow.Publisher<R> {
+ }
+
+ @java.lang.FunctionalInterface public static interface Flow.Publisher<T> {
+ method public void subscribe(java.util.concurrent.Flow.Subscriber<? super T>);
+ }
+
+ public static interface Flow.Subscriber<T> {
+ method public void onComplete();
+ method public void onError(Throwable);
+ method public void onNext(T);
+ method public void onSubscribe(java.util.concurrent.Flow.Subscription);
+ }
+
+ public static interface Flow.Subscription {
+ method public void cancel();
+ method public void request(long);
+ }
+
public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
ctor public ForkJoinPool();
ctor public ForkJoinPool(int);
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 508718e..a3318c7 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -509,6 +509,10 @@
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#ELYMAIC:
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#KHITAN_SMALL_SCRIPT:
+
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#LISU_SUPPLEMENT:
+
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NANDINAGARI:
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#NYIAKENG_PUACHUE_HMONG:
@@ -519,22 +523,28 @@
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_AND_PICTOGRAPHS_EXTENDED_A:
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#SYMBOLS_FOR_LEGACY_COMPUTING:
+
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TAMIL_SUPPLEMENT:
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#TANGUT_SUPPLEMENT:
+
MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#WANCHO:
+MissingNullability: android.icu.lang.UCharacter.UnicodeBlock#YEZIDI:
+
MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth):
MissingNullability: android.icu.text.DateTimePatternGenerator#getFieldDisplayName(int, android.icu.text.DateTimePatternGenerator.DisplayWidth) parameter #1:
MissingNullability: android.icu.util.MeasureUnit#ATMOSPHERE:
- Missing nullability on field `ATMOSPHERE` in class `class android.icu.util.MeasureUnit`
+
MissingNullability: android.icu.util.MeasureUnit#PERCENT:
- Missing nullability on field `PERCENT` in class `class android.icu.util.MeasureUnit`
+
MissingNullability: android.icu.util.MeasureUnit#PERMILLE:
- Missing nullability on field `PERMILLE` in class `class android.icu.util.MeasureUnit`
+
MissingNullability: android.icu.util.MeasureUnit#PETABYTE:
- Missing nullability on field `PETABYTE` in class `class android.icu.util.MeasureUnit`
+
MissingNullability: android.icu.util.VersionInfo#UNICODE_12_0:
MissingNullability: android.icu.util.VersionInfo#UNICODE_12_1:
diff --git a/api/system-current.txt b/api/system-current.txt
index e4a16677..2dbd7f5 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5284,15 +5284,6 @@
method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
}
- public final class StringNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
- ctor public StringNetworkSpecifier(@NonNull String);
- method public int describeContents();
- method public boolean satisfiedBy(android.net.NetworkSpecifier);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.StringNetworkSpecifier> CREATOR;
- field @NonNull public final String specifier;
- }
-
public final class TelephonyNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
method public boolean satisfiedBy(android.net.NetworkSpecifier);
}
@@ -5422,9 +5413,11 @@
}
public abstract class ChildSessionParams {
+ method public long getHardLifetime();
method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getLocalTrafficSelectors();
method @NonNull public java.util.List<android.net.ipsec.ike.IkeTrafficSelector> getRemoteTrafficSelectors();
method @NonNull public java.util.List<android.net.ipsec.ike.ChildSaProposal> getSaProposals();
+ method public long getSoftLifetime();
}
public class IkeFqdnIdentification extends android.net.ipsec.ike.IkeIdentification {
@@ -5493,12 +5486,14 @@
}
public final class IkeSessionParams {
+ method public long getHardLifetime();
method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getLocalAuthConfig();
method @NonNull public android.net.ipsec.ike.IkeIdentification getLocalIdentification();
method @NonNull public android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig getRemoteAuthConfig();
method @NonNull public android.net.ipsec.ike.IkeIdentification getRemoteIdentification();
method @NonNull public java.util.List<android.net.ipsec.ike.IkeSaProposal> getSaProposals();
method @NonNull public java.net.InetAddress getServerAddress();
+ method public long getSoftLifetime();
method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket getUdpEncapsulationSocket();
}
@@ -5510,6 +5505,7 @@
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthDigitalSignature(@Nullable java.security.cert.X509Certificate, @NonNull java.security.cert.X509Certificate, @NonNull java.util.List<java.security.cert.X509Certificate>, @NonNull java.security.PrivateKey);
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthEap(@Nullable java.security.cert.X509Certificate, @NonNull android.net.eap.EapSessionConfig);
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setAuthPsk(@NonNull byte[]);
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLifetime(long, long);
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setLocalIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setRemoteIdentification(@NonNull android.net.ipsec.ike.IkeIdentification);
method @NonNull public android.net.ipsec.ike.IkeSessionParams.Builder setServerAddress(@NonNull java.net.InetAddress);
@@ -5580,6 +5576,7 @@
method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams build();
+ method @NonNull public android.net.ipsec.ike.TransportModeChildSessionParams.Builder setLifetime(long, long);
}
public final class TunnelModeChildSessionParams extends android.net.ipsec.ike.ChildSessionParams {
@@ -5597,6 +5594,7 @@
method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addOutboundTrafficSelectors(@NonNull android.net.ipsec.ike.IkeTrafficSelector);
method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder addSaProposal(@NonNull android.net.ipsec.ike.ChildSaProposal);
method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams build();
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams.Builder setLifetime(long, long);
}
public static interface TunnelModeChildSessionParams.ConfigRequest {
@@ -9606,8 +9604,6 @@
public final class AccessNetworkConstants {
field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
- field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
- field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
}
public final class BarringInfo implements android.os.Parcelable {
@@ -10252,37 +10248,18 @@
}
public final class NetworkRegistrationInfo implements android.os.Parcelable {
- method public int describeContents();
- method public int getAccessNetworkTechnology();
- method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
- method @Nullable public android.telephony.CellIdentity getCellIdentity();
method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
- method public int getDomain();
- method public int getNrState();
method public int getRegistrationState();
method public int getRejectCause();
method public int getRoamingType();
- method public int getTransportType();
method public boolean isEmergencyEnabled();
- method public boolean isRoaming();
method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
- field public static final int DOMAIN_CS = 1; // 0x1
- field public static final int DOMAIN_CS_PS = 3; // 0x3
- field public static final int DOMAIN_PS = 2; // 0x2
- field public static final int DOMAIN_UNKNOWN = 0; // 0x0
field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
- field public static final int SERVICE_TYPE_DATA = 2; // 0x2
- field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
- field public static final int SERVICE_TYPE_SMS = 3; // 0x3
- field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
- field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
- field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
}
public static final class NetworkRegistrationInfo.Builder {
@@ -10500,7 +10477,6 @@
method public int getDataRegistrationState();
method public boolean getDataRoamingFromRegistration();
method @Nullable public android.telephony.NetworkRegistrationInfo getNetworkRegistrationInfo(int, int);
- method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList();
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int);
method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int);
method public int getNrFrequencyRange();
@@ -10646,7 +10622,7 @@
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public java.util.List<android.telephony.SmsMessage> getMessagesFromIcc();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getPremiumSmsConsent(@NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getSmsCapacityOnIcc();
- method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+ method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void sendMultipartTextMessageWithoutPersisting(String, String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPremiumSmsConsent(@NonNull String, int);
field public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3; // 0x3
@@ -10871,6 +10847,9 @@
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
+ field public static final int CARD_POWER_DOWN = 0; // 0x0
+ field public static final int CARD_POWER_UP = 1; // 0x1
+ field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
@@ -11023,6 +11002,23 @@
package android.telephony.data {
+ public class ApnSetting implements android.os.Parcelable {
+ method @NonNull public static String getApnTypesStringFromBitmask(int);
+ field public static final String TYPE_ALL_STRING = "*";
+ field public static final String TYPE_CBS_STRING = "cbs";
+ field public static final String TYPE_DEFAULT_STRING = "default";
+ field public static final String TYPE_DUN_STRING = "dun";
+ field public static final String TYPE_EMERGENCY_STRING = "emergency";
+ field public static final String TYPE_FOTA_STRING = "fota";
+ field public static final String TYPE_HIPRI_STRING = "hipri";
+ field public static final String TYPE_IA_STRING = "ia";
+ field public static final String TYPE_IMS_STRING = "ims";
+ field public static final String TYPE_MCX_STRING = "mcx";
+ field public static final String TYPE_MMS_STRING = "mms";
+ field public static final String TYPE_SUPL_STRING = "supl";
+ field public static final String TYPE_XCAP_STRING = "xcap";
+ }
+
public final class DataCallResponse implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -11335,6 +11331,7 @@
method public int getEmergencyServiceCategories();
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+ method @Nullable public android.os.Bundle getProprietaryCallExtras();
method public int getRestrictCause();
method public int getServiceType();
method public static int getVideoStateFromCallType(int);
@@ -11837,6 +11834,9 @@
method public boolean isCapable(int);
method public boolean isCapable(@NonNull String);
method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CAPABILITY_CALL_COMPOSER = 4194304; // 0x400000
+ field public static final int CAPABILITY_CHAT_BOT = 67108864; // 0x4000000
+ field public static final int CAPABILITY_CHAT_BOT_ROLE = 134217728; // 0x8000000
field public static final int CAPABILITY_CHAT_SESSION = 2; // 0x2
field public static final int CAPABILITY_CHAT_SESSION_STORE_FORWARD = 4; // 0x4
field public static final int CAPABILITY_CHAT_STANDALONE = 1; // 0x1
@@ -11853,9 +11853,13 @@
field public static final int CAPABILITY_IMAGE_SHARE = 256; // 0x100
field public static final int CAPABILITY_IP_VIDEO_CALL = 16384; // 0x4000
field public static final int CAPABILITY_IP_VOICE_CALL = 8192; // 0x2000
+ field public static final int CAPABILITY_PLUG_IN = 268435456; // 0x10000000
+ field public static final int CAPABILITY_POST_CALL = 8388608; // 0x800000
field public static final int CAPABILITY_RCS_VIDEO_CALL = 1048576; // 0x100000
field public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = 2097152; // 0x200000
field public static final int CAPABILITY_RCS_VOICE_CALL = 524288; // 0x80000
+ field public static final int CAPABILITY_SHARED_MAP = 16777216; // 0x1000000
+ field public static final int CAPABILITY_SHARED_SKETCH = 33554432; // 0x2000000
field public static final int CAPABILITY_SOCIAL_PRESENCE = 2048; // 0x800
field public static final int CAPABILITY_VIDEO_SHARE = 1024; // 0x400
field public static final int CAPABILITY_VIDEO_SHARE_DURING_CS_CALL = 512; // 0x200
@@ -11911,6 +11915,7 @@
public abstract class ImsFeature {
ctor public ImsFeature();
method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+ method public int getFeatureState();
method public final int getSlotIndex();
method public abstract void onFeatureReady();
method public abstract void onFeatureRemoved();
@@ -12158,6 +12163,17 @@
method public int updateClir(int);
method public int updateColp(boolean);
method public int updateColr(int);
+ field public static final int CALL_BARRING_ALL = 7; // 0x7
+ field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+ field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+ field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+ field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+ field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+ field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+ field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+ field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+ field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+ field public static final int INVALID_RESULT = -1; // 0xffffffff
}
}
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 07b8969..973d827 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -121,6 +121,18 @@
}
+package android.net {
+
+ @Deprecated public final class StringNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
+ ctor public StringNetworkSpecifier(@NonNull String);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.StringNetworkSpecifier> CREATOR;
+ field @NonNull public final String specifier;
+ }
+
+}
+
package android.net.wifi {
@Deprecated public class BatchedScanResult implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 28119e3..190f9fe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3141,8 +3141,6 @@
public final class AccessNetworkConstants {
field public static final int TRANSPORT_TYPE_INVALID = -1; // 0xffffffff
- field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
- field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
}
public final class BarringInfo implements android.os.Parcelable {
@@ -3218,36 +3216,18 @@
}
public final class NetworkRegistrationInfo implements android.os.Parcelable {
- method public int describeContents();
- method public int getAccessNetworkTechnology();
- method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
- method @Nullable public android.telephony.CellIdentity getCellIdentity();
method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
- method public int getDomain();
method public int getRegistrationState();
method public int getRejectCause();
method public int getRoamingType();
- method public int getTransportType();
method public boolean isEmergencyEnabled();
- method public boolean isRoaming();
method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
- field public static final int DOMAIN_CS = 1; // 0x1
- field public static final int DOMAIN_CS_PS = 3; // 0x3
- field public static final int DOMAIN_PS = 2; // 0x2
- field public static final int DOMAIN_UNKNOWN = 0; // 0x0
field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
- field public static final int SERVICE_TYPE_DATA = 2; // 0x2
- field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
- field public static final int SERVICE_TYPE_SMS = 3; // 0x3
- field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
- field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
- field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
}
public static final class NetworkRegistrationInfo.Builder {
@@ -3296,7 +3276,7 @@
public final class SmsManager {
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
- method public void sendMultipartTextMessage(@NonNull String, @NonNull String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
+ method public void sendMultipartTextMessage(@NonNull String, @Nullable String, @NonNull java.util.List<java.lang.String>, @Nullable java.util.List<android.app.PendingIntent>, @Nullable java.util.List<android.app.PendingIntent>, @NonNull String);
field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
@@ -3393,6 +3373,7 @@
method public int getEmergencyServiceCategories();
method @NonNull public java.util.List<java.lang.String> getEmergencyUrns();
method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile();
+ method @Nullable public android.os.Bundle getProprietaryCallExtras();
method public int getRestrictCause();
method public int getServiceType();
method public static int getVideoStateFromCallType(int);
@@ -3446,6 +3427,7 @@
field public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
field public static final String EXTRA_EMERGENCY_CALL = "e_call";
field public static final String EXTRA_IS_CALL_PULL = "CallPull";
+ field public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
field public static final String EXTRA_OI = "oi";
field public static final String EXTRA_OIR = "oir";
field public static final String EXTRA_REMOTE_URI = "remote_uri";
@@ -3924,6 +3906,7 @@
public abstract class ImsFeature {
ctor public ImsFeature();
method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy);
+ method public int getFeatureState();
method public final int getSlotIndex();
method public abstract void onFeatureReady();
method public abstract void onFeatureRemoved();
@@ -4171,6 +4154,17 @@
method public int updateClir(int);
method public int updateColp(boolean);
method public int updateColr(int);
+ field public static final int CALL_BARRING_ALL = 7; // 0x7
+ field public static final int CALL_BARRING_ALL_INCOMING = 1; // 0x1
+ field public static final int CALL_BARRING_ALL_OUTGOING = 2; // 0x2
+ field public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6; // 0x6
+ field public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9; // 0x9
+ field public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8; // 0x8
+ field public static final int CALL_BARRING_OUTGOING_INTL = 3; // 0x3
+ field public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4; // 0x4
+ field public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10; // 0xa
+ field public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5; // 0x5
+ field public static final int INVALID_RESULT = -1; // 0xffffffff
}
}
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8fac31a..2537eda 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -100,6 +100,7 @@
static const int TEXT_CENTER_VALUE = INT_MAX;
static const int TEXT_MISSING_VALUE = INT_MIN;
static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
+static const char DISPLAYS_PROP_NAME[] = "persist.service.bootanim.displays";
static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
@@ -291,10 +292,10 @@
// this guest property specifies multi-display IDs to show the boot animation
// multiple ids can be set with comma (,) as separator, for example:
- // setprop boot.animation.displays 19260422155234049,19261083906282754
+ // setprop persist.boot.animation.displays 19260422155234049,19261083906282754
Vector<uint64_t> physicalDisplayIds;
char displayValue[PROPERTY_VALUE_MAX] = "";
- property_get("boot.animation.displays", displayValue, "");
+ property_get(DISPLAYS_PROP_NAME, displayValue, "");
bool isValid = displayValue[0] != '\0';
if (isValid) {
char *p = displayValue;
@@ -306,7 +307,7 @@
p ++;
}
if (!isValid)
- SLOGE("Invalid syntax for the value of system prop: boot.animation.displays");
+ SLOGE("Invalid syntax for the value of system prop: %s", DISPLAYS_PROP_NAME);
}
if (isValid) {
std::istringstream stream(displayValue);
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 1c6867c3..6eafbd8 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -73,7 +73,6 @@
"src/external/puller_util.cpp",
"src/external/ResourceHealthManagerPuller.cpp",
"src/external/StatsCallbackPuller.cpp",
- "src/external/StatsCallbackPullerDeprecated.cpp",
"src/external/StatsCompanionServicePuller.cpp",
"src/external/StatsPuller.cpp",
"src/external/StatsPullerManager.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ada2f2d..c1a8d69 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1265,16 +1265,6 @@
return Status::ok();
}
-Status StatsService::registerPullerCallback(int32_t atomTag,
- const sp<android::os::IStatsPullerCallback>& pullerCallback,
- const String16& packageName) {
- ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
- VLOG("StatsService::registerPullerCallback called.");
- mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
- return Status::ok();
-}
-
Status StatsService::registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
int64_t timeoutNs, const std::vector<int32_t>& additiveFields,
const sp<android::os::IPullAtomCallback>& pullerCallback) {
@@ -1297,14 +1287,6 @@
return Status::ok();
}
-Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
- ENFORCE_DUMP_AND_USAGE_STATS(packageName);
-
- VLOG("StatsService::unregisterPullerCallback called.");
- mPullerManager->UnregisterPullerCallback(atomTag);
- return Status::ok();
-}
-
Status StatsService::unregisterPullAtomCallback(int32_t uid, int32_t atomTag) {
ENFORCE_UID(AID_SYSTEM);
VLOG("StatsService::unregisterPullAtomCallback called.");
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 7990e5e..f2079d9 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -171,14 +171,6 @@
virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
/**
- * Binder call to register a callback function for a vendor pulled atom.
- * Note: this atom must NOT have uid as a field.
- */
- virtual Status registerPullerCallback(int32_t atomTag,
- const sp<android::os::IStatsPullerCallback>& pullerCallback,
- const String16& packageName) override;
-
- /**
* Binder call to register a callback function for a pulled atom.
*/
virtual Status registerPullAtomCallback(int32_t uid, int32_t atomTag, int64_t coolDownNs,
@@ -193,11 +185,6 @@
const sp<android::os::IPullAtomCallback>& pullerCallback) override;
/**
- * Binder call to unregister any existing callback function for a vendor pulled atom.
- */
- virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
-
- /**
* Binder call to unregister any existing callback for the given uid and atom.
*/
virtual Status unregisterPullAtomCallback(int32_t uid, int32_t atomTag) override;
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
deleted file mode 100644
index 4f88a91..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "StatsCallbackPullerDeprecated.h"
-
-#include <android/os/IStatsPullerCallback.h>
-
-#include "logd/LogEvent.h"
-#include "stats_log_util.h"
-
-using namespace android::binder;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-StatsCallbackPullerDeprecated::StatsCallbackPullerDeprecated(
- int tagId, const sp<IStatsPullerCallback>& callback)
- : StatsPuller(tagId), mCallback(callback) {
- VLOG("StatsCallbackPuller created for tag %d", tagId);
-}
-
-bool StatsCallbackPullerDeprecated::PullInternal(vector<shared_ptr<LogEvent>>* data) {
- VLOG("StatsCallbackPuller called for tag %d", mTagId)
- if (mCallback == nullptr) {
- ALOGW("No callback registered");
- return false;
- }
- int64_t wallClockTimeNs = getWallClockNs();
- int64_t elapsedTimeNs = getElapsedRealtimeNs();
- vector<StatsLogEventWrapper> returned_value;
- Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
- if (!status.isOk()) {
- ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
- return false;
- }
- data->clear();
- for (const StatsLogEventWrapper& it : returned_value) {
- LogEvent::createLogEvents(it, *data);
- }
- VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h b/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
deleted file mode 100644
index 0289029..0000000
--- a/cmds/statsd/src/external/StatsCallbackPullerDeprecated.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include <android/os/IStatsPullerCallback.h>
-#include <utils/String16.h>
-
-#include "StatsPuller.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class StatsCallbackPullerDeprecated : public StatsPuller {
-public:
- explicit StatsCallbackPullerDeprecated(int tagId, const sp<IStatsPullerCallback>& callback);
-
-private:
- bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
- const sp<IStatsPullerCallback> mCallback;
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index d5cda85..b4fde16 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -21,7 +21,6 @@
#include <android/os/IPullAtomCallback.h>
#include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
#include <cutils/log.h>
#include <math.h>
#include <stdint.h>
@@ -38,7 +37,6 @@
#include "PowerStatsPuller.h"
#include "ResourceHealthManagerPuller.h"
#include "StatsCallbackPuller.h"
-#include "StatsCallbackPullerDeprecated.h"
#include "StatsCompanionServicePuller.h"
#include "SubsystemSleepStatePuller.h"
#include "TrainInfoPuller.h"
@@ -68,13 +66,6 @@
{{.atomTag = android::util::ON_DEVICE_POWER_MEASUREMENT},
{.puller = new PowerStatsPuller()}},
- // system_elapsed_realtime
- {{.atomTag = android::util::SYSTEM_ELAPSED_REALTIME},
- {.coolDownNs = NS_PER_SEC,
- .puller = new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME),
- .pullTimeoutNs = NS_PER_SEC / 2,
- }},
-
// remaining_battery_capacity
{{.atomTag = android::util::REMAINING_BATTERY_CAPACITY},
{.puller = new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
@@ -95,35 +86,6 @@
{{.atomTag = android::util::BATTERY_CYCLE_COUNT},
{.puller = new ResourceHealthManagerPuller(android::util::BATTERY_CYCLE_COUNT)}},
- // looper_stats
- {{.atomTag = android::util::LOOPER_STATS},
- {.additiveFields = {5, 6, 7, 8, 9},
- .puller = new StatsCompanionServicePuller(android::util::LOOPER_STATS)}},
-
- // Disk Stats
- {{.atomTag = android::util::DISK_STATS},
- {.puller = new StatsCompanionServicePuller(android::util::DISK_STATS)}},
-
- // Directory usage
- {{.atomTag = android::util::DIRECTORY_USAGE},
- {.puller = new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}},
-
- // Size of app's code, data, and cache
- {{.atomTag = android::util::APP_SIZE},
- {.puller = new StatsCompanionServicePuller(android::util::APP_SIZE)}},
-
- // Size of specific categories of files. Eg. Music.
- {{.atomTag = android::util::CATEGORY_SIZE},
- {.puller = new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}},
-
- // Number of fingerprints enrolled for each user.
- {{.atomTag = android::util::NUM_FINGERPRINTS_ENROLLED},
- {.puller = new StatsCompanionServicePuller(android::util::NUM_FINGERPRINTS_ENROLLED)}},
-
- // Number of faces enrolled for each user.
- {{.atomTag = android::util::NUM_FACES_ENROLLED},
- {.puller = new StatsCompanionServicePuller(android::util::NUM_FACES_ENROLLED)}},
-
// ProcStats.
{{.atomTag = android::util::PROC_STATS},
{.puller = new StatsCompanionServicePuller(android::util::PROC_STATS)}},
@@ -132,20 +94,6 @@
{{.atomTag = android::util::PROC_STATS_PKG_PROC},
{.puller = new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}},
- // Disk I/O stats per uid.
- {{.atomTag = android::util::DISK_IO},
- {.additiveFields = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
- .coolDownNs = 3 * NS_PER_SEC,
- .puller = new StatsCompanionServicePuller(android::util::DISK_IO)}},
-
- // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
- {{.atomTag = android::util::PROCESS_CPU_TIME},
- {.coolDownNs = 5 * NS_PER_SEC /* min cool-down in seconds*/,
- .puller = new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
- {{.atomTag = android::util::CPU_TIME_PER_THREAD_FREQ},
- {.additiveFields = {7, 9, 11, 13, 15, 17, 19, 21},
- .puller = new StatsCompanionServicePuller(android::util::CPU_TIME_PER_THREAD_FREQ)}},
-
// DebugElapsedClock.
{{.atomTag = android::util::DEBUG_ELAPSED_CLOCK},
{.additiveFields = {1, 2, 3, 4},
@@ -156,25 +104,9 @@
{.additiveFields = {1, 2, 3, 4},
.puller = new StatsCompanionServicePuller(android::util::DEBUG_FAILING_ELAPSED_CLOCK)}},
- // RoleHolder.
- {{.atomTag = android::util::ROLE_HOLDER},
- {.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
-
- // PermissionState.
- {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE},
- {.puller = new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE)}},
-
// TrainInfo.
{{.atomTag = android::util::TRAIN_INFO}, {.puller = new TrainInfoPuller()}},
- // TimeZoneDataInfo.
- {{.atomTag = android::util::TIME_ZONE_DATA_INFO},
- {.puller = new StatsCompanionServicePuller(android::util::TIME_ZONE_DATA_INFO)}},
-
- // ExternalStorageInfo
- {{.atomTag = android::util::EXTERNAL_STORAGE_INFO},
- {.puller = new StatsCompanionServicePuller(android::util::EXTERNAL_STORAGE_INFO)}},
-
// GpuStatsGlobalInfo
{{.atomTag = android::util::GPU_STATS_GLOBAL_INFO},
{.puller = new GpuStatsPuller(android::util::GPU_STATS_GLOBAL_INFO)}},
@@ -183,31 +115,14 @@
{{.atomTag = android::util::GPU_STATS_APP_INFO},
{.puller = new GpuStatsPuller(android::util::GPU_STATS_APP_INFO)}},
- // AppsOnExternalStorageInfo
- {{.atomTag = android::util::APPS_ON_EXTERNAL_STORAGE_INFO},
- {.puller = new StatsCompanionServicePuller(android::util::APPS_ON_EXTERNAL_STORAGE_INFO)}},
-
// Face Settings
{{.atomTag = android::util::FACE_SETTINGS},
{.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
- // App ops
- {{.atomTag = android::util::APP_OPS},
- {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
-
// VmsClientStats
{{.atomTag = android::util::VMS_CLIENT_STATS},
{.additiveFields = {5, 6, 7, 8, 9, 10},
.puller = new CarStatsPuller(android::util::VMS_CLIENT_STATS)}},
-
- // NotiifcationRemoteViews.
- {{.atomTag = android::util::NOTIFICATION_REMOTE_VIEWS},
- {.puller = new StatsCompanionServicePuller(android::util::NOTIFICATION_REMOTE_VIEWS)}},
-
- // PermissionStateSampled.
- {{.atomTag = android::util::DANGEROUS_PERMISSION_STATE_SAMPLED},
- {.puller =
- new StatsCompanionServicePuller(android::util::DANGEROUS_PERMISSION_STATE_SAMPLED)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
@@ -406,21 +321,6 @@
return totalCleared;
}
-// Deprecated, remove after puller API is complete.
-void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
- const sp<IStatsPullerCallback>& callback) {
- AutoMutex _l(mLock);
- // Platform pullers cannot be changed.
- if (!isVendorPulledAtom(atomTag)) {
- VLOG("RegisterPullerCallback: atom tag %d is not vendor pulled", atomTag);
- return;
- }
- VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
- kAllPullAtomInfo[{.atomTag = atomTag}] = {
- .puller = new StatsCallbackPullerDeprecated(atomTag, callback)};
-}
-
void StatsPullerManager::RegisterPullAtomCallback(const int uid, const int32_t atomTag,
const int64_t coolDownNs, const int64_t timeoutNs,
const vector<int32_t>& additiveFields,
@@ -437,16 +337,6 @@
};
}
-void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
- AutoMutex _l(mLock);
- // Platform pullers cannot be changed.
- if (!isVendorPulledAtom(atomTag)) {
- return;
- }
- StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
- kAllPullAtomInfo.erase({.atomTag = atomTag});
-}
-
void StatsPullerManager::UnregisterPullAtomCallback(const int uid, const int32_t atomTag) {
AutoMutex _l(mLock);
StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 349fd47..4b6ab57 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -18,7 +18,6 @@
#include <android/os/IPullAtomCallback.h>
#include <android/os/IStatsCompanionService.h>
-#include <android/os/IStatsPullerCallback.h>
#include <binder/IServiceManager.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -116,15 +115,10 @@
void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
- // Deprecated, remove after puller API is complete.
- void RegisterPullerCallback(int32_t atomTag, const sp<IStatsPullerCallback>& callback);
-
void RegisterPullAtomCallback(const int uid, const int32_t atomTag, const int64_t coolDownNs,
const int64_t timeoutNs, const vector<int32_t>& additiveFields,
const sp<IPullAtomCallback>& callback);
- void UnregisterPullerCallback(int32_t atomTag);
-
void UnregisterPullAtomCallback(const int uid, const int32_t atomTag);
static std::map<PullerKey, PullAtomInfo> kAllPullAtomInfo;
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 692d91e..3282785 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -164,9 +164,6 @@
// Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
static const int kMaxNonPlatformPushedAtoms = 100;
- // Max platform atom tag number.
- static const int32_t kMaxPlatformAtomTag = 100000;
-
// Vendor pulled atom start id.
static const int32_t kVendorPulledAtomStartTag = 150000;
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d39a8c4..326a076 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1675,6 +1675,10 @@
}
@UnsupportedAppUsage
+ protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
+ this(context, pm, ActivityThread.getPermissionManager());
+ }
+
protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
IPermissionManager permissionManager) {
mContext = context;
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 0beceb0..0ea05d8 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -25,11 +25,9 @@
import android.annotation.SystemApi;
import android.content.Context;
import android.os.Binder;
-import android.os.IBinder;
import android.os.IPullAtomCallback;
import android.os.IPullAtomResultReceiver;
import android.os.IStatsManagerService;
-import android.os.IStatsPullerCallback;
import android.os.IStatsd;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -476,42 +474,6 @@
}
/**
- * Registers a callback for an atom when that atom is to be pulled. The stats service will
- * invoke pullData in the callback when the stats service determines that this atom needs to be
- * pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
- *
- * @param atomTag The tag of the atom for this puller callback. Must be at least 100000.
- * @param callback The callback to be invoked when the stats service pulls the atom.
- * @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
- *
- * @hide
- * @deprecated Please use registerPullAtomCallback
- */
- @Deprecated
- @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
- public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
- throws StatsUnavailableException {
- synchronized (sLock) {
- try {
- IStatsd service = getIStatsdLocked();
- if (callback == null) {
- service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
- } else {
- service.registerPullerCallback(atomTag, callback,
- mContext.getOpPackageName());
- }
-
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
- throw new StatsUnavailableException("could not connect", e);
- } catch (SecurityException e) {
- throw new StatsUnavailableException(e.getMessage(), e);
- }
- }
- }
-
-
- /**
* Temp registration for while the migration is in progress.
*
* @hide
@@ -734,32 +696,6 @@
int onPullAtom(int atomTag, @NonNull List<StatsEvent> data);
}
- private class StatsdDeathRecipient implements IBinder.DeathRecipient {
- @Override
- public void binderDied() {
- synchronized (sLock) {
- mService = null;
- }
- }
- }
-
- @GuardedBy("sLock")
- private IStatsd getIStatsdLocked() throws StatsUnavailableException {
- if (mService != null) {
- return mService;
- }
- mService = IStatsd.Stub.asInterface(ServiceManager.getService("stats"));
- if (mService == null) {
- throw new StatsUnavailableException("could not be found");
- }
- try {
- mService.asBinder().linkToDeath(new StatsdDeathRecipient(), 0);
- } catch (RemoteException e) {
- throw new StatsUnavailableException("could not connect when linkToDeath", e);
- }
- return mService;
- }
-
@GuardedBy("sLock")
private IStatsManagerService getIStatsManagerServiceLocked() {
if (mStatsManagerService != null) {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 9ad3d38..a885009 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1564,6 +1564,8 @@
* @return The desired minimum width for the wallpaper. This value should
* be honored by applications that set the wallpaper but it is not
* mandatory.
+ *
+ * @see #getDesiredMinimumHeight()
*/
public int getDesiredMinimumWidth() {
if (sGlobals.mService == null) {
@@ -1590,6 +1592,8 @@
* @return The desired minimum height for the wallpaper. This value should
* be honored by applications that set the wallpaper but it is not
* mandatory.
+ *
+ * @see #getDesiredMinimumWidth()
*/
public int getDesiredMinimumHeight() {
if (sGlobals.mService == null) {
@@ -1609,12 +1613,11 @@
* a virtual wallpaper that is larger than the physical screen, matching
* the size of their workspace.
*
- * <p>Note developers, who don't seem to be reading this. This is
- * for <em>home apps</em> to tell what size wallpaper they would like.
- * Nobody else should be calling this! Certainly not other non-home
- * apps that change the wallpaper. Those apps are supposed to
- * <b>retrieve</b> the suggested size so they can construct a wallpaper
- * that matches it.
+ * <p class="note">Calling this method from apps other than the active
+ * home app is not guaranteed to work properly. Other apps that supply
+ * wallpaper imagery should use {@link #getDesiredMinimumWidth()} and
+ * {@link #getDesiredMinimumHeight()} and construct a wallpaper that
+ * matches those dimensions.
*
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#SET_WALLPAPER_HINTS}.
diff --git a/core/java/android/net/StringNetworkSpecifier.java b/core/java/android/net/StringNetworkSpecifier.java
index 83dbc63..530c84a 100644
--- a/core/java/android/net/StringNetworkSpecifier.java
+++ b/core/java/android/net/StringNetworkSpecifier.java
@@ -26,7 +26,16 @@
import java.util.Objects;
-/** @hide */
+/**
+ * @deprecated use other subclass of {@link android.net.NetworkSpecifier},
+ * eg. {@link android.net.TelephonyNetworkSpecifier},
+ * {@link android.net.wifi.WifiNetworkSpecifier} instead.
+ * @see {@link android.net.NetworkRequest#setNetworkSpecifier(String)} for details.
+ * @removed this class was tentatively made SystemApi in December 2019 in the scramble for
+ * publishing mainline APIs, it should be removed before R release is published.
+ * @hide
+ */
+@Deprecated
@SystemApi
public final class StringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
/**
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 179828c..13d0c5c 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -35,6 +35,7 @@
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.RuntimeHooks;
+import dalvik.system.ThreadPrioritySetter;
import dalvik.system.VMRuntime;
import libcore.content.type.MimeMap;
@@ -204,6 +205,7 @@
*/
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());
@@ -216,6 +218,35 @@
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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b27348..7181142 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -563,10 +563,12 @@
<protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
- <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
+ <protected-broadcast android:name="android.net.sip.action.SIP_INCOMING_CALL" />
<protected-broadcast android:name="com.android.phone.SIP_ADD_PHONE" />
- <protected-broadcast android:name="com.android.phone.SIP_REMOVE_PHONE" />
- <protected-broadcast android:name="com.android.phone.SIP_CALL_OPTION_CHANGED" />
+ <protected-broadcast android:name="android.net.sip.action.SIP_REMOVE_PROFILE" />
+ <protected-broadcast android:name="android.net.sip.action.SIP_SERVICE_UP" />
+ <protected-broadcast android:name="android.net.sip.action.SIP_CALL_OPTION_CHANGED" />
+ <protected-broadcast android:name="android.net.sip.action.START_SIP" />
<protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_CONNECTED" />
<protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED" />
diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java
index e4bab74..f898931 100644
--- a/media/java/android/media/CamcorderProfile.java
+++ b/media/java/android/media/CamcorderProfile.java
@@ -99,25 +99,21 @@
/**
* Quality level corresponding to the VGA (640 x 480) resolution.
- * @hide
*/
public static final int QUALITY_VGA = 9;
/**
* Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
- * @hide
*/
public static final int QUALITY_4KDCI = 10;
/**
* Quality level corresponding to QHD (2560 x 1440) resolution
- * @hide
*/
public static final int QUALITY_QHD = 11;
/**
* Quality level corresponding to 2K (2048 x 1080) resolution
- * @hide
*/
public static final int QUALITY_2K = 12;
@@ -172,25 +168,21 @@
/**
* Time lapse quality level corresponding to the VGA (640 x 480) resolution.
- * @hide
*/
public static final int QUALITY_TIME_LAPSE_VGA = 1009;
/**
* Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
- * @hide
*/
public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
/**
* Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
- * @hide
*/
public static final int QUALITY_TIME_LAPSE_QHD = 1011;
/**
* Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
- * @hide
*/
public static final int QUALITY_TIME_LAPSE_2K = 1012;
@@ -255,19 +247,16 @@
/**
* High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
- * @hide
*/
public static final int QUALITY_HIGH_SPEED_CIF = 2006;
/**
* High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
- * @hide
*/
public static final int QUALITY_HIGH_SPEED_VGA = 2007;
/**
* High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
- * @hide
*/
public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
diff --git a/packages/CarSystemUI/res/xml/overlayable.xml b/packages/CarSystemUI/res/xml/overlayable.xml
new file mode 100644
index 0000000..2b6e66e
--- /dev/null
+++ b/packages/CarSystemUI/res/xml/overlayable.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <overlayable name="SystemBarsLayouts">
+ <policy type="product|signature">
+ <item type="layout" name="car_navigation_bar" />
+ </policy>
+ </overlayable>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/scripts/update_shared_lib.sh b/packages/SystemUI/scripts/update_shared_lib.sh
new file mode 100755
index 0000000..0537493
--- /dev/null
+++ b/packages/SystemUI/scripts/update_shared_lib.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+NUM_ARGS=$#
+
+has_croot() {
+ declare -F croot > /dev/null
+ return $?
+}
+
+check_environment() {
+ if ! has_croot; then
+ echo "Run script in a shell that has had envsetup run. Run '. update_shared_lib.sh' from scripts directory"
+ return 1
+ fi
+
+ if [ $NUM_ARGS -ne 1 ]; then
+ echo "Usage: . update_shared_lib PATH_TO_UNBUNDLED_LAUNCER e.g. . update_shared_lib ~/src/ub-launcher3-master"
+ return 1
+ fi
+ return 0
+}
+
+main() {
+ if check_environment ; then
+ pushd .
+ croot
+ mma -j16 SystemUISharedLib
+ JAR_DESTINATION="$1/prebuilts/framework_intermediates/quickstep/libs/sysui_shared.jar"
+ cp out/target/product/$TARGET_PRODUCT/obj/JAVA_LIBRARIES/SystemUISharedLib_intermediates/javalib.jar $JAR_DESTINATION
+ popd
+ fi
+}
+
+main
+
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
new file mode 100644
index 0000000..70a464d
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java
@@ -0,0 +1,67 @@
+/*
+ * 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.systemui.shared.system;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.SurfaceControl;
+import android.view.SurfaceView;
+
+/** Utility class that is shared between SysUI and Launcher for Universal Smartspace features. */
+public final class UniversalSmartspaceUtils {
+ public static final String ACTION_REQUEST_SMARTSPACE_VIEW =
+ "com.android.systemui.REQUEST_SMARTSPACE_VIEW";
+
+ private static final String SYSUI_PACKAGE = "com.android.systemui";
+ private static final String INTENT_KEY_INPUT_BUNDLE = "input_bundle";
+ private static final String BUNDLE_KEY_INPUT_TOKEN = "input_token";
+ private static final String INTENT_KEY_SURFACE_CONTROL = "surface_control";
+
+ /** Creates an intent to request that sysui draws the Smartspace to the SurfaceView. */
+ public static Intent createRequestSmartspaceIntent(SurfaceView surfaceView) {
+ Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);
+
+ Bundle inputBundle = new Bundle();
+ inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getInputToken());
+ return intent
+ .putExtra(INTENT_KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl())
+ .putExtra(INTENT_KEY_INPUT_BUNDLE, inputBundle)
+ .setPackage(SYSUI_PACKAGE)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+ | Intent.FLAG_RECEIVER_FOREGROUND);
+ }
+
+ /**
+ * Retrieves the SurfaceControl from an Intent created by
+ * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+ **/
+ public static SurfaceControl getSurfaceControl(Intent intent) {
+ return intent.getParcelableExtra(INTENT_KEY_SURFACE_CONTROL);
+ }
+
+ /**
+ * Retrieves the input token from an Intent created by
+ * {@link #createRequestSmartspaceIntent(SurfaceView)}.
+ **/
+ public static IBinder getInputToken(Intent intent) {
+ Bundle inputBundle = intent.getBundleExtra(INTENT_KEY_INPUT_BUNDLE);
+ return inputBundle == null ? null : inputBundle.getBinder(BUNDLE_KEY_INPUT_TOKEN);
+ }
+
+ private UniversalSmartspaceUtils() {}
+}
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index e441fb5..cf2b1f06 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -35,7 +35,7 @@
"framework-tethering",
"unsupportedappusage",
],
-
+ plugins: ["java_api_finder"],
manifest: "AndroidManifestBase.xml",
}
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 4306cf0b..0491ad7 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -441,7 +441,8 @@
}
final Boolean setIfaceUp;
- if (mInterfaceType == TetheringManager.TETHERING_WIFI) {
+ if (mInterfaceType == TetheringManager.TETHERING_WIFI
+ || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) {
// The WiFi stack has ownership of the interface up/down state.
// It is unclear whether the Bluetooth or USB stacks will manage their own
// state.
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
index 37e0cc1..8d1e0c9 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java
@@ -207,6 +207,7 @@
private Network mTetherUpstream;
private TetherStatesParcel mTetherStatesParcel;
private boolean mDataSaverEnabled = false;
+ private String mWifiP2pTetherInterface = null;
public Tethering(TetheringDependencies deps) {
mLog.mark("Tethering.constructed");
@@ -852,6 +853,11 @@
}
}
+ private boolean isGroupOwner(WifiP2pGroup group) {
+ return group != null && group.isGroupOwner()
+ && !TextUtils.isEmpty(group.getInterface());
+ }
+
private void handleWifiP2pAction(Intent intent) {
if (mConfig.isWifiP2pLegacyTetheringMode()) return;
@@ -864,24 +870,31 @@
Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group);
}
- if (p2pInfo == null) return;
- // When a p2p group is disconnected, p2pInfo would be cleared.
- // group is still valid for detecting whether this device is group owner.
- if (group == null || !group.isGroupOwner()
- || TextUtils.isEmpty(group.getInterface())) return;
-
synchronized (Tethering.this.mPublicSync) {
- // Enter below only if this device is Group Owner with a valid interface.
- if (p2pInfo.groupFormed) {
- TetherState tetherState = mTetherStates.get(group.getInterface());
- if (tetherState == null
- || (tetherState.lastState != IpServer.STATE_TETHERED
- && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) {
- enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY);
- }
- } else {
- disableWifiP2pIpServingLocked(group.getInterface());
+ // if no group is formed, bring it down if needed.
+ if (p2pInfo == null || !p2pInfo.groupFormed) {
+ disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ mWifiP2pTetherInterface = null;
+ return;
}
+
+ // If there is a group but the device is not the owner, bail out.
+ if (!isGroupOwner(group)) return;
+
+ // If already serving from the correct interface, nothing to do.
+ if (group.getInterface().equals(mWifiP2pTetherInterface)) return;
+
+ // If already serving from another interface, turn it down first.
+ if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) {
+ mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
+ + "is different from current interface "
+ + group.getInterface() + ", re-tether it");
+ disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ }
+
+ // Finally bring up serving on the new interface
+ mWifiP2pTetherInterface = group.getInterface();
+ enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
}
}
@@ -979,7 +992,9 @@
disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
}
- private void disableWifiP2pIpServingLocked(String ifname) {
+ private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
+ if (TextUtils.isEmpty(ifname)) return;
+
disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
}
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 1f50b6b..f29ad78 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -273,7 +273,7 @@
dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY);
InOrder inOrder = inOrder(mCallback, mNetd);
inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg ->
- IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP)));
+ IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP)));
inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME);
inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME);
inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME),
@@ -547,4 +547,14 @@
fail("Missing flag: " + match);
return false;
}
+
+ private boolean assertNotContainsFlag(String[] flags, String match) {
+ for (String flag : flags) {
+ if (flag.equals(match)) {
+ fail("Unexpected flag: " + match);
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
index 5910624..d6afa47 100644
--- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java
@@ -493,13 +493,15 @@
private void sendWifiP2pConnectionChanged(
boolean isGroupFormed, boolean isGroupOwner, String ifname) {
+ WifiP2pGroup group = null;
WifiP2pInfo p2pInfo = new WifiP2pInfo();
p2pInfo.groupFormed = isGroupFormed;
- p2pInfo.isGroupOwner = isGroupOwner;
-
- WifiP2pGroup group = mock(WifiP2pGroup.class);
- when(group.isGroupOwner()).thenReturn(isGroupOwner);
- when(group.getInterface()).thenReturn(ifname);
+ if (isGroupFormed) {
+ p2pInfo.isGroupOwner = isGroupOwner;
+ group = mock(WifiP2pGroup.class);
+ when(group.isGroupOwner()).thenReturn(isGroupOwner);
+ when(group.getInterface()).thenReturn(ifname);
+ }
final Intent intent = mock(Intent.class);
when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
diff --git a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
index 3af15c7..5e6f97e 100644
--- a/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/InlineSuggestionFactory.java
@@ -20,23 +20,24 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.slice.Slice;
import android.content.Context;
-import android.os.Handler;
import android.os.RemoteException;
import android.service.autofill.Dataset;
+import android.service.autofill.InlinePresentation;
import android.util.Slog;
import android.view.SurfaceControl;
import android.view.View;
import android.view.autofill.AutofillId;
import android.view.autofill.IAutoFillManagerClient;
-import android.view.inline.InlinePresentationSpec;
import android.view.inputmethod.InlineSuggestion;
import android.view.inputmethod.InlineSuggestionInfo;
-import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InlineSuggestionsResponse;
import com.android.internal.view.inline.IInlineContentCallback;
import com.android.internal.view.inline.IInlineContentProvider;
+import com.android.server.UiThread;
+import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.autofill.ui.InlineSuggestionUi;
import java.util.ArrayList;
@@ -56,23 +57,59 @@
int sessionId,
@NonNull Dataset[] datasets,
@NonNull AutofillId autofillId,
- @NonNull InlineSuggestionsRequest request,
- @NonNull Handler uiHandler,
@NonNull Context context,
@NonNull IAutoFillManagerClient client) {
+ if (sDebug) Slog.d(TAG, "createAugmentedInlineSuggestionsResponse called");
+
+ final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
+ final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
+ for (Dataset dataset : datasets) {
+ final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+ if (fieldIndex < 0) {
+ Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+ return null;
+ }
+ final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+ fieldIndex);
+ if (inlinePresentation == null) {
+ Slog.w(TAG, "InlinePresentation not found in dataset");
+ return null;
+ }
+ InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
+ inlinePresentation, inlineSuggestionUi, client);
+ inlineSuggestions.add(inlineSuggestion);
+ }
+ return new InlineSuggestionsResponse(inlineSuggestions);
+ }
+
+ /**
+ * Creates an {@link InlineSuggestionsResponse} with the {@code datasets} provided by the
+ * autofill service.
+ */
+ public static InlineSuggestionsResponse createInlineSuggestionsResponse(int requestId,
+ @NonNull Dataset[] datasets,
+ @NonNull AutofillId autofillId,
+ @NonNull Context context,
+ @NonNull AutoFillUI.AutoFillUiCallback client) {
if (sDebug) Slog.d(TAG, "createInlineSuggestionsResponse called");
final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(context);
for (Dataset dataset : datasets) {
- // TODO(b/146453195): use the spec in the dataset.
- InlinePresentationSpec spec = request.getPresentationSpecs().get(0);
- if (spec == null) {
- Slog.w(TAG, "InlinePresentationSpec is not provided in the response data set");
- continue;
+ final int fieldIndex = dataset.getFieldIds().indexOf(autofillId);
+ if (fieldIndex < 0) {
+ Slog.w(TAG, "AutofillId=" + autofillId + " not found in dataset");
+ return null;
}
- InlineSuggestion inlineSuggestion = createAugmentedInlineSuggestion(sessionId, dataset,
- autofillId, spec, uiHandler, inlineSuggestionUi, client);
+ final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(
+ fieldIndex);
+ if (inlinePresentation == null) {
+ Slog.w(TAG, "InlinePresentation not found in dataset");
+ return null;
+ }
+ InlineSuggestion inlineSuggestion = createInlineSuggestion(requestId, dataset,
+ fieldIndex,
+ inlinePresentation, inlineSuggestionUi, client);
inlineSuggestions.add(inlineSuggestion);
}
return new InlineSuggestionsResponse(inlineSuggestions);
@@ -80,33 +117,55 @@
private static InlineSuggestion createAugmentedInlineSuggestion(int sessionId,
@NonNull Dataset dataset,
- @NonNull AutofillId autofillId,
- @NonNull InlinePresentationSpec spec,
- @NonNull Handler uiHandler,
+ @NonNull InlinePresentation inlinePresentation,
@NonNull InlineSuggestionUi inlineSuggestionUi,
@NonNull IAutoFillManagerClient client) {
// TODO(b/146453195): fill in the autofill hint properly.
final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
- spec, InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
- final View.OnClickListener onClickListener = createOnClickListener(sessionId, dataset,
- client);
+ inlinePresentation.getInlinePresentationSpec(),
+ InlineSuggestionInfo.SOURCE_PLATFORM, new String[]{""});
+ final View.OnClickListener onClickListener = v -> {
+ try {
+ client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Encounter exception autofilling the values");
+ }
+ };
final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
- createInlineContentProvider(autofillId, dataset, uiHandler, inlineSuggestionUi,
+ createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
+ onClickListener));
+ return inlineSuggestion;
+ }
+
+ private static InlineSuggestion createInlineSuggestion(int requestId,
+ @NonNull Dataset dataset,
+ int fieldIndex,
+ @NonNull InlinePresentation inlinePresentation,
+ @NonNull InlineSuggestionUi inlineSuggestionUi,
+ @NonNull AutoFillUI.AutoFillUiCallback client) {
+ // TODO(b/146453195): fill in the autofill hint properly.
+ final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
+ inlinePresentation.getInlinePresentationSpec(),
+ InlineSuggestionInfo.SOURCE_AUTOFILL, new String[]{""});
+ final View.OnClickListener onClickListener = v -> {
+ client.fill(requestId, fieldIndex, dataset);
+ };
+ final InlineSuggestion inlineSuggestion = new InlineSuggestion(inlineSuggestionInfo,
+ createInlineContentProvider(inlinePresentation.getSlice(), inlineSuggestionUi,
onClickListener));
return inlineSuggestion;
}
private static IInlineContentProvider.Stub createInlineContentProvider(
- @NonNull AutofillId autofillId, @NonNull Dataset dataset, @NonNull Handler uiHandler,
- @NonNull InlineSuggestionUi inlineSuggestionUi,
+ @NonNull Slice slice, @NonNull InlineSuggestionUi inlineSuggestionUi,
@Nullable View.OnClickListener onClickListener) {
return new IInlineContentProvider.Stub() {
@Override
public void provideContent(int width, int height,
IInlineContentCallback callback) {
- uiHandler.post(() -> {
- SurfaceControl sc = inlineSuggestionUi.inflate(dataset, autofillId,
- width, height, onClickListener);
+ UiThread.getHandler().post(() -> {
+ SurfaceControl sc = inlineSuggestionUi.inflate(slice, width, height,
+ onClickListener);
try {
callback.onContent(sc);
} catch (RemoteException e) {
@@ -117,19 +176,6 @@
};
}
- private static View.OnClickListener createOnClickListener(int sessionId,
- @NonNull Dataset dataset,
- @NonNull IAutoFillManagerClient client) {
- return v -> {
- if (sDebug) Slog.d(TAG, "Inline suggestion clicked");
- try {
- client.autofill(sessionId, dataset.getFieldIds(), dataset.getFieldValues());
- } catch (RemoteException e) {
- Slog.w(TAG, "Encounter exception autofilling the values");
- }
- };
- }
-
private InlineSuggestionFactory() {
}
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 2a7357b..5fbdd25 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -161,8 +161,7 @@
@Override
public void onSuccess(@Nullable Dataset[] inlineSuggestionsData) {
maybeHandleInlineSuggestions(sessionId, inlineSuggestionsData,
- focusedId, inlineSuggestionsRequest,
- inlineSuggestionsCallback, client);
+ focusedId, inlineSuggestionsCallback, client);
requestAutofill.complete(null);
}
@@ -226,19 +225,15 @@
private void maybeHandleInlineSuggestions(int sessionId,
@Nullable Dataset[] inlineSuggestionsData, @NonNull AutofillId focusedId,
- @Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
@Nullable IInlineSuggestionsResponseCallback inlineSuggestionsCallback,
@NonNull IAutoFillManagerClient client) {
- if (inlineSuggestionsRequest == null
- || ArrayUtils.isEmpty(inlineSuggestionsData)
- || inlineSuggestionsCallback == null) {
+ if (ArrayUtils.isEmpty(inlineSuggestionsData) || inlineSuggestionsCallback == null) {
return;
}
try {
inlineSuggestionsCallback.onInlineSuggestionsResponse(
- InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(
- sessionId, inlineSuggestionsData, focusedId, inlineSuggestionsRequest,
- getJobHandler(), mContext, client));
+ InlineSuggestionFactory.createAugmentedInlineSuggestionsResponse(sessionId,
+ inlineSuggestionsData, focusedId, mContext, client));
} catch (RemoteException e) {
Slog.w(TAG, "Exception sending inline suggestions response back to IME.");
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index cdd7510..ee37de5 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -71,7 +71,6 @@
import android.service.autofill.FillContext;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
-import android.service.autofill.InlinePresentation;
import android.service.autofill.InternalSanitizer;
import android.service.autofill.InternalValidator;
import android.service.autofill.SaveInfo;
@@ -93,9 +92,6 @@
import android.view.autofill.AutofillValue;
import android.view.autofill.IAutoFillManagerClient;
import android.view.autofill.IAutofillWindowPresenter;
-import android.view.inline.InlinePresentationSpec;
-import android.view.inputmethod.InlineSuggestion;
-import android.view.inputmethod.InlineSuggestionInfo;
import android.view.inputmethod.InlineSuggestionsRequest;
import android.view.inputmethod.InlineSuggestionsResponse;
@@ -106,8 +102,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.view.IInlineSuggestionsRequestCallback;
import com.android.internal.view.IInlineSuggestionsResponseCallback;
-import com.android.internal.view.inline.IInlineContentCallback;
-import com.android.internal.view.inline.IInlineContentProvider;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.autofill.ui.PendingUi;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -148,6 +142,7 @@
private final Handler mHandler;
private final Object mLock;
private final AutoFillUI mUi;
+ private final Context mContext;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
@@ -773,6 +768,7 @@
mLock = lock;
mUi = ui;
mHandler = handler;
+ mContext = context;
mRemoteFillService = serviceComponentName == null ? null
: new RemoteFillService(context, serviceComponentName, userId, this,
bindInstantServiceAllowed);
@@ -2733,35 +2729,11 @@
return false;
}
- final int size = datasets.size();
- final ArrayList<InlineSuggestion> inlineSuggestions = new ArrayList<>();
-
- for (int index = 0; index < size; index++) {
- final Dataset dataset = datasets.get(index);
- //TODO(b/146453536): Use the proper presentation/spec for currently focused view.
- final InlinePresentation inlinePresentation = dataset.getFieldInlinePresentation(0);
- if (inlinePresentation == null) {
- if (sDebug) Log.d(TAG, "Missing InlinePresentation on dataset=" + dataset);
- continue;
- }
- final InlinePresentationSpec spec = inlinePresentation.getInlinePresentationSpec();
- final InlineSuggestionInfo inlineSuggestionInfo = new InlineSuggestionInfo(
- spec, InlineSuggestionInfo.SOURCE_AUTOFILL, new String[] { "" });
-
- inlineSuggestions.add(new InlineSuggestion(inlineSuggestionInfo,
- new IInlineContentProvider.Stub() {
- @Override
- public void provideContent(int width, int height,
- IInlineContentCallback callback) throws RemoteException {
- getUiForShowing().getSuggestionSurfaceForShowing(dataset, response,
- mCurrentViewId, width, height, callback);
- }
- }));
- }
-
+ InlineSuggestionsResponse inlineSuggestionsResponse =
+ InlineSuggestionFactory.createInlineSuggestionsResponse(response.getRequestId(),
+ datasets.toArray(new Dataset[]{}), mCurrentViewId, mContext, this);
try {
- inlineContentCallback.onInlineSuggestionsResponse(
- new InlineSuggestionsResponse(inlineSuggestions));
+ inlineContentCallback.onInlineSuggestionsResponse(inlineSuggestionsResponse);
} catch (RemoteException e) {
Log.w(TAG, "onFillReady() remote error calling onInlineSuggestionsResponse()");
return false;
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 0511bf2..26bb7c3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -37,7 +37,6 @@
import android.text.TextUtils;
import android.util.Slog;
import android.view.KeyEvent;
-import android.view.SurfaceControl;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.IAutofillWindowPresenter;
@@ -45,7 +44,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.view.inline.IInlineContentCallback;
import com.android.server.LocalServices;
import com.android.server.UiModeManagerInternal;
import com.android.server.UiThread;
@@ -173,36 +171,6 @@
}
/**
- * TODO(b/137800469): Fill in javadoc.
- * TODO(b/137800469): peoperly manage lifecycle of suggestions surfaces.
- */
- public void getSuggestionSurfaceForShowing(@NonNull Dataset dataset,
- @NonNull FillResponse response, AutofillId autofillId, int width, int height,
- IInlineContentCallback cb) {
- if (dataset == null) {
- Slog.w(TAG, "getSuggestionSurfaceForShowing() called with null dataset");
- }
- mHandler.post(() -> {
- final InlineSuggestionUi inlineSuggestionUi = new InlineSuggestionUi(mContext);
- final SurfaceControl suggestionSurface = inlineSuggestionUi.inflate(dataset,
- autofillId, width, height, v -> {
- Slog.d(TAG, "Inline suggestion clicked");
- hideFillUiUiThread(mCallback, true);
- if (mCallback != null) {
- final int datasetIndex = response.getDatasets().indexOf(dataset);
- mCallback.fill(response.getRequestId(), datasetIndex, dataset);
- }
- });
-
- try {
- cb.onContent(suggestionSurface);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException replying onContent(" + suggestionSurface + "): " + e);
- }
- });
- }
-
- /**
* Shows the fill UI, removing the previous fill UI if the has changed.
*
* @param focusedId the currently focused field
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
index 1e3ee88..2460732 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionUi.java
@@ -28,17 +28,13 @@
import android.graphics.PixelFormat;
import android.graphics.drawable.Icon;
import android.os.IBinder;
-import android.service.autofill.Dataset;
import android.util.Log;
-import android.util.Slog;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillValue;
import android.widget.ImageView;
import android.widget.TextView;
@@ -69,23 +65,18 @@
*/
@MainThread
@Nullable
- public SurfaceControl inflate(@NonNull Dataset dataset, @NonNull AutofillId autofillId,
- int width, int height, @Nullable View.OnClickListener onClickListener) {
+ public SurfaceControl inflate(@NonNull Slice slice, int width, int height,
+ @Nullable View.OnClickListener onClickListener) {
Log.d(TAG, "Inflating the inline suggestion UI");
- final int index = dataset.getFieldIds().indexOf(autofillId);
- if (index < 0) {
- Slog.w(TAG, "inflateInlineSuggestion(): AutofillId=" + autofillId
- + " not found in dataset");
- return null;
- }
- final AutofillValue datasetValue = dataset.getFieldValues().get(index);
+
//TODO(b/137800469): Pass in inputToken from IME.
final SurfaceControlViewHost wvr = new SurfaceControlViewHost(mContext,
mContext.getDisplay(), (IBinder) null);
final SurfaceControl sc = wvr.getSurfacePackage().getSurfaceControl();
-
- final ViewGroup suggestionView =
- (ViewGroup) renderSlice(dataset.getFieldInlinePresentation(index).getSlice());
+ final ViewGroup suggestionView = (ViewGroup) renderSlice(slice);
+ if (onClickListener != null) {
+ suggestionView.setOnClickListener(onClickListener);
+ }
WindowManager.LayoutParams lp =
new WindowManager.LayoutParams(width, height,
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 4f03a8e..7324d97 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2413,43 +2413,12 @@
Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(PHONE_CONSTANTS_STATE_KEY, dataStateToString(state));
intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn);
- intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, getApnTypesStringFromBitmask(apnType));
+ intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY,
+ ApnSetting.getApnTypesStringFromBitmask(apnType));
intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private static final Map<Integer, String> APN_TYPE_INT_MAP;
- static {
- APN_TYPE_INT_MAP = new android.util.ArrayMap<Integer, String>();
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DEFAULT, "default");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MMS, "mms");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_SUPL, "supl");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_DUN, "dun");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_HIPRI, "hipri");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_FOTA, "fota");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IMS, "ims");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_CBS, "cbs");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_IA, "ia");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_EMERGENCY, "emergency");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_MCX, "mcx");
- APN_TYPE_INT_MAP.put(ApnSetting.TYPE_XCAP, "xcap");
- }
-
- /**
- * Copy of ApnSetting#getApnTypesStringFromBitmask for legacy broadcast.
- * @param apnTypeBitmask bitmask of APN types.
- * @return comma delimited list of APN types.
- */
- private static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
- List<String> types = new ArrayList<>();
- for (Integer type : APN_TYPE_INT_MAP.keySet()) {
- if ((apnTypeBitmask & type) == type) {
- types.add(APN_TYPE_INT_MAP.get(type));
- }
- }
- return android.text.TextUtils.join(",", types);
- }
-
private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
if (checkNotifyPermission()) {
return;
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index dfc0080..4bf606e 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -53,6 +53,7 @@
public OverrideAllowedState getOverrideAllowedState(long changeId, String packageName) {
boolean debuggableBuild = false;
boolean finalBuild = false;
+ int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
debuggableBuild = mAndroidBuildClassifier.isDebuggableBuild();
finalBuild = mAndroidBuildClassifier.isFinalBuild();
@@ -76,15 +77,14 @@
if ((applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
return new OverrideAllowedState(DISABLED_NOT_DEBUGGABLE, -1, -1);
}
- int minTargetSdk = mCompatConfig.minTargetSdkForChangeId(changeId);
- // Do not allow overriding non-target sdk gated changes on user builds
- if (minTargetSdk == -1) {
- return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
- }
// Allow overriding any change for debuggable apps on non-final builds.
if (!finalBuild) {
return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
}
+ // Do not allow overriding non-target sdk gated changes on user builds
+ if (minTargetSdk == -1) {
+ return new OverrideAllowedState(DISABLED_NON_TARGET_SDK, appTargetSdk, minTargetSdk);
+ }
// Only allow to opt-in for a targetSdk gated change.
if (applicationInfo.targetSdkVersion < minTargetSdk) {
return new OverrideAllowedState(ALLOWED, appTargetSdk, minTargetSdk);
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 1e85688..b11ec6f 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -168,6 +168,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.MissingResourceException;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@@ -198,9 +199,16 @@
private final Object mThermalLock = new Object();
@GuardedBy("mThermalLock")
private IThermalService mThermalService;
+ private final Object mStoragedLock = new Object();
+ @GuardedBy("mStoragedLock")
+ private IStoraged mStorageService;
+ private final Object mNotificationStatsLock = new Object();
+ @GuardedBy("mNotificationStatsLock")
+ private INotificationManager mNotificationManagerService;
private final Context mContext;
private StatsManager mStatsManager;
+ private StorageManager mStorageManager;
public StatsPullAtomService(Context context) {
super(context);
@@ -212,6 +220,7 @@
mStatsManager = (StatsManager) mContext.getSystemService(Context.STATS_MANAGER);
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mTelephony = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
// Used to initialize the CPU Frequency atom.
PowerProfile powerProfile = new PowerProfile(mContext);
@@ -224,6 +233,10 @@
numSpeedSteps);
firstCpuOfCluster += powerProfile.getNumCoresInCpuCluster(i);
}
+
+ // Used for CPU_TIME_PER_THREAD_FREQ
+ mKernelCpuThreadReader =
+ KernelCpuThreadReaderSettingsObserver.getSettingsModifiedReader(mContext);
}
@Override
@@ -291,7 +304,6 @@
registerDebugFailingElapsedClock();
registerBuildInformation();
registerRoleHolder();
- registerDangerousPermissionState();
registerTimeZoneDataInfo();
registerExternalStorageInfo();
registerAppsOnExternalStorageInfo();
@@ -346,6 +358,51 @@
return mThermalService;
}
}
+
+ private IStoraged getIStoragedService() {
+ synchronized (mStoragedLock) {
+ if (mStorageService == null) {
+ mStorageService = IStoraged.Stub.asInterface(
+ ServiceManager.getService("storaged"));
+ }
+ if (mStorageService != null) {
+ try {
+ mStorageService.asBinder().linkToDeath(() -> {
+ synchronized (mStoragedLock) {
+ mStorageService = null;
+ }
+ }, /* flags */ 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "linkToDeath with storagedService failed", e);
+ mStorageService = null;
+ }
+ }
+ }
+ return mStorageService;
+ }
+
+ private INotificationManager getINotificationManagerService() {
+ synchronized (mNotificationStatsLock) {
+ if (mNotificationManagerService == null) {
+ mNotificationManagerService = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ }
+ if (mNotificationManagerService != null) {
+ try {
+ mNotificationManagerService.asBinder().linkToDeath(() -> {
+ synchronized (mNotificationStatsLock) {
+ mNotificationManagerService = null;
+ }
+ }, /* flags */ 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "linkToDeath with notificationManager failed", e);
+ mNotificationManagerService = null;
+ }
+ }
+ }
+ return mNotificationManagerService;
+ }
+
private void registerWifiBytesTransfer() {
int tagId = StatsLog.WIFI_BYTES_TRANSFER;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
@@ -935,12 +992,29 @@
return StatsManager.PULL_SUCCESS;
}
+ private static final long NS_PER_SEC = 1000000000;
+
private void registerSystemElapsedRealtime() {
- // No op.
+ int tagId = StatsLog.SYSTEM_ELAPSED_REALTIME;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setCoolDownNs(NS_PER_SEC)
+ .setTimeoutNs(NS_PER_SEC / 2)
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullSystemElapsedRealtime(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullSystemElapsedRealtime() {
- // No op.
+ private int pullSystemElapsedRealtime(int atomTag, List<StatsEvent> pulledData) {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(SystemClock.elapsedRealtime())
+ .build();
+ pulledData.add(e);
+ return StatsManager.PULL_SUCCESS;
}
private void registerSystemUptime() {
@@ -1426,59 +1500,372 @@
}
private void registerLooperStats() {
- // No op.
+ int tagId = StatsLog.LOOPER_STATS;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setAdditiveFields(new int[] {5, 6, 7, 8, 9})
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullLooperStats(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullLooperStats() {
- // No op.
+ private int pullLooperStats(int atomTag, List<StatsEvent> pulledData) {
+ LooperStats looperStats = LocalServices.getService(LooperStats.class);
+ if (looperStats == null) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+ looperStats.reset();
+ for (LooperStats.ExportedEntry entry : entries) {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(entry.workSourceUid)
+ .writeString(entry.handlerClassName)
+ .writeString(entry.threadName)
+ .writeString(entry.messageName)
+ .writeLong(entry.messageCount)
+ .writeLong(entry.exceptionCount)
+ .writeLong(entry.recordedMessageCount)
+ .writeLong(entry.totalLatencyMicros)
+ .writeLong(entry.cpuUsageMicros)
+ .writeBoolean(entry.isInteractive)
+ .writeLong(entry.maxCpuUsageMicros)
+ .writeLong(entry.maxLatencyMicros)
+ .writeLong(entry.recordedDelayMessageCount)
+ .writeLong(entry.delayMillis)
+ .writeLong(entry.maxDelayMillis)
+ .build();
+ pulledData.add(e);
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerDiskStats() {
- // No op.
+ int tagId = StatsLog.DISK_STATS;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullDiskStats(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDiskStats() {
- // No op.
+ private int pullDiskStats(int atomTag, List<StatsEvent> pulledData) {
+ // Run a quick-and-dirty performance test: write 512 bytes
+ byte[] junk = new byte[512];
+ for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes
+
+ File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp");
+ FileOutputStream fos = null;
+ IOException error = null;
+
+ long before = SystemClock.elapsedRealtime();
+ try {
+ fos = new FileOutputStream(tmp);
+ fos.write(junk);
+ } catch (IOException e) {
+ error = e;
+ } finally {
+ try {
+ if (fos != null) fos.close();
+ } catch (IOException e) {
+ // Do nothing.
+ }
+ }
+
+ long latency = SystemClock.elapsedRealtime() - before;
+ if (tmp.exists()) tmp.delete();
+
+ if (error != null) {
+ Slog.e(TAG, "Error performing diskstats latency test");
+ latency = -1;
+ }
+ // File based encryption.
+ boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
+
+ //Recent disk write speed. Binder call to storaged.
+ int writeSpeed = -1;
+ IStoraged storaged = getIStoragedService();
+ if (storaged == null) {
+ return StatsManager.PULL_SKIP;
+ }
+ try {
+ writeSpeed = storaged.getRecentPerf();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "storaged not found");
+ }
+
+ // Add info pulledData.
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeLong(latency)
+ .writeBoolean(fileBased)
+ .writeInt(writeSpeed)
+ .build();
+ pulledData.add(e);
+ return StatsManager.PULL_SUCCESS;
}
private void registerDirectoryUsage() {
- // No op.
+ int tagId = StatsLog.DIRECTORY_USAGE;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullDirectoryUsage(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDirectoryUsage() {
- // No op.
+ private int pullDirectoryUsage(int atomTag, List<StatsEvent> pulledData) {
+ StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
+ StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
+ StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA)
+ .writeLong(statFsData.getAvailableBytes())
+ .writeLong(statFsData.getTotalBytes())
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE)
+ .writeLong(statFsCache.getAvailableBytes())
+ .writeLong(statFsCache.getTotalBytes())
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM)
+ .writeLong(statFsSystem.getAvailableBytes())
+ .writeLong(statFsSystem.getTotalBytes())
+ .build();
+ pulledData.add(e);
+ return StatsManager.PULL_SUCCESS;
}
private void registerAppSize() {
- // No op.
+ int tagId = StatsLog.APP_SIZE;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullAppSize(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullAppSize() {
- // No op.
+ private int pullAppSize(int atomTag, List<StatsEvent> pulledData) {
+ try {
+ String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+ JSONObject json = new JSONObject(jsonStr);
+ long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L);
+ JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY);
+ JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY);
+ JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY);
+ JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY);
+ // Sanity check: Ensure all 4 lists have the same length.
+ int length = pkg_names.length();
+ if (app_sizes.length() != length || app_data_sizes.length() != length
+ || app_cache_sizes.length() != length) {
+ Slog.e(TAG, "formatting error in diskstats cache file!");
+ return StatsManager.PULL_SKIP;
+ }
+ for (int i = 0; i < length; i++) {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeString(pkg_names.getString(i))
+ .writeLong(app_sizes.optLong(i, /* fallback */ -1L))
+ .writeLong(app_data_sizes.optLong(i, /* fallback */ -1L))
+ .writeLong(app_cache_sizes.optLong(i, /* fallback */ -1L))
+ .writeLong(cache_time)
+ .build();
+ pulledData.add(e);
+ }
+ } catch (IOException | JSONException e) {
+ Slog.e(TAG, "exception reading diskstats cache file", e);
+ return StatsManager.PULL_SKIP;
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerCategorySize() {
- // No op.
+ int tagId = StatsLog.CATEGORY_SIZE;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullCategorySize(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullCategorySize() {
- // No op.
+ private int pullCategorySize(int atomTag, List<StatsEvent> pulledData) {
+ try {
+ String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH);
+ JSONObject json = new JSONObject(jsonStr);
+ long cacheTime = json.optLong(
+ DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, /* fallback */ -1L);
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.APP_SIZE_AGG_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.APP_CACHE_AGG_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.PHOTOS_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS)
+ .writeLong(
+ json.optLong(DiskStatsFileLogger.VIDEOS_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.AUDIO_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS)
+ .writeLong(
+ json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.SYSTEM_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+
+ e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER)
+ .writeLong(json.optLong(
+ DiskStatsFileLogger.MISC_KEY, /* fallback */ -1L))
+ .writeLong(cacheTime)
+ .build();
+ pulledData.add(e);
+ } catch (IOException | JSONException e) {
+ Slog.e(TAG, "exception reading diskstats cache file", e);
+ return StatsManager.PULL_SKIP;
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerNumFingerprintsEnrolled() {
- // No op.
- }
-
- private void pullNumFingerprintsEnrolled() {
- // No op.
+ int tagId = StatsLog.NUM_FINGERPRINTS_ENROLLED;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullNumBiometricsEnrolled(
+ BiometricsProtoEnums.MODALITY_FINGERPRINT, atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
private void registerNumFacesEnrolled() {
- // No op.
+ int tagId = StatsLog.NUM_FACES_ENROLLED;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullNumBiometricsEnrolled(
+ BiometricsProtoEnums.MODALITY_FACE, atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullNumFacesEnrolled() {
- // No op.
+ private int pullNumBiometricsEnrolled(int modality, int atomTag, List<StatsEvent> pulledData) {
+ final PackageManager pm = mContext.getPackageManager();
+ FingerprintManager fingerprintManager = null;
+ FaceManager faceManager = null;
+
+ if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ fingerprintManager = mContext.getSystemService(FingerprintManager.class);
+ }
+ if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ faceManager = mContext.getSystemService(FaceManager.class);
+ }
+
+ if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT && fingerprintManager == null) {
+ return StatsManager.PULL_SKIP;
+ }
+ if (modality == BiometricsProtoEnums.MODALITY_FACE && faceManager == null) {
+ return StatsManager.PULL_SKIP;
+ }
+ UserManager userManager = mContext.getSystemService(UserManager.class);
+ if (userManager == null) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ for (UserInfo user : userManager.getUsers()) {
+ final int userId = user.getUserHandle().getIdentifier();
+ int numEnrolled = 0;
+ if (modality == BiometricsProtoEnums.MODALITY_FINGERPRINT) {
+ numEnrolled = fingerprintManager.getEnrolledFingerprints(userId).size();
+ } else if (modality == BiometricsProtoEnums.MODALITY_FACE) {
+ numEnrolled = faceManager.getEnrolledFaces(userId).size();
+ } else {
+ return StatsManager.PULL_SKIP;
+ }
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(userId)
+ .writeInt(numEnrolled)
+ .build();
+ pulledData.add(e);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerProcStats() {
@@ -1497,12 +1884,44 @@
// No op.
}
+ private StoragedUidIoStatsReader mStoragedUidIoStatsReader =
+ new StoragedUidIoStatsReader();
+
private void registerDiskIO() {
- // No op.
+ int tagId = StatsLog.DISK_IO;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setAdditiveFields(new int[] {2, 3, 4, 5, 6, 7, 8, 9, 10, 11})
+ .setCoolDownNs(3 * NS_PER_SEC)
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullDiskIO(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDiskIO() {
- // No op.
+ private int pullDiskIO(int atomTag, List<StatsEvent> pulledData) {
+ mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
+ fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
+ fgFsync, bgFsync) -> {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(uid)
+ .writeLong(fgCharsRead)
+ .writeLong(fgCharsWrite)
+ .writeLong(fgBytesRead)
+ .writeLong(fgBytesWrite)
+ .writeLong(bgCharsRead)
+ .writeLong(bgCharsWrite)
+ .writeLong(bgBytesRead)
+ .writeLong(bgBytesWrite)
+ .writeLong(fgFsync)
+ .writeLong(bgFsync)
+ .build();
+ pulledData.add(e);
+ });
+ return StatsManager.PULL_SUCCESS;
}
private void registerPowerProfile() {
@@ -1528,20 +1947,118 @@
return StatsManager.PULL_SUCCESS;
}
+ private final Object mCpuTrackerLock = new Object();
+ @GuardedBy("mCpuTrackerLock")
+ private ProcessCpuTracker mProcessCpuTracker;
+
private void registerProcessCpuTime() {
- // No op.
+ int tagId = StatsLog.PROCESS_CPU_TIME;
+ // Min cool-down is 5 sec, inline with what ActivityManagerService uses.
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setCoolDownNs(5 * NS_PER_SEC)
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullProcessCpuTime(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullProcessCpuTime() {
- // No op.
+ private int pullProcessCpuTime(int atomTag, List<StatsEvent> pulledData) {
+ synchronized (mCpuTrackerLock) {
+ if (mProcessCpuTracker == null) {
+ mProcessCpuTracker = new ProcessCpuTracker(false);
+ mProcessCpuTracker.init();
+ }
+ mProcessCpuTracker.update();
+ for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
+ ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(st.uid)
+ .writeString(st.name)
+ .writeLong(st.base_utime)
+ .writeLong(st.base_stime)
+ .build();
+ pulledData.add(e);
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
}
+ @Nullable
+ private KernelCpuThreadReaderDiff mKernelCpuThreadReader;
+ private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
+
private void registerCpuTimePerThreadFreq() {
- // No op.
+ int tagId = StatsLog.CPU_TIME_PER_THREAD_FREQ;
+ PullAtomMetadata metadata = PullAtomMetadata.newBuilder()
+ .setAdditiveFields(new int[] {7, 9, 11, 13, 15, 17, 19, 21})
+ .build();
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ metadata,
+ (atomTag, data) -> pullCpuTimePerThreadFreq(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullCpuTimePerThreadFreq() {
- // No op.
+ private int pullCpuTimePerThreadFreq(int atomTag, List<StatsEvent> pulledData) {
+ if (this.mKernelCpuThreadReader == null) {
+ Slog.e(TAG, "mKernelCpuThreadReader is null");
+ return StatsManager.PULL_SKIP;
+ }
+ ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
+ this.mKernelCpuThreadReader.getProcessCpuUsageDiffed();
+ if (processCpuUsages == null) {
+ Slog.e(TAG, "processCpuUsages is null");
+ return StatsManager.PULL_SKIP;
+ }
+ int[] cpuFrequencies = mKernelCpuThreadReader.getCpuFrequenciesKhz();
+ if (cpuFrequencies.length > CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES) {
+ String message = "Expected maximum " + CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES
+ + " frequencies, but got " + cpuFrequencies.length;
+ Slog.w(TAG, message);
+ return StatsManager.PULL_SKIP;
+ }
+ for (int i = 0; i < processCpuUsages.size(); i++) {
+ KernelCpuThreadReader.ProcessCpuUsage processCpuUsage = processCpuUsages.get(i);
+ ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
+ processCpuUsage.threadCpuUsages;
+ for (int j = 0; j < threadCpuUsages.size(); j++) {
+ KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage = threadCpuUsages.get(j);
+ if (threadCpuUsage.usageTimesMillis.length != cpuFrequencies.length) {
+ String message = "Unexpected number of usage times,"
+ + " expected " + cpuFrequencies.length
+ + " but got " + threadCpuUsage.usageTimesMillis.length;
+ Slog.w(TAG, message);
+ return StatsManager.PULL_SKIP;
+ }
+
+ StatsEvent.Builder e = StatsEvent.newBuilder();
+ e.setAtomId(atomTag);
+ e.writeInt(processCpuUsage.uid);
+ e.writeInt(processCpuUsage.processId);
+ e.writeInt(threadCpuUsage.threadId);
+ e.writeString(processCpuUsage.processName);
+ e.writeString(threadCpuUsage.threadName);
+ for (int k = 0; k < CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES; k++) {
+ if (k < cpuFrequencies.length) {
+ e.writeInt(cpuFrequencies[k]);
+ e.writeInt(threadCpuUsage.usageTimesMillis[k]);
+ } else {
+ // If we have no more frequencies to write, we still must write empty data.
+ // We know that this data is empty (and not just zero) because all
+ // frequencies are expected to be greater than zero
+ e.writeInt(0);
+ e.writeInt(0);
+ }
+ }
+ pulledData.add(e.build());
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
}
// TODO: move to top of file when all migrations are complete
@@ -1703,43 +2220,280 @@
}
private void registerRoleHolder() {
- // No op.
+ int tagId = StatsLog.ROLE_HOLDER;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullRoleHolder(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullRoleHolder() {
- // No op.
+ // Add a RoleHolder atom for each package that holds a role.
+ private int pullRoleHolder(int atomTag, List<StatsEvent> pulledData) {
+ long callingToken = Binder.clearCallingIdentity();
+ try {
+ PackageManager pm = mContext.getPackageManager();
+ RoleManagerInternal rmi = LocalServices.getService(RoleManagerInternal.class);
+
+ List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+ int numUsers = users.size();
+ for (int userNum = 0; userNum < numUsers; userNum++) {
+ int userId = users.get(userNum).getUserHandle().getIdentifier();
+
+ ArrayMap<String, ArraySet<String>> roles = rmi.getRolesAndHolders(userId);
+
+ int numRoles = roles.size();
+ for (int roleNum = 0; roleNum < numRoles; roleNum++) {
+ String roleName = roles.keyAt(roleNum);
+ ArraySet<String> holders = roles.valueAt(roleNum);
+
+ int numHolders = holders.size();
+ for (int holderNum = 0; holderNum < numHolders; holderNum++) {
+ String holderName = holders.valueAt(holderNum);
+
+ PackageInfo pkg;
+ try {
+ pkg = pm.getPackageInfoAsUser(holderName, 0, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Role holder " + holderName + " not found");
+ return StatsManager.PULL_SKIP;
+ }
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(pkg.applicationInfo.uid)
+ .writeString(holderName)
+ .writeString(roleName)
+ .build();
+ pulledData.add(e);
+ }
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerDangerousPermissionState() {
- // No op.
+ int tagId = StatsLog.DANGEROUS_PERMISSION_STATE;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullDangerousPermissionState() {
- // No op.
+ private int pullDangerousPermissionState(int atomTag, List<StatsEvent> pulledData) {
+ final long token = Binder.clearCallingIdentity();
+ Set<Integer> reportedUids = new HashSet<>();
+ try {
+ PackageManager pm = mContext.getPackageManager();
+
+ List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+ int numUsers = users.size();
+ for (int userNum = 0; userNum < numUsers; userNum++) {
+ UserHandle user = users.get(userNum).getUserHandle();
+
+ List<PackageInfo> pkgs = pm.getInstalledPackagesAsUser(
+ PackageManager.GET_PERMISSIONS, user.getIdentifier());
+
+ int numPkgs = pkgs.size();
+ for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
+ PackageInfo pkg = pkgs.get(pkgNum);
+
+ if (pkg.requestedPermissions == null) {
+ continue;
+ }
+
+ if (reportedUids.contains(pkg.applicationInfo.uid)) {
+ // do not report same uid twice
+ continue;
+ }
+ reportedUids.add(pkg.applicationInfo.uid);
+
+ if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED
+ && ThreadLocalRandom.current().nextFloat() > 0.2f) {
+ continue;
+ }
+
+ int numPerms = pkg.requestedPermissions.length;
+ for (int permNum = 0; permNum < numPerms; permNum++) {
+ String permName = pkg.requestedPermissions[permNum];
+
+ PermissionInfo permissionInfo;
+ int permissionFlags = 0;
+ try {
+ permissionInfo = pm.getPermissionInfo(permName, 0);
+ permissionFlags =
+ pm.getPermissionFlags(permName, pkg.packageName, user);
+ } catch (PackageManager.NameNotFoundException ignored) {
+ continue;
+ }
+
+ if (permissionInfo.getProtection() != PROTECTION_DANGEROUS) {
+ continue;
+ }
+
+ StatsEvent.Builder e = StatsEvent.newBuilder();
+ e.setAtomId(atomTag);
+ e.writeString(permName);
+ e.writeInt(pkg.applicationInfo.uid);
+ if (atomTag == StatsLog.DANGEROUS_PERMISSION_STATE) {
+ e.writeString("");
+ }
+ e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
+ & REQUESTED_PERMISSION_GRANTED) != 0);
+ e.writeInt(permissionFlags);
+
+ pulledData.add(e.build());
+ }
+ }
+ }
+ } catch (Throwable t) {
+ Log.e(TAG, "Could not read permissions", t);
+ return StatsManager.PULL_SKIP;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerTimeZoneDataInfo() {
- // No op.
+ int tagId = StatsLog.TIME_ZONE_DATA_INFO;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullTimeZoneDataInfo(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullTimeZoneDataInfo() {
- // No op.
+ private int pullTimeZoneDataInfo(int atomTag, List<StatsEvent> pulledData) {
+ String tzDbVersion = "Unknown";
+ try {
+ tzDbVersion = android.icu.util.TimeZone.getTZDataVersion();
+ } catch (MissingResourceException e) {
+ Slog.e(TAG, "Getting tzdb version failed: ", e);
+ return StatsManager.PULL_SKIP;
+ }
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeString(tzDbVersion)
+ .build();
+ pulledData.add(e);
+ return StatsManager.PULL_SUCCESS;
}
private void registerExternalStorageInfo() {
- // No op.
+ int tagId = StatsLog.EXTERNAL_STORAGE_INFO;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullExternalStorageInfo(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullExternalStorageInfo() {
- // No op.
+ private int pullExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+ if (mStorageManager == null) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ List<VolumeInfo> volumes = mStorageManager.getVolumes();
+ for (VolumeInfo vol : volumes) {
+ final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
+ final DiskInfo diskInfo = vol.getDisk();
+ if (diskInfo != null && envState.equals(Environment.MEDIA_MOUNTED)) {
+ // Get the type of the volume, if it is adoptable or portable.
+ int volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__OTHER;
+ if (vol.getType() == TYPE_PUBLIC) {
+ volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PUBLIC;
+ } else if (vol.getType() == TYPE_PRIVATE) {
+ volumeType = StatsLog.EXTERNAL_STORAGE_INFO__VOLUME_TYPE__PRIVATE;
+ }
+
+ // Get the type of external storage inserted in the device (sd cards, usb, etc.)
+ int externalStorageType;
+ if (diskInfo.isSd()) {
+ externalStorageType = StorageEnums.SD_CARD;
+ } else if (diskInfo.isUsb()) {
+ externalStorageType = StorageEnums.USB;
+ } else {
+ externalStorageType = StorageEnums.OTHER;
+ }
+
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(externalStorageType)
+ .writeInt(volumeType)
+ .writeLong(diskInfo.size)
+ .build();
+ pulledData.add(e);
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerAppsOnExternalStorageInfo() {
- // No op.
+ int tagId = StatsLog.APPS_ON_EXTERNAL_STORAGE_INFO;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullAppsOnExternalStorageInfo(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullAppsOnExternalStorageInfo() {
- // No op.
+ private int pullAppsOnExternalStorageInfo(int atomTag, List<StatsEvent> pulledData) {
+ if (mStorageManager == null) {
+ return StatsManager.PULL_SKIP;
+ }
+
+ PackageManager pm = mContext.getPackageManager();
+ List<ApplicationInfo> apps = pm.getInstalledApplications(/*flags=*/ 0);
+ for (ApplicationInfo appInfo : apps) {
+ UUID storageUuid = appInfo.storageUuid;
+ if (storageUuid == null) {
+ continue;
+ }
+
+ VolumeInfo volumeInfo = mStorageManager.findVolumeByUuid(
+ appInfo.storageUuid.toString());
+ if (volumeInfo == null) {
+ continue;
+ }
+
+ DiskInfo diskInfo = volumeInfo.getDisk();
+ if (diskInfo == null) {
+ continue;
+ }
+
+ int externalStorageType = -1;
+ if (diskInfo.isSd()) {
+ externalStorageType = StorageEnums.SD_CARD;
+ } else if (diskInfo.isUsb()) {
+ externalStorageType = StorageEnums.USB;
+ } else if (appInfo.isExternal()) {
+ externalStorageType = StorageEnums.OTHER;
+ }
+
+ // App is installed on external storage.
+ if (externalStorageType != -1) {
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeInt(externalStorageType)
+ .writeString(appInfo.packageName)
+ .build();
+ pulledData.add(e);
+ }
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerFaceSettings() {
@@ -1751,26 +2505,167 @@
}
private void registerAppOps() {
- // No op.
+ int tagId = StatsLog.APP_OPS;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullAppOps(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
+
}
- private void pullAppOps() {
- // No op.
+ private int pullAppOps(int atomTag, List<StatsEvent> pulledData) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+
+ CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
+ HistoricalOpsRequest histOpsRequest =
+ new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).build();
+ appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);
+
+ HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
+ TimeUnit.MILLISECONDS);
+
+ for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
+ final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
+ final int uid = uidOps.getUid();
+ for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
+ final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
+ for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
+ final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
+
+ StatsEvent.Builder e = StatsEvent.newBuilder();
+ e.setAtomId(atomTag);
+ e.writeInt(uid);
+ e.writeString(packageOps.getPackageName());
+ e.writeInt(op.getOpCode());
+ e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+ e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
+
+ String perm = AppOpsManager.opToPermission(op.getOpCode());
+ if (perm == null) {
+ e.writeBoolean(false);
+ } else {
+ PermissionInfo permInfo;
+ try {
+ permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
+ e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
+ } catch (PackageManager.NameNotFoundException exception) {
+ e.writeBoolean(false);
+ }
+ }
+
+ pulledData.add(e.build());
+ }
+ }
+ }
+ } catch (Throwable t) {
+ // TODO: catch exceptions at a more granular level
+ Slog.e(TAG, "Could not read appops", t);
+ return StatsManager.PULL_SKIP;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+
+ static void unpackStreamedData(int atomTag, List<StatsEvent> pulledData,
+ List<ParcelFileDescriptor> statsFiles) throws IOException {
+ InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
+ int[] len = new int[1];
+ byte[] stats = readFully(stream, len);
+ StatsEvent e = StatsEvent.newBuilder()
+ .setAtomId(atomTag)
+ .writeByteArray(Arrays.copyOf(stats, len[0]))
+ .build();
+ pulledData.add(e);
+ }
+
+ static byte[] readFully(InputStream stream, int[] outLen) throws IOException {
+ int pos = 0;
+ final int initialAvail = stream.available();
+ byte[] data = new byte[initialAvail > 0 ? (initialAvail + 1) : 16384];
+ while (true) {
+ int amt = stream.read(data, pos, data.length - pos);
+ if (DEBUG) {
+ Slog.i(TAG, "Read " + amt + " bytes at " + pos + " of avail " + data.length);
+ }
+ if (amt < 0) {
+ if (DEBUG) {
+ Slog.i(TAG, "**** FINISHED READING: pos=" + pos + " len=" + data.length);
+ }
+ outLen[0] = pos;
+ return data;
+ }
+ pos += amt;
+ if (pos >= data.length) {
+ byte[] newData = new byte[pos + 16384];
+ if (DEBUG) {
+ Slog.i(TAG, "Copying " + pos + " bytes to new array len " + newData.length);
+ }
+ System.arraycopy(data, 0, newData, 0, pos);
+ data = newData;
+ }
+ }
}
private void registerNotificationRemoteViews() {
- // No op.
+ int tagId = StatsLog.NOTIFICATION_REMOTE_VIEWS;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullNotificationRemoteViews(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
- private void pullNotificationRemoteViews() {
- // No op.
+ private int pullNotificationRemoteViews(int atomTag, List<StatsEvent> pulledData) {
+ INotificationManager notificationManagerService = getINotificationManagerService();
+ if (notificationManagerService == null) {
+ return StatsManager.PULL_SKIP;
+ }
+ final long callingToken = Binder.clearCallingIdentity();
+ try {
+ // determine last pull tine. Copy file trick from pullProcessStats?
+ long wallClockNanos = SystemClock.currentTimeMicro() * 1000L;
+ long lastNotificationStatsNs = wallClockNanos -
+ TimeUnit.NANOSECONDS.convert(1, TimeUnit.DAYS);
+
+ List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+ notificationManagerService.pullStats(lastNotificationStatsNs,
+ NotificationManagerService.REPORT_REMOTE_VIEWS, true, statsFiles);
+ if (statsFiles.size() != 1) {
+ return StatsManager.PULL_SKIP;
+ }
+ unpackStreamedData(atomTag, pulledData, statsFiles);
+ } catch (IOException e) {
+ Slog.e(TAG, "Getting notistats failed: ", e);
+ return StatsManager.PULL_SKIP;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Getting notistats failed: ", e);
+ return StatsManager.PULL_SKIP;
+ } catch (SecurityException e) {
+ Slog.e(TAG, "Getting notistats failed: ", e);
+ return StatsManager.PULL_SKIP;
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
+ }
+ return StatsManager.PULL_SUCCESS;
}
private void registerDangerousPermissionStateSampled() {
- // No op.
- }
-
- private void pullDangerousPermissionStateSampled() {
- // No op.
+ int tagId = StatsLog.DANGEROUS_PERMISSION_STATE_SAMPLED;
+ mStatsManager.registerPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ (atomTag, data) -> pullDangerousPermissionState(atomTag, data),
+ BackgroundThread.getExecutor()
+ );
}
}
diff --git a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
index 9cd743b..8b6526ff 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
@@ -20,6 +20,7 @@
#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <vector>
#include <jni.h>
diff --git a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
index ecd07bd..b14291b 100644
--- a/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/OverrideValidatorImplTest.java
@@ -188,7 +188,7 @@
}
@Test
- public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_rejectOverride()
+ public void getOverrideAllowedState_betaBuildEnabledChangeDebugApp_allowOverride()
throws Exception {
CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
.addEnabledChangeWithId(1).build();
@@ -203,11 +203,11 @@
overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
assertThat(allowedState)
- .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+ .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
}
@Test
- public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_rejectOverride()
+ public void getOverrideAllowedState_betaBuildDisabledChangeDebugApp_allowOverride()
throws Exception {
CompatConfig config = CompatConfigBuilder.create(betaBuild(), mContext)
.addDisabledChangeWithId(1).build();
@@ -221,7 +221,7 @@
overrideValidator.getOverrideAllowedState(1, PACKAGE_NAME);
assertThat(allowedState)
- .isEqualTo(new OverrideAllowedState(DISABLED_NON_TARGET_SDK, -1, -1));
+ .isEqualTo(new OverrideAllowedState(ALLOWED, -1, -1));
}
@Test
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index c4c1e21..c3fb510 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -849,6 +849,17 @@
*/
public static final int PRESENTATION_PAYPHONE = 4;
+
+ /*
+ * Values for the adb property "persist.radio.videocall.audio.output"
+ */
+ /** @hide */
+ public static final int AUDIO_OUTPUT_ENABLE_SPEAKER = 0;
+ /** @hide */
+ public static final int AUDIO_OUTPUT_DISABLE_SPEAKER = 1;
+ /** @hide */
+ public static final int AUDIO_OUTPUT_DEFAULT = AUDIO_OUTPUT_ENABLE_SPEAKER;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index b8b203d..89cd461 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -558,7 +558,7 @@
}
if (DBG) {
- Log.d(LOG_TAG, "No READ_PRIVILEDED_PHONE_STATE permission, "
+ Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE permission, "
+ "check carrier privilege next.");
}
@@ -566,6 +566,33 @@
}
/**
+ * Ensure the caller (or self, if not processing an IPC) has
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+ * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or carrier privileges.
+ *
+ * @throws SecurityException if the caller does not have the required permission/privileges
+ */
+ public static void enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+ Context context, int subId, String message) {
+ if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ == PERMISSION_GRANTED) {
+ return;
+ }
+
+ if (context.checkCallingOrSelfPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
+ == PERMISSION_GRANTED) {
+ return;
+ }
+
+ if (DBG) {
+ Log.d(LOG_TAG, "No READ_PRIVILEGED_PHONE_STATE nor READ_PRECISE_PHONE_STATE permission"
+ + ", check carrier privilege next.");
+ }
+
+ enforceCallingOrSelfCarrierPrivilege(context, subId, message);
+ }
+
+ /**
* Make sure the caller (or self, if not processing an IPC) has carrier privileges.
*
* @throws SecurityException if the caller does not have the required privileges
diff --git a/telephony/framework-telephony-jarjar-rules.txt b/telephony/framework-telephony-jarjar-rules.txt
index 7cab806..212eba1 100644
--- a/telephony/framework-telephony-jarjar-rules.txt
+++ b/telephony/framework-telephony-jarjar-rules.txt
@@ -1,4 +1,9 @@
rule android.telephony.Annotation* android.telephony.framework.Annotation@1
+rule android.util.RecurrenceRule* android.telephony.RecurrenceRule@1
rule com.android.i18n.phonenumbers.** com.android.telephony.framework.phonenumbers.@1
-#TODO: add jarjar rules for statically linked util classes
-
+rule com.android.internal.os.SomeArgs* android.telephony.SomeArgs@1
+rule com.android.internal.util.BitwiseInputStream* android.telephony.BitwiseInputStream@1
+rule com.android.internal.util.BitwiseOutputStream* android.telephony.BitwiseOutputStream@1
+rule com.android.internal.util.Preconditions* android.telephony.Preconditions@1
+rule com.android.internal.util.IndentingPrintWriter* android.telephony.IndentingPrintWriter@1
+rule com.android.internal.util.HexDump* android.telephony.HexDump@1
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index bb28df2..d325cd8 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -50,18 +50,12 @@
/**
* Transport type for Wireless Wide Area Networks (i.e. Cellular)
- * @hide
*/
- @SystemApi
- @TestApi
public static final int TRANSPORT_TYPE_WWAN = 1;
/**
* Transport type for Wireless Local Area Networks (i.e. Wifi)
- * @hide
*/
- @SystemApi
- @TestApi
public static final int TRANSPORT_TYPE_WLAN = 2;
/** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5a7c3b3..ff31d3e 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1575,7 +1575,10 @@
public static final String KEY_MMS_UA_PROF_TAG_NAME_STRING = "uaProfTagName";
public static final String KEY_MMS_UA_PROF_URL_STRING = "uaProfUrl";
public static final String KEY_MMS_USER_AGENT_STRING = "userAgent";
- /** @hide */
+ /**
+ * If true, add "Connection: close" header to MMS HTTP requests so the connection
+ * is immediately closed (disabling keep-alive).
+ */
public static final String KEY_MMS_CLOSE_CONNECTION_BOOL = "mmsCloseConnection";
/**
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index 475c99b..ec86c14 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.SuppressLint;
import android.compat.annotation.UnsupportedAppUsage;
import android.hardware.radio.V1_4.CellInfo.Info;
import android.os.Parcel;
@@ -179,6 +180,18 @@
*
* @return a time stamp in nanos since boot.
*/
+ @SuppressLint("MethodNameUnits")
+ public long getTimestampNanos() {
+ return mTimeStamp;
+ }
+
+ /**
+ * Approximate time this cell information was received from the modem.
+ *
+ * @return a time stamp in nanos since boot.
+ * @deprecated Use {@link #getTimestampNanos} instead.
+ */
+ @Deprecated
public long getTimeStamp() {
return mTimeStamp;
}
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index cbd5ed6..32ffb75 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -36,10 +36,7 @@
/**
* Description of a mobile network registration info
- * @hide
*/
-@SystemApi
-@TestApi
public final class NetworkRegistrationInfo implements Parcelable {
/**
* Network domain
@@ -51,9 +48,9 @@
/** Unknown / Unspecified domain */
public static final int DOMAIN_UNKNOWN = 0;
- /** Circuit switching domain */
+ /** Circuit switched domain */
public static final int DOMAIN_CS = android.hardware.radio.V1_5.Domain.CS;
- /** Packet switching domain */
+ /** Packet switched domain */
public static final int DOMAIN_PS = android.hardware.radio.V1_5.Domain.PS;
/** Applicable to both CS and PS Domain */
public static final int DOMAIN_CS_PS = DOMAIN_CS | DOMAIN_PS;
@@ -69,17 +66,41 @@
REGISTRATION_STATE_UNKNOWN, REGISTRATION_STATE_ROAMING})
public @interface RegistrationState {}
- /** Not registered. The device is not currently searching a new operator to register. */
+ /**
+ * Not registered. The device is not currently searching a new operator to register.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0;
- /** Registered on home network. */
+ /**
+ * Registered on home network.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_HOME = 1;
- /** Not registered. The device is currently searching a new operator to register. */
+ /**
+ * Not registered. The device is currently searching a new operator to register.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2;
- /** Registration denied. */
+ /**
+ * Registration denied.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_DENIED = 3;
- /** Registration state is unknown. */
+ /**
+ * Registration state is unknown.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_UNKNOWN = 4;
- /** Registered on roaming network. */
+ /**
+ * Registered on roaming network.
+ * @hide
+ */
+ @SystemApi @TestApi
public static final int REGISTRATION_STATE_ROAMING = 5;
/** @hide */
@@ -92,7 +113,6 @@
/**
* The device isn't camped on an LTE cell or the LTE cell doesn't support E-UTRA-NR
* Dual Connectivity(EN-DC).
- * @hide
*/
public static final int NR_STATE_NONE = 0;
@@ -100,7 +120,6 @@
* The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) but
* either the use of dual connectivity with NR(DCNR) is restricted or NR is not supported by
* the selected PLMN.
- * @hide
*/
public static final int NR_STATE_RESTRICTED = 1;
@@ -108,14 +127,12 @@
* The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and both
* the use of dual connectivity with NR(DCNR) is not restricted and NR is supported by the
* selected PLMN.
- * @hide
*/
public static final int NR_STATE_NOT_RESTRICTED = 2;
/**
* The device is camped on an LTE cell that supports E-UTRA-NR Dual Connectivity(EN-DC) and
* also connected to at least one 5G cell as a secondary serving cell.
- * @hide
*/
public static final int NR_STATE_CONNECTED = 3;
@@ -129,22 +146,34 @@
SERVICE_TYPE_VIDEO, SERVICE_TYPE_EMERGENCY})
public @interface ServiceType {}
- /** Unkown service */
+ /**
+ * Unknown service
+ */
public static final int SERVICE_TYPE_UNKNOWN = 0;
- /** Voice service */
+ /**
+ * Voice service
+ */
public static final int SERVICE_TYPE_VOICE = 1;
- /** Data service */
+ /**
+ * Data service
+ */
public static final int SERVICE_TYPE_DATA = 2;
- /** SMS service */
+ /**
+ * SMS service
+ */
public static final int SERVICE_TYPE_SMS = 3;
- /** Video service */
+ /**
+ * Video service
+ */
public static final int SERVICE_TYPE_VIDEO = 4;
- /** Emergency service */
+ /**
+ * Emergency service
+ */
public static final int SERVICE_TYPE_EMERGENCY = 5;
@Domain
@@ -330,9 +359,7 @@
* Get the 5G NR connection state.
*
* @return the 5G NR connection state.
- * @hide
*/
- @SystemApi
public @NRState int getNrState() {
return mNrState;
}
@@ -344,7 +371,10 @@
/**
* @return The registration state.
+ *
+ * @hide
*/
+ @SystemApi @TestApi
public @RegistrationState int getRegistrationState() {
return mRegistrationState;
}
@@ -352,6 +382,21 @@
/**
* @return {@code true} if registered on roaming network, {@code false} otherwise.
*/
+ public boolean isRegistered() {
+ return mRegistrationState == REGISTRATION_STATE_HOME
+ || mRegistrationState == REGISTRATION_STATE_ROAMING;
+ }
+
+ /**
+ * @return {@code true} if registered on roaming network, {@code false} otherwise.
+ */
+ public boolean isSearching() {
+ return mRegistrationState == REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
+ }
+
+ /**
+ * @return {@code true} if registered on roaming network, {@code false} otherwise.
+ */
public boolean isRoaming() {
return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
}
@@ -376,15 +421,18 @@
/**
* @return the current network roaming type.
+ * @hide
*/
-
+ @SystemApi @TestApi
public @ServiceState.RoamingType int getRoamingType() {
return mRoamingType;
}
/**
* @return Whether emergency is enabled.
+ * @hide
*/
+ @SystemApi @TestApi
public boolean isEmergencyEnabled() { return mEmergencyOnly; }
/**
@@ -422,7 +470,9 @@
* @return Reason for denial if the registration state is {@link #REGISTRATION_STATE_DENIED}.
* Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
* 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
+ * @hide
*/
+ @SystemApi @TestApi
public int getRejectCause() {
return mRejectCause;
}
@@ -445,8 +495,10 @@
/**
* @return Data registration related info
+ * @hide
*/
@Nullable
+ @SystemApi @TestApi
public DataSpecificRegistrationInfo getDataSpecificInfo() {
return mDataSpecificInfo;
}
@@ -571,7 +623,11 @@
&& mNrState == other.mNrState;
}
+ /**
+ * @hide
+ */
@Override
+ @SystemApi @TestApi
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mDomain);
dest.writeInt(mTransportType);
@@ -659,7 +715,9 @@
* .setRegistrationState(REGISTRATION_STATE_HOME)
* .build();
* </code></pre>
+ * @hide
*/
+ @SystemApi @TestApi
public static final class Builder {
@Domain
private int mDomain;
@@ -759,7 +817,9 @@
* @param emergencyOnly True if this network registration is for emergency use only.
*
* @return The same instance of the builder.
+ * @hide
*/
+ @SystemApi @TestApi
public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
mEmergencyOnly = emergencyOnly;
return this;
@@ -771,7 +831,9 @@
* @param availableServices Available services.
*
* @return The same instance of the builder.
+ * @hide
*/
+ @SystemApi @TestApi
public @NonNull Builder setAvailableServices(
@NonNull @ServiceType List<Integer> availableServices) {
mAvailableServices = availableServices;
@@ -784,7 +846,9 @@
* @param cellIdentity The cell identity.
*
* @return The same instance of the builder.
+ * @hide
*/
+ @SystemApi @TestApi
public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
mCellIdentity = cellIdentity;
return this;
@@ -792,9 +856,10 @@
/**
* Build the NetworkRegistrationInfo.
- *
* @return the NetworkRegistrationInfo object.
+ * @hide
*/
+ @SystemApi @TestApi
public @NonNull NetworkRegistrationInfo build() {
return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 2c8014e..1e64a81 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1855,10 +1855,8 @@
* Get all of the available network registration info.
*
* @return List of {@link NetworkRegistrationInfo}
- * @hide
*/
@NonNull
- @SystemApi
public List<NetworkRegistrationInfo> getNetworkRegistrationInfoList() {
synchronized (mNetworkRegistrationInfos) {
List<NetworkRegistrationInfo> newList = new ArrayList<>();
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 1c58f8f..5a4dac5 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -16,9 +16,8 @@
package android.telephony;
-import com.android.telephony.Rlog;
-
import android.annotation.NonNull;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
@@ -26,6 +25,9 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
+import android.os.SystemClock;
+
+import com.android.telephony.Rlog;
import java.util.ArrayList;
import java.util.List;
@@ -77,6 +79,9 @@
/* The type of signal measurement */
private static final String MEASUREMENT_TYPE_RSCP = "rscp";
+ // timeStamp of signalStrength in nanoseconds since boot
+ private long mTimestamp = Long.MAX_VALUE;
+
CellSignalStrengthCdma mCdma;
CellSignalStrengthGsm mGsm;
CellSignalStrengthWcdma mWcdma;
@@ -134,6 +139,7 @@
mTdscdma = tdscdma;
mLte = lte;
mNr = nr;
+ mTimestamp = SystemClock.elapsedRealtimeNanos();
}
/**
@@ -268,6 +274,7 @@
mTdscdma.updateLevel(cc, ss);
mLte.updateLevel(cc, ss);
mNr.updateLevel(cc, ss);
+ mTimestamp = SystemClock.elapsedRealtimeNanos();
}
/**
@@ -293,6 +300,7 @@
mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
mLte = new CellSignalStrengthLte(s.mLte);
mNr = new CellSignalStrengthNr(s.mNr);
+ mTimestamp = s.getTimestampNanos();
}
/**
@@ -310,6 +318,7 @@
mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
+ mTimestamp = in.readLong();
}
/**
@@ -322,9 +331,18 @@
out.writeParcelable(mTdscdma, flags);
out.writeParcelable(mLte, flags);
out.writeParcelable(mNr, flags);
+ out.writeLong(mTimestamp);
}
/**
+ * @return mTimestamp in nanoseconds
+ */
+ @SuppressLint("MethodNameUnits")
+ public long getTimestampNanos() {
+ return mTimestamp;
+ }
+
+ /**
* {@link Parcelable#describeContents}
*/
public int describeContents() {
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index fee6d3f..2f95a50 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -424,7 +424,26 @@
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- true /* persistMessage*/, null);
+ true /* persistMessage*/, null, 0L /* messageId */);
+ }
+
+
+ /**
+ * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress,
+ * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but
+ * adds an optional messageId.
+ * @param messageId An id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
+ *
+ * @throws IllegalArgumentException if destinationAddress or text are empty
+ *
+ */
+ public void sendTextMessage(
+ @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text,
+ @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
+ long messageId) {
+ sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
+ true /* persistMessage*/, null, messageId);
}
/**
@@ -542,7 +561,7 @@
private void sendTextMessageInternal(String destinationAddress, String scAddress,
String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
- boolean persistMessage, String packageName) {
+ boolean persistMessage, String packageName, long messageId) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -569,10 +588,10 @@
try {
iSms.sendTextForSubscriber(subId, packageName,
destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- persistMessage);
+ persistMessage, messageId);
} catch (RemoteException e) {
Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
- + e.getMessage());
+ + e.getMessage() + " id: " + messageId);
notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
}
}
@@ -589,10 +608,10 @@
try {
iSms.sendTextForSubscriber(getSubscriptionId(), packageName,
destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- persistMessage);
+ persistMessage, messageId);
} catch (RemoteException e) {
Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - "
- + e.getMessage());
+ + e.getMessage() + " id: " + messageId);
notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
}
}
@@ -634,7 +653,8 @@
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
- false /* persistMessage */, null);
+ false /* persistMessage */, null,
+ 0L /* messageId */);
}
private void sendTextMessageInternal(
@@ -921,7 +941,26 @@
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, true /* persistMessage*/, null);
+ deliveryIntents, true /* persistMessage*/, null,
+ 0L /* messageId */);
+ }
+
+ /**
+ * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String,
+ * ArrayList, ArrayList, ArrayList), but adds an optional messageId.
+ * @param messageId An id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
+ *
+ * @throws IllegalArgumentException if destinationAddress or data are empty
+ *
+ */
+ public void sendMultipartTextMessage(
+ @NonNull String destinationAddress, @Nullable String scAddress,
+ @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
+ @Nullable List<PendingIntent> deliveryIntents, long messageId) {
+ sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
+ deliveryIntents, true /* persistMessage*/, null,
+ messageId);
}
/**
@@ -946,17 +985,17 @@
@SystemApi
@TestApi
public void sendMultipartTextMessage(
- @NonNull String destinationAddress, @NonNull String scAddress,
+ @NonNull String destinationAddress, @Nullable String scAddress,
@NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
@Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, true /* persistMessage*/, packageName);
+ deliveryIntents, true /* persistMessage*/, packageName, 0L /* messageId */);
}
private void sendMultipartTextMessageInternal(
String destinationAddress, String scAddress, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
- boolean persistMessage, String packageName) {
+ boolean persistMessage, String packageName, long messageId) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -983,10 +1022,11 @@
ISms iSms = getISmsServiceOrThrow();
iSms.sendMultipartTextForSubscriber(subId, packageName,
destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, persistMessage);
+ deliveryIntents, persistMessage, messageId);
} catch (RemoteException e) {
Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
- + e.getMessage());
+ + e.getMessage() + " id: "
+ + messageId);
notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
}
}
@@ -1003,11 +1043,11 @@
if (iSms != null) {
iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
destinationAddress, scAddress, parts, sentIntents, deliveryIntents,
- persistMessage);
+ persistMessage, messageId);
}
} catch (RemoteException e) {
Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
- + e.getMessage());
+ + e.getMessage() + " id: " + messageId);
notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
}
}
@@ -1021,7 +1061,7 @@
deliveryIntent = deliveryIntents.get(0);
}
sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
- sentIntent, deliveryIntent, true, packageName);
+ sentIntent, deliveryIntent, true, packageName, messageId);
}
}
@@ -1051,7 +1091,8 @@
String destinationAddress, String scAddress, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
- deliveryIntents, false /* persistMessage*/, null);
+ deliveryIntents, false /* persistMessage*/, null,
+ 0L /* messageId */);
}
/**
@@ -2545,16 +2586,6 @@
/** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
- /** Represents the received SMS message for importing {@hide} */
- public static final int SMS_TYPE_INCOMING = 0;
- /** Represents the sent SMS message for importing {@hide} */
- public static final int SMS_TYPE_OUTGOING = 1;
-
- /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */
- public static final String MESSAGE_STATUS_SEEN = "seen";
- /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */
- public static final String MESSAGE_STATUS_READ = "read";
-
/**
* Get carrier-dependent MMS configuration values.
*
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c4bcc17..3a66b2c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9534,15 +9534,20 @@
}
/**
- * Requested state of SIM
- *
- * CARD_POWER_DOWN
* Powers down the SIM. SIM must be up prior.
- *
- * CARD_POWER_UP
+ * @hide
+ */
+ @SystemApi
+ public static final int CARD_POWER_DOWN = 0;
+
+ /**
* Powers up the SIM normally. SIM must be down prior.
- *
- * CARD_POWER_UP_PASS_THROUGH
+ * @hide
+ */
+ @SystemApi
+ public static final int CARD_POWER_UP = 1;
+
+ /**
* Powers up the SIM in PASS_THROUGH mode. SIM must be down prior.
* When SIM is powered up in PASS_THOUGH mode, the modem does not send
* any command to it (for example SELECT of MF, or TERMINAL CAPABILITY),
@@ -9555,12 +9560,9 @@
* is activated, and normal behavior occurs at the next SIM initialization,
* unless PASS_THROUGH mode is requested again. Hence, the last power-up mode
* is NOT persistent across boots. On reboot, SIM will power up normally.
+ * @hide
*/
- /** @hide */
- public static final int CARD_POWER_DOWN = 0;
- /** @hide */
- public static final int CARD_POWER_UP = 1;
- /** @hide */
+ @SystemApi
public static final int CARD_POWER_UP_PASS_THROUGH = 2;
/**
@@ -10980,9 +10982,15 @@
}
/**
- * Checks if FEATURE_TELEPHONY_DATA is enabled.
- *
- * @hide
+ * @return true if the current device is "data capable" over a radio on the device.
+ * <p>
+ * "Data capable" means that this device supports packet-switched
+ * data connections over the telephony network.
+ * <p>
+ * Note: the meaning of this flag is subtly different from the
+ * PackageManager.FEATURE_TELEPHONY system feature, which is available
+ * on any device with a telephony radio, even if the device is
+ * voice-only.
*/
public boolean isDataCapable() {
if (mContext == null) return true;
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index fab1bf2..6e630e3 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.ContentValues;
import android.database.Cursor;
import android.hardware.radio.V1_5.ApnTypes;
@@ -28,13 +29,14 @@
import android.provider.Telephony.Carriers;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.NetworkType;
-import com.android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
+import com.android.telephony.Rlog;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
@@ -123,6 +125,122 @@
/** Authentication type for PAP or CHAP. */
public static final int AUTH_TYPE_PAP_OR_CHAP = 3;
+ /**
+ * APN types for data connections. These are usage categories for an APN
+ * entry. One APN entry may support multiple APN types, eg, a single APN
+ * may service regular internet traffic ("default") as well as MMS-specific
+ * connections.<br/>
+ * APN_TYPE_ALL is a special type to indicate that this APN entry can
+ * service all data connections.
+ * <p>
+ * Note: The goal is to deprecate this. Due to the Carrier Table being used
+ * directly, this isn't feasible right now.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_ALL_STRING = "*";
+
+ /**
+ * APN type for default data traffic
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_DEFAULT_STRING = "default";
+
+
+ /**
+ * APN type for MMS traffic
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_MMS_STRING = "mms";
+
+
+ /**
+ * APN type for SUPL assisted GPS
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_SUPL_STRING = "supl";
+
+ /**
+ * APN type for DUN traffic
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_DUN_STRING = "dun";
+
+ /**
+ * APN type for HiPri traffic
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_HIPRI_STRING = "hipri";
+
+ /**
+ * APN type for FOTA
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_FOTA_STRING = "fota";
+
+ /**
+ * APN type for IMS
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_IMS_STRING = "ims";
+
+ /**
+ * APN type for CBS
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_CBS_STRING = "cbs";
+
+ /**
+ * APN type for IA Initial Attach APN
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_IA_STRING = "ia";
+
+ /**
+ * APN type for Emergency PDN. This is not an IA apn, but is used
+ * for access to carrier services in an emergency call situation.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_EMERGENCY_STRING = "emergency";
+
+ /**
+ * APN type for Mission Critical Services
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_MCX_STRING = "mcx";
+
+ /**
+ * APN type for XCAP
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String TYPE_XCAP_STRING = "xcap";
+
+
/** @hide */
@IntDef(prefix = { "AUTH_TYPE_" }, value = {
AUTH_TYPE_NONE,
@@ -1289,10 +1407,13 @@
}
/**
+ * Converts the integer value of an APN type to the string version.
* @param apnTypeBitmask bitmask of APN types.
* @return comma delimited list of APN types.
* @hide
*/
+ @SystemApi
+ @NonNull
public static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
List<String> types = new ArrayList<>();
for (Integer type : APN_TYPE_INT_MAP.keySet()) {
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index bc60d81..3f260eb 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -40,10 +41,11 @@
import java.util.List;
/**
- * Parcelable object to handle IMS call profile.
- * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
- * It provides the service and call type, the additional information related to the call.
- *
+ * A Parcelable object to handle the IMS call profile, which provides the service, call type, and
+ * additional information related to the call.
+ * <p>
+ * See the following specifications for more information about this class: GSMA IR.92/IR.94,
+ * 3GPP TS 24.229/TS 26.114/TS26.111.
* @hide
*/
@SystemApi
@@ -151,12 +153,13 @@
*/
public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
- // Extra string for internal use only. OEMs should not use
- // this for packing extras.
/**
+ * Extra key used to store a Bundle containing proprietary extras to send to the ImsService.
+ * Use {@link #getProprietaryCallExtras()} instead.
* @hide
*/
- public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
+ @TestApi
+ public static final String EXTRA_OEM_EXTRAS = "android.telephony.ims.extra.OEM_EXTRAS";
/**
* Rule for originating identity (number) presentation, MO/MT.
@@ -687,6 +690,18 @@
return mCallExtras;
}
+ /**
+ * Get the proprietary extras set for this ImsCallProfile.
+ * @return A {@link Bundle} containing proprietary call extras that were not set by the
+ * platform.
+ */
+ public @Nullable Bundle getProprietaryCallExtras() {
+ if (mCallExtras == null) {
+ return null;
+ }
+ return mCallExtras.getBundle(EXTRA_OEM_EXTRAS);
+ }
+
public ImsStreamMediaProfile getMediaProfile() {
return mMediaProfile;
}
diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
index 893a311..3e2903f 100644
--- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java
+++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java
@@ -83,8 +83,23 @@
public static final int CAPABILITY_RCS_VOICE_CALL = (1 << 19);
/** Supports RCS video calling */
public static final int CAPABILITY_RCS_VIDEO_CALL = (1 << 20);
- /** Supports RCS video calling, where video media can not be dropped */
+ /** Supports RCS video calling, where video media can not be dropped. */
public static final int CAPABILITY_RCS_VIDEO_ONLY_CALL = (1 << 21);
+ /** Supports call composer, where outgoing calls can be enriched with pre-call content.*/
+ public static final int CAPABILITY_CALL_COMPOSER = (1 << 22);
+ /** Supports post call information that is included in the call if the call is missed.*/
+ public static final int CAPABILITY_POST_CALL = (1 << 23);
+ /** Supports sharing a map where the user can draw, share markers, and share their position. */
+ public static final int CAPABILITY_SHARED_MAP = (1 << 24);
+ /** Supports sharing a canvas, where users can draw, add images, and change background colors.*/
+ public static final int CAPABILITY_SHARED_SKETCH = (1 << 25);
+ /** Supports communication with Chatbots. */
+ public static final int CAPABILITY_CHAT_BOT = (1 << 26);
+ /** Supports Chatbot roles. */
+ public static final int CAPABILITY_CHAT_BOT_ROLE = (1 << 27);
+ /** Supports the unidirectional plug-ins framework. */
+ public static final int CAPABILITY_PLUG_IN = (1 << 28);
+
/** @hide*/
@Retention(RetentionPolicy.SOURCE)
@@ -110,7 +125,14 @@
CAPABILITY_GEOLOCATION_PULL_FILE_TRANSFER,
CAPABILITY_RCS_VOICE_CALL,
CAPABILITY_RCS_VIDEO_CALL,
- CAPABILITY_RCS_VIDEO_ONLY_CALL
+ CAPABILITY_RCS_VIDEO_ONLY_CALL,
+ CAPABILITY_CALL_COMPOSER,
+ CAPABILITY_POST_CALL,
+ CAPABILITY_SHARED_MAP,
+ CAPABILITY_SHARED_SKETCH,
+ CAPABILITY_CHAT_BOT,
+ CAPABILITY_CHAT_BOT_ROLE,
+ CAPABILITY_PLUG_IN
})
public @interface CapabilityFlag {}
@@ -183,7 +205,7 @@
}
private final Uri mContactUri;
- private int mCapabilities;
+ private long mCapabilities;
private List<String> mExtensionTags = new ArrayList<>();
private Map<Integer, Uri> mServiceMap = new HashMap<>();
@@ -198,7 +220,7 @@
private RcsContactUceCapability(Parcel in) {
mContactUri = in.readParcelable(Uri.class.getClassLoader());
- mCapabilities = in.readInt();
+ mCapabilities = in.readLong();
in.readStringList(mExtensionTags);
// read mServiceMap as key,value pair
int mapSize = in.readInt();
@@ -223,7 +245,7 @@
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeParcelable(mContactUri, 0);
- out.writeInt(mCapabilities);
+ out.writeLong(mCapabilities);
out.writeStringList(mExtensionTags);
// write mServiceMap as key,value pairs
int mapSize = mServiceMap.keySet().size();
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 4cb8575..1004e1b 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -337,11 +337,10 @@
}
/**
- * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE},
- * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}.
- * @hide
+ * @return The current state of the ImsFeature, set previously by {@link #setFeatureState(int)}
+ * or {@link #STATE_UNAVAILABLE} if it has not been updated yet.
*/
- public int getFeatureState() {
+ public @ImsState int getFeatureState() {
synchronized (mLock) {
return mState;
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
index feac3c2..3ec4f34 100644
--- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java
@@ -16,6 +16,7 @@
package android.telephony.ims.stub;
+import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Bundle;
@@ -25,6 +26,9 @@
import com.android.ims.internal.IImsUt;
import com.android.ims.internal.IImsUtListener;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Base implementation of IMS UT interface, which implements stubs. Override these methods to
* implement functionality.
@@ -36,6 +40,70 @@
@SystemApi
@TestApi
public class ImsUtImplBase {
+ /**
+ * Bar all incoming calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_ALL_INCOMING = 1;
+
+ /**
+ * Bar all outgoing calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_ALL_OUTGOING = 2;
+
+ /**
+ * Bar all outgoing international calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_OUTGOING_INTL = 3;
+
+ /**
+ * Bar all outgoing international calls, excluding those to the home PLMN country
+ * (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_OUTGOING_INTL_EXCL_HOME = 4;
+
+ /**
+ * Bar all incoming calls when roaming (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BLOCKING_INCOMING_WHEN_ROAMING = 5;
+
+ /**
+ * Enable Anonymous Communication Rejection (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_ANONYMOUS_INCOMING = 6;
+
+ /**
+ * Bar all incoming and outgoing calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_ALL = 7;
+
+ /**
+ * Bar all outgoing service requests, including calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_OUTGOING_ALL_SERVICES = 8;
+
+ /**
+ * Bar all incoming service requests, including calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_INCOMING_ALL_SERVICES = 9;
+
+ /**
+ * Bar specific incoming calls. (See 3GPP TS 24.611)
+ */
+ public static final int CALL_BARRING_SPECIFIC_INCOMING_CALLS = 10;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "CALL_BARRING_", value = {CALL_BARRING_ALL_INCOMING, CALL_BARRING_ALL_OUTGOING,
+ CALL_BARRING_OUTGOING_INTL, CALL_BARRING_OUTGOING_INTL_EXCL_HOME,
+ CALL_BLOCKING_INCOMING_WHEN_ROAMING, CALL_BARRING_ANONYMOUS_INCOMING,
+ CALL_BARRING_ALL, CALL_BARRING_OUTGOING_ALL_SERVICES,
+ CALL_BARRING_INCOMING_ALL_SERVICES, CALL_BARRING_SPECIFIC_INCOMING_CALLS})
+ public @interface CallBarringMode {}
+
+ /**
+ * Constant used to denote an invalid return value.
+ */
+ public static final int INVALID_RESULT = -1;
private IImsUt.Stub mServiceImpl = new IImsUt.Stub() {
@Override
@@ -247,15 +315,15 @@
/**
* Updates the configuration of the call barring.
*/
- public int updateCallBarring(int cbType, int action, String[] barrList) {
+ public int updateCallBarring(@CallBarringMode int cbType, int action, String[] barrList) {
return -1;
}
/**
* Updates the configuration of the call barring for specified service class.
*/
- public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList,
- int serviceClass) {
+ public int updateCallBarringForServiceClass(@CallBarringMode int cbType, int action,
+ String[] barrList, int serviceClass) {
return -1;
}
diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java
index 50b63bd..15f8371 100644
--- a/telephony/java/com/android/ims/ImsUtInterface.java
+++ b/telephony/java/com/android/ims/ImsUtInterface.java
@@ -21,6 +21,7 @@
import android.os.Message;
import android.telephony.ims.ImsCallForwardInfo;
import android.telephony.ims.ImsSsInfo;
+import android.telephony.ims.stub.ImsUtImplBase;
/**
* Provides APIs for the supplementary service settings using IMS (Ut interface).
@@ -58,47 +59,48 @@
* CDIV (Communication Diversion, 3GPP TS 24.604)
* actions: target, no reply timer
*/
- public static final int CDIV_CF_UNCONDITIONAL = 0;
- public static final int CDIV_CF_BUSY = 1;
- public static final int CDIV_CF_NO_REPLY = 2;
- public static final int CDIV_CF_NOT_REACHABLE = 3;
+ public static final int CDIV_CF_UNCONDITIONAL = ImsCallForwardInfo.CDIV_CF_REASON_UNCONDITIONAL;
+ public static final int CDIV_CF_BUSY = ImsCallForwardInfo.CDIV_CF_REASON_BUSY;
+ public static final int CDIV_CF_NO_REPLY = ImsCallForwardInfo.CDIV_CF_REASON_NO_REPLY;
+ public static final int CDIV_CF_NOT_REACHABLE = ImsCallForwardInfo.CDIV_CF_REASON_NOT_REACHABLE;
// For CS service code: 002
- public static final int CDIV_CF_ALL = 4;
+ public static final int CDIV_CF_ALL = ImsCallForwardInfo.CDIV_CF_REASON_ALL;
// For CS service code: 004
- public static final int CDIV_CF_ALL_CONDITIONAL = 5;
+ public static final int CDIV_CF_ALL_CONDITIONAL =
+ ImsCallForwardInfo.CDIV_CF_REASON_ALL_CONDITIONAL;
// It's only supported in the IMS service (CS does not define it).
// IR.92 recommends that an UE activates both the CFNRc and the CFNL
// (CDIV using condition not-registered) to the same target.
- public static final int CDIV_CF_NOT_LOGGED_IN = 6;
+ public static final int CDIV_CF_NOT_LOGGED_IN = ImsCallForwardInfo.CDIV_CF_REASON_NOT_LOGGED_IN;
/**
* CB (Communication Barring, 3GPP TS 24.611)
*/
// Barring of All Incoming Calls
- public static final int CB_BAIC = 1;
+ public static final int CB_BAIC = ImsUtImplBase.CALL_BARRING_ALL_INCOMING;
// Barring of All Outgoing Calls
- public static final int CB_BAOC = 2;
+ public static final int CB_BAOC = ImsUtImplBase.CALL_BARRING_ALL_OUTGOING;
// Barring of Outgoing International Calls
- public static final int CB_BOIC = 3;
+ public static final int CB_BOIC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL;
// Barring of Outgoing International Calls - excluding Home Country
- public static final int CB_BOIC_EXHC = 4;
+ public static final int CB_BOIC_EXHC = ImsUtImplBase.CALL_BARRING_OUTGOING_INTL_EXCL_HOME;
// Barring of Incoming Calls - when roaming
- public static final int CB_BIC_WR = 5;
+ public static final int CB_BIC_WR = ImsUtImplBase.CALL_BLOCKING_INCOMING_WHEN_ROAMING;
// Barring of Anonymous Communication Rejection (ACR) - a particular case of ICB service
- public static final int CB_BIC_ACR = 6;
+ public static final int CB_BIC_ACR = ImsUtImplBase.CALL_BARRING_ANONYMOUS_INCOMING;
// Barring of All Calls
- public static final int CB_BA_ALL = 7;
+ public static final int CB_BA_ALL = ImsUtImplBase.CALL_BARRING_ALL;
// Barring of Outgoing Services (Service Code 333 - 3GPP TS 22.030 Table B-1)
- public static final int CB_BA_MO = 8;
+ public static final int CB_BA_MO = ImsUtImplBase.CALL_BARRING_OUTGOING_ALL_SERVICES;
// Barring of Incoming Services (Service Code 353 - 3GPP TS 22.030 Table B-1)
- public static final int CB_BA_MT = 9;
+ public static final int CB_BA_MT = ImsUtImplBase.CALL_BARRING_INCOMING_ALL_SERVICES;
// Barring of Specific Incoming calls
- public static final int CB_BS_MT = 10;
+ public static final int CB_BS_MT = ImsUtImplBase.CALL_BARRING_SPECIFIC_INCOMING_CALLS;
/**
* Invalid result value.
*/
- public static final int INVALID = (-1);
+ public static final int INVALID = ImsUtImplBase.INVALID_RESULT;
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c07a171..79cdce8 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -145,10 +145,13 @@
* be automatically persisted in the SMS db. It only affects messages sent
* by a non-default SMS app. Currently only the carrier app can set this
* parameter to false to skip auto message persistence.
+ * @param messageId An id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
*/
void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr,
in String scAddr, in String text, in PendingIntent sentIntent,
- in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp);
+ in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp,
+ in long messageId);
/**
* Send an SMS. Internal use only.
@@ -270,11 +273,14 @@
* be automatically persisted in the SMS db. It only affects messages sent
* by a non-default SMS app. Currently only the carrier app can set this
* parameter to false to skip auto message persistence.
+ * @param messageId An id that uniquely identifies the message requested to be sent.
+ * Used for logging and diagnostics purposes. The id may be 0.
*/
void sendMultipartTextForSubscriber(in int subId, String callingPkg,
in String destinationAddress, in String scAddress,
in List<String> parts, in List<PendingIntent> sentIntents,
- in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp);
+ in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp,
+ in long messageId);
/**
* Send a multi-part text based SMS with options using Subscription Id.
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index ddd3457..db0b8e5 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -61,7 +61,8 @@
@Override
public void sendTextForSubscriber(int subId, String callingPkg, String destAddr,
String scAddr, String text, PendingIntent sentIntent,
- PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) {
+ PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp,
+ long messageId) {
throw new UnsupportedOperationException();
}
@@ -90,7 +91,8 @@
public void sendMultipartTextForSubscriber(int subId, String callingPkg,
String destinationAddress, String scAddress,
List<String> parts, List<PendingIntent> sentIntents,
- List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) {
+ List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp,
+ long messageId) {
throw new UnsupportedOperationException();
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index db8c845..4d67754 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
import android.compat.annotation.UnsupportedAppUsage;
+import android.telephony.data.ApnSetting;
/**
* @hide
@@ -125,32 +126,32 @@
* APN_TYPE_ALL is a special type to indicate that this APN entry can
* service all data connections.
*/
- public static final String APN_TYPE_ALL = "*";
+ public static final String APN_TYPE_ALL = ApnSetting.TYPE_ALL_STRING;
/** APN type for default data traffic */
- public static final String APN_TYPE_DEFAULT = "default";
+ public static final String APN_TYPE_DEFAULT = ApnSetting.TYPE_DEFAULT_STRING;
/** APN type for MMS traffic */
- public static final String APN_TYPE_MMS = "mms";
+ public static final String APN_TYPE_MMS = ApnSetting.TYPE_MMS_STRING;
/** APN type for SUPL assisted GPS */
- public static final String APN_TYPE_SUPL = "supl";
+ public static final String APN_TYPE_SUPL = ApnSetting.TYPE_SUPL_STRING;
/** APN type for DUN traffic */
- public static final String APN_TYPE_DUN = "dun";
+ public static final String APN_TYPE_DUN = ApnSetting.TYPE_DUN_STRING;
/** APN type for HiPri traffic */
- public static final String APN_TYPE_HIPRI = "hipri";
+ public static final String APN_TYPE_HIPRI = ApnSetting.TYPE_HIPRI_STRING;
/** APN type for FOTA */
- public static final String APN_TYPE_FOTA = "fota";
+ public static final String APN_TYPE_FOTA = ApnSetting.TYPE_FOTA_STRING;
/** APN type for IMS */
- public static final String APN_TYPE_IMS = "ims";
+ public static final String APN_TYPE_IMS = ApnSetting.TYPE_IMS_STRING;
/** APN type for CBS */
- public static final String APN_TYPE_CBS = "cbs";
+ public static final String APN_TYPE_CBS = ApnSetting.TYPE_CBS_STRING;
/** APN type for IA Initial Attach APN */
- public static final String APN_TYPE_IA = "ia";
+ public static final String APN_TYPE_IA = ApnSetting.TYPE_IA_STRING;
/** APN type for Emergency PDN. This is not an IA apn, but is used
* for access to carrier services in an emergency call situation. */
- public static final String APN_TYPE_EMERGENCY = "emergency";
+ public static final String APN_TYPE_EMERGENCY = ApnSetting.TYPE_EMERGENCY_STRING;
/** APN type for Mission Critical Services */
- public static final String APN_TYPE_MCX = "mcx";
+ public static final String APN_TYPE_MCX = ApnSetting.TYPE_MCX_STRING;
/** APN type for XCAP */
- public static final String APN_TYPE_XCAP = "xcap";
+ public static final String APN_TYPE_XCAP = ApnSetting.TYPE_XCAP_STRING;
/** Array of all APN types */
public static final String[] APN_TYPES = {APN_TYPE_DEFAULT,
APN_TYPE_MMS,
diff --git a/wifi/Android.bp b/wifi/Android.bp
index 4c9ee85..5ef892d 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -114,6 +114,8 @@
":framework-annotations",
":framework-wifi-updatable-sources",
],
+ // This is needed as IOnWifiActivityEnergyInfoListener.aidl in framework-wifi depends on
+ // WifiActivityEnergyInfo.aidl in framework-minus-apex
aidl: {
include_dirs: ["frameworks/base/core/java"],
},
@@ -125,11 +127,6 @@
java_library {
name: "framework-wifi-stubs",
srcs: [":framework-wifi-stubs-srcs"],
- aidl: {
- export_include_dirs: [
- "java",
- ],
- },
sdk_version: "core_current",
libs: ["android_system_stubs_current"],
installable: false,